X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Fsupport%2FMessages.cpp;h=5eee6b7f6d5aa20d29b6d255c6b3adb208ce8cd3;hb=f1ab5dfc5878bc736fd185279a0ef7a185b2d8d8;hp=00735e480871659b56f8987b80a3987530d690f8;hpb=9383f4c3c6f9cfab2d658701ba66e2b54cd68bea;p=lyx.git diff --git a/src/support/Messages.cpp b/src/support/Messages.cpp index 00735e4808..5eee6b7f6d 100644 --- a/src/support/Messages.cpp +++ b/src/support/Messages.cpp @@ -2,7 +2,7 @@ * This file is part of LyX, the document processor. * Licence details can be found in the file COPYING. * - * \author Lars Gullik Bjønnes + * \author Lars Gullik Bjønnes * * Full author contact details are available in file CREDITS. */ @@ -14,19 +14,19 @@ #include "support/debug.h" #include "support/docstring.h" #include "support/environment.h" +#include "support/lstrings.h" #include "support/Package.h" #include "support/unicode.h" -#include +#include "support/lassert.h" #include -using namespace std; +# define N_(str) (str) // for marking strings to be translated -namespace { +using namespace std; -using lyx::docstring; -using lyx::from_ascii; +namespace lyx { void cleanTranslation(docstring & trans) { @@ -48,7 +48,7 @@ void cleanTranslation(docstring & trans) } } -} +} // lyx #ifdef ENABLE_NLS @@ -60,15 +60,12 @@ void cleanTranslation(docstring & trans) # if HAVE_GETTEXT # include // use the header already in the system *EK* # else -# include "../intl/libintl.h" +# include "intl/libintl.h" # endif -namespace lyx { - -using support::package; -using support::getEnv; -using support::setEnv; +using namespace lyx::support; +namespace lyx { // This version use the traditional gettext. Messages::Messages(string const & l) @@ -77,7 +74,7 @@ Messages::Messages(string const & l) // strip off any encoding suffix, i.e., assume 8-bit po files size_t i = lang_.find("."); lang_ = lang_.substr(0, i); - LYXERR(Debug::DEBUG, "language(" << lang_ << ")"); + LYXERR(Debug::LOCALE, "language(" << lang_ << ")"); } @@ -88,13 +85,13 @@ void Messages::init() char const * c = bindtextdomain(PACKAGE, locale_dir.c_str()); int e = errno; if (e) { - LYXERR(Debug::DEBUG, "Error code: " << errno << '\n' - << "Directory : " << package().locale_dir().absFilename() << '\n' + LYXERR(Debug::LOCALE, "Error code: " << errno << '\n' + << "Directory : " << package().locale_dir().absFileName() << '\n' << "Rtn value : " << c); } if (!bind_textdomain_codeset(PACKAGE, ucs4_codeset)) { - LYXERR(Debug::DEBUG, "Error code: " << errno << '\n' + LYXERR(Debug::LOCALE, "Error code: " << errno << '\n' << "Codeset : " << ucs4_codeset); } @@ -102,6 +99,38 @@ void Messages::init() } +string Messages::language() const +{ + // get the language from the gmo file + string const test = N_("[[Replace with the code of your language]]"); + string const trans = to_utf8(get(test)); + if (trans == test) { + LYXERR0("Something is weird."); + return string(); + } else + return trans; +} + + +bool Messages::available(string const & c) +{ + static string locale_dir = package().locale_dir().toFilesystemEncoding(); + string code = c; + // this loops at most twice + while (true) { + string const filen = locale_dir + "/" + code + + "/LC_MESSAGES/"PACKAGE".mo"; + if (FileName(filen).isReadableFile()) + return true; + if (contains(code, '_')) + code = token(code, '_', 0); + else return false; + } + return false; + +} + + docstring const Messages::get(string const & m) const { if (m.empty()) @@ -113,35 +142,46 @@ docstring const Messages::get(string const & m) const return it->second; // The string was not found, use gettext to generate it - - string const oldLANGUAGE = getEnv("LANGUAGE"); - string const oldLC_ALL = getEnv("LC_ALL"); + static string oldLC_ALL; + static string oldLANGUAGE; if (!lang_.empty()) { + oldLC_ALL = getEnv("LC_ALL"); // This GNU extension overrides any language locale // wrt gettext. - setEnv("LANGUAGE", lang_); + LYXERR(Debug::LOCALE, "Setting LANGUAGE to " << lang_); + oldLANGUAGE = getEnv("LANGUAGE"); + if (!setEnv("LANGUAGE", lang_)) + LYXERR(Debug::LOCALE, "\t... failed!"); // However, setting LANGUAGE does nothing when the // locale is "C". Therefore we set the locale to // something that is believed to exist on most // systems. The idea is that one should be able to // load German documents even without having de_DE // installed. - setEnv("LC_ALL", "en_US"); + LYXERR(Debug::LOCALE, "Setting LC_ALL to en_US"); + if (!setEnv("LC_ALL", "en_US")) + LYXERR(Debug::LOCALE, "\t... failed!"); #ifdef HAVE_LC_MESSAGES setlocale(LC_MESSAGES, ""); #endif } + // FIXME: gettext sometimes "forgets" the ucs4_codeset we set + // in init(), which leads to severe message corruption (#7371) + // We set it again here unconditionally. A real fix must be found! + LASSERT(bind_textdomain_codeset(PACKAGE, ucs4_codeset), /**/); + char const * m_c = m.c_str(); char const * trans_c = gettext(m_c); docstring trans; - if (!trans_c) - LYXERR0("Undefined result from gettext"); - else if (trans_c == m_c) { - LYXERR(Debug::DEBUG, "Same as entered returned"); + if (!trans_c) { + LYXERR(Debug::LOCALE, "Undefined result from gettext for `" << m << "'."); + trans = from_ascii(m); + } else if (trans_c == m_c) { + //LYXERR(Debug::LOCALE, "Same as entered returned"); trans = from_ascii(m); } else { - LYXERR(Debug::DEBUG, "We got a translation"); + //LYXERR(Debug::LOCALE, "We got a translation"); // m is actually not a char const * but ucs4 data trans = reinterpret_cast(trans_c); } @@ -151,17 +191,24 @@ docstring const Messages::get(string const & m) const // Reset environment variables as they were. if (!lang_.empty()) { // Reset everything as it was. - setEnv("LANGUAGE", oldLANGUAGE); - setEnv("LC_ALL", oldLC_ALL); + LYXERR(Debug::LOCALE, "restoring LANGUAGE from " + << getEnv("LANGUAGE") + << " to " << oldLANGUAGE); + if (!setEnv("LANGUAGE", oldLANGUAGE)) + LYXERR(Debug::LOCALE, "\t... failed!"); + LYXERR(Debug::LOCALE, "restoring LC_ALL from " << getEnv("LC_ALL") + << " to " << oldLC_ALL); + if (!setEnv("LC_ALL", oldLC_ALL)) + LYXERR(Debug::LOCALE, "\t... failed!"); #ifdef HAVE_LC_MESSAGES setlocale(LC_MESSAGES, ""); #endif } - std::pair result = - cache_.insert(std::make_pair(m, trans)); + pair result = + cache_.insert(make_pair(m, trans)); - BOOST_ASSERT(result.second); + LASSERT(result.second, /**/); return result.first->second; } @@ -173,7 +220,7 @@ docstring const Messages::get(string const & m) const namespace lyx { -Messages::Messages(string const & l) {} +Messages::Messages(string const & /* l */) {} void Messages::init() { @@ -187,6 +234,17 @@ docstring const Messages::get(string const & m) const return trans; } +std::string Messages::language() const + { + return string(); + } + +bool Messages::available(string const & c) +{ + (void)c; + return false; +} + } // namespace lyx #endif @@ -201,12 +259,12 @@ namespace lyx { // libstdc++ that is distributed with GNU G++. class Messages::Pimpl { public: - typedef std::messages::catalog catalog; + typedef messages::catalog catalog; Pimpl(string const & l) : lang_(l), loc_gl(lang_.c_str()), - mssg_gl(std::use_facet >(loc_gl)) + mssg_gl(use_facet >(loc_gl)) { //LYXERR("Messages: language(" << l << ") in dir(" << dir << ")"); @@ -228,9 +286,9 @@ private: /// string lang_; /// - std::locale loc_gl; + locale loc_gl; /// - std::messages const & mssg_gl; + messages const & mssg_gl; /// catalog cat_gl; };