2 * This file is part of LyX, the document processor.
3 * Licence details can be found in the file COPYING.
5 * \author Lars Gullik Bjønnes
7 * Full author contact details are available in file CREDITS.
12 #include "support/Messages.h"
14 #include "support/debug.h"
15 #include "support/docstring.h"
16 #include "support/environment.h"
17 #include "support/Package.h"
19 #include <boost/assert.hpp>
28 using lyx::from_ascii;
30 void cleanTranslation(docstring & trans)
33 Some english words have different translations, depending on
34 context. In these cases the original string is augmented by
35 context information (e.g. "To:[[as in 'From page x to page
36 y']]" and "To:[[as in 'From format x to format y']]". This
37 means that we need to filter out everything in double square
38 brackets at the end of the string, otherwise the user sees
39 bogus messages. If we are unable to honour the request we
40 just return what we got in.
42 size_t const pos1 = trans.find(from_ascii("[["));
43 if (pos1 != docstring::npos) {
44 size_t const pos2 = trans.find(from_ascii("]]"), pos1);
45 if (pos2 != docstring::npos)
46 trans.erase(pos1, pos2 - pos1 + 2);
60 # include <libintl.h> // use the header already in the system *EK*
62 # include "../intl/libintl.h"
65 using namespace lyx::support;
69 // This version use the traditional gettext.
70 Messages::Messages(string const & l)
71 : lang_(l), warned_(false)
73 // strip off any encoding suffix, i.e., assume 8-bit po files
74 size_t i = lang_.find(".");
75 lang_ = lang_.substr(0, i);
76 LYXERR(Debug::DEBUG, "language(" << lang_ << ")");
83 string const locale_dir = package().locale_dir().toFilesystemEncoding();
84 char const * c = bindtextdomain(PACKAGE, locale_dir.c_str());
87 LYXERR(Debug::DEBUG, "Error code: " << errno << '\n'
88 << "Directory : " << package().locale_dir().absFilename() << '\n'
89 << "Rtn value : " << c);
92 if (!bind_textdomain_codeset(PACKAGE, ucs4_codeset)) {
93 LYXERR(Debug::DEBUG, "Error code: " << errno << '\n'
94 << "Codeset : " << ucs4_codeset);
101 docstring const Messages::get(string const & m) const
106 // Look for the translated string in the cache.
107 TranslationCache::iterator it = cache_.find(m);
108 if (it != cache_.end())
111 // The string was not found, use gettext to generate it
113 string const oldLANGUAGE = getEnv("LANGUAGE");
114 string const oldLC_ALL = getEnv("LC_ALL");
115 if (!lang_.empty()) {
116 // This GNU extension overrides any language locale
118 setEnv("LANGUAGE", lang_);
119 // However, setting LANGUAGE does nothing when the
120 // locale is "C". Therefore we set the locale to
121 // something that is believed to exist on most
122 // systems. The idea is that one should be able to
123 // load German documents even without having de_DE
125 setEnv("LC_ALL", "en_US");
126 #ifdef HAVE_LC_MESSAGES
127 setlocale(LC_MESSAGES, "");
131 char const * m_c = m.c_str();
132 char const * trans_c = gettext(m_c);
135 LYXERR0("Undefined result from gettext");
136 else if (trans_c == m_c) {
137 LYXERR(Debug::DEBUG, "Same as entered returned");
138 trans = from_ascii(m);
140 LYXERR(Debug::DEBUG, "We got a translation");
141 // m is actually not a char const * but ucs4 data
142 trans = reinterpret_cast<char_type const *>(trans_c);
145 cleanTranslation(trans);
147 // Reset environment variables as they were.
148 if (!lang_.empty()) {
149 // Reset everything as it was.
150 setEnv("LANGUAGE", oldLANGUAGE);
151 setEnv("LC_ALL", oldLC_ALL);
152 #ifdef HAVE_LC_MESSAGES
153 setlocale(LC_MESSAGES, "");
157 pair<TranslationCache::iterator, bool> result =
158 cache_.insert(make_pair(m, trans));
160 BOOST_ASSERT(result.second);
162 return result.first->second;
168 // This is the dummy variant.
172 Messages::Messages(string const & l) {}
174 void Messages::init()
179 docstring const Messages::get(string const & m) const
181 docstring trans = from_ascii(m);
182 cleanTranslation(trans);
196 // This version of the Pimpl utilizes the message capability of
197 // libstdc++ that is distributed with GNU G++.
198 class Messages::Pimpl {
200 typedef messages<char>::catalog catalog;
202 Pimpl(string const & l)
204 loc_gl(lang_.c_str()),
205 mssg_gl(use_facet<messages<char> >(loc_gl))
207 //LYXERR("Messages: language(" << l << ") in dir(" << dir << ")");
209 string const locale_dir = package().locale_dir().toFilesystemEncoding();
210 cat_gl = mssg_gl.open(PACKAGE, loc_gl, locale_dir.c_str());
216 mssg_gl.close(cat_gl);
219 docstring const get(string const & msg) const
221 return mssg_gl.get(cat_gl, 0, 0, msg);
229 messages<char> const & mssg_gl;