X-Git-Url: http://g0dil.de/git?a=blobdiff_plain;f=senf%2FUtils%2FTermlib%2FTerminfo.cc;h=a3ae123609094b3bed958afbfc4d428382a8d8bc;hb=refs%2Fheads%2Fmaster;hp=44bdb6f80c1b56b5c51f06a4a9e48a0ea40bbbe3;hpb=601d1f509f5bb24df167a4dd5a20da67a0af9af8;p=senf.git diff --git a/senf/Utils/Termlib/Terminfo.cc b/senf/Utils/Termlib/Terminfo.cc index 44bdb6f..a3ae123 100644 --- a/senf/Utils/Termlib/Terminfo.cc +++ b/senf/Utils/Termlib/Terminfo.cc @@ -1,24 +1,29 @@ // $Id$ // -// Copyright (C) 2009 +// Copyright (C) 2009 // Fraunhofer Institute for Open Communication Systems (FOKUS) -// Competence Center NETwork research (NET), St. Augustin, GERMANY -// Stefan Bund // -// 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. +// The contents of this file are subject to the Fraunhofer FOKUS Public License +// Version 1.0 (the "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// http://senf.berlios.de/license.html // -// 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. +// The Fraunhofer FOKUS Public License Version 1.0 is based on, +// but modifies the Mozilla Public License Version 1.1. +// See the full license text for the amendments. // -// 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. +// Software distributed under the License is distributed on an "AS IS" basis, +// WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +// for the specific language governing rights and limitations under the License. +// +// The Original Code is Fraunhofer FOKUS code. +// +// The Initial Developer of the Original Code is Fraunhofer-Gesellschaft e.V. +// (registered association), Hansastraße 27 c, 80686 Munich, Germany. +// All Rights Reserved. +// +// Contributor(s): +// Stefan Bund /** \file \brief Terminfo non-inline non-template implementation */ @@ -37,7 +42,7 @@ //#include "Terminfo.mpp" #define prefix_ -///////////////////////////////cc.p//////////////////////////////////////// +//-///////////////////////////////////////////////////////////////////////////////////////////////// char const * const senf::term::Terminfo::properties::BooleanNames [] = { "AutoLeftMargin", "AutoRightMargin", "NoEscCtlc", "CeolStandoutGlitch", "EatNewlineGlitch", @@ -126,9 +131,16 @@ char const * const senf::term::Terminfo::properties::StringNames[] = { "AcsUlcorner", "AcsLlcorner", "AcsUrcorner", "AcsLrcorner", "AcsLtee", "AcsRtee", "AcsBtee", "AcsTtee", "AcsHline", "AcsVline", "AcsPlus", "MemoryLock", "MemoryUnlock", "BoxChars1" }; -/////////////////////////////////////////////////////////////////////////// +//-///////////////////////////////////////////////////////////////////////////////////////////////// // senf::term::Terminfo +prefix_ senf::term::Terminfo::InvalidTerminfoException::InvalidTerminfoException(std::string const & term) + : senf::Exception("Unreadable terminfo file") +{ + if (!term.empty()) + append( ": " + term); +} + prefix_ senf::term::Terminfo::Terminfo() {} @@ -140,10 +152,15 @@ prefix_ senf::term::Terminfo::Terminfo(std::string const & term) prefix_ void senf::term::Terminfo::load(std::string const & term) { std::string filename (findTerminfo(term)); - if (filename.empty()) throw InvalidTerminfoException(); + if (filename.empty()) throw InvalidTerminfoException(term); std::ifstream is (filename.c_str()); - if (!is) throw InvalidTerminfoException(); - load(is); + if (!is) throw InvalidTerminfoException(filename); + try { + load(is); + } catch (InvalidTerminfoException & ex) { + ex << ": " << filename; + throw ex; + } } prefix_ bool senf::term::Terminfo::getFlag(properties::Boolean p) @@ -194,13 +211,13 @@ namespace { { std::vector stack; - void push(senf::term::Terminfo::number_t v) + void push(senf::term::Terminfo::number_t v) { stack.push_back(v); } - senf::term::Terminfo::number_t pop() - { + senf::term::Terminfo::number_t pop() + { if (stack.empty()) return 0; else { @@ -282,11 +299,11 @@ prefix_ std::string senf::term::Terminfo::formatString(properties::String p, case '~': stack.push(~stack.pop()); break; case 't': bCondValue = stack.pop(); case 'e': if ((bCondValue = !bCondValue)) // this also supports elsif - --(i = prgstr.begin() + std::min (prgstr.find ("%e", i-prgstr.begin()), + --(i = prgstr.begin() + std::min (prgstr.find ("%e", i-prgstr.begin()), prgstr.find ("%;", i-prgstr.begin()))); case '?': case ';': break; - case 'p': + case 'p': switch (*++i) { case '1': stack.push(arg1); break; case '2': stack.push(arg2); break; @@ -338,7 +355,7 @@ prefix_ std::string senf::term::Terminfo::formatString(properties::String p, NumberVec::const_iterator i (numbers_.begin()); NumberVec::const_iterator const i_end (numbers_.end()); for (; i != i_end; ++i, ++n) - if (*i != NoValue + if (*i != NoValue && n < sizeof(properties::NumericNames)/sizeof(properties::NumericNames[0])) os << " " << properties::NumericNames[n] << " = " << *i << "\n"; } @@ -367,18 +384,18 @@ prefix_ std::string senf::term::Terminfo::findTerminfo(std::string const & name) char const * tivar (::getenv("TERMINFO")); if (tivar) { tientry = boost::filesystem::path(tivar) / subdir; - if (boost::filesystem::exists(tientry)) return tientry.native_file_string(); + if (boost::filesystem::exists(tientry)) return tientry.string(); } } tientry = boost::filesystem::path("/etc/terminfo") / subdir; - if (boost::filesystem::exists(tientry)) return tientry.native_file_string(); + if (boost::filesystem::exists(tientry)) return tientry.string(); tientry = boost::filesystem::path("/lib/terminfo") / subdir; - if (boost::filesystem::exists(tientry)) return tientry.native_file_string(); + if (boost::filesystem::exists(tientry)) return tientry.string(); tientry = boost::filesystem::path("/usr/share/terminfo") / subdir; - if (boost::filesystem::exists(tientry)) return tientry.native_file_string(); + if (boost::filesystem::exists(tientry)) return tientry.string(); return ""; } @@ -394,6 +411,15 @@ namespace { boost::uint16_t nNumbers; boost::uint16_t nStrings; boost::uint16_t stringPoolSz; + + void letoh() { + magic = le16toh(magic); + namesSz = le16toh(namesSz); + nBooleans = le16toh(nBooleans); + nNumbers = le16toh(nNumbers); + nStrings = le16toh(nStrings); + stringPoolSz = le16toh(stringPoolSz); + } }; } @@ -402,7 +428,9 @@ prefix_ void senf::term::Terminfo::load(std::istream & is) { TerminfoHeader h; is.read(static_cast(static_cast(&h)), sizeof(h)); - if (!is || h.magic != TerminfoMagic) throw InvalidTerminfoException(); + h.letoh(); + if (!is || h.magic != TerminfoMagic) throw InvalidTerminfoException( + "invalid magic number (") << h.magic << "!=" << TerminfoMagic << ")"; name_.resize(h.namesSz); is.read(&(name_[0]), name_.size()); @@ -424,7 +452,7 @@ prefix_ void senf::term::Terminfo::load(std::istream & is) } if (booleans_.size() & 1) is.ignore(1u); - + numbers_.resize(h.nNumbers); for (NumberVec::iterator i (numbers_.begin()); i != numbers_.end(); ++i) { number_t v; @@ -440,9 +468,9 @@ prefix_ void senf::term::Terminfo::load(std::istream & is) number_t v; is.read(static_cast(static_cast(&v)), sizeof(v)); if (!is) throw InvalidTerminfoException(); - *i = v; + *i = le16toh(v); } - + stringPool_.resize(h.stringPoolSz); is.read(&(stringPool_[0]), stringPool_.size()); if (!is) throw InvalidTerminfoException(); @@ -456,7 +484,7 @@ prefix_ void senf::term::Terminfo::load(std::istream & is) *j = 0; } -/////////////////////////////////////////////////////////////////////////// +//-///////////////////////////////////////////////////////////////////////////////////////////////// // senf::term::KeyParser char const * const senf::term::KeyParser::KeyNames[] = { @@ -561,7 +589,7 @@ senf::term::KeyParser::lookup(std::string const & key) if (key.empty()) return std::make_pair(KeyCode(0), 0); - // There are several cases: + // 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' @@ -605,7 +633,7 @@ prefix_ void senf::term::KeyParser::dump(std::ostream & os) } } -///////////////////////////////cc.e//////////////////////////////////////// +//-///////////////////////////////////////////////////////////////////////////////////////////////// #undef prefix_ //#include "Terminfo.mpp"