Guys,
I need your help. On Windows, LyX crashes with a segmentation fault. The
problem is within ./src/messages.C (see code snippet below). gdb tells
me that "setlocale(LC_MESSAGES, NULL) " returns NULL which makes
Messages::Pimpl::Pimpl crash.
Ok, that is problem. But what is the correct fix???
To my surprise, Messages::Pimpl::get() invokes the same function - and
checks for NULL! Does that mean that we check the locale every time we
have to translate a message? If that is the case, what is the purpose of
"lang_"?
Could someone please enlighten me - preferably with a ready-to-use patch
for the Windows problem?
Thanks a lot in advance!
Michael
****** Messages.C *****
// This is a more traditional variant.
class Messages::Pimpl {
public:
Pimpl(string const & l)
: lang_(l)
{
if ( lang_.empty() )
lang_ = setlocale(LC_MESSAGES, NULL);
******* <<<<<<< CRASH <<<<<<< *****
// strip off any encoding suffix, i.e., assume 8-bit po
files
string::size_type i = lang_.find(".");
lang_ = lang_.substr(0, i);
lyxerr[Debug::DEBUG] << BOOST_CURRENT_FUNCTION
<< ": language(" << lang_ << ")" <<
std::endl;
}
~Pimpl() {}
string const get(string const & m) const
{
if (m.empty())
return m;
//string oldMSG = setlocale(LC_MESSAGES, NULL);
// In this order, see support/filetools.C:
string lang = getEnv("LC_ALL");
if (lang.empty()) {
lang = getEnv("LC_MESSAGES");
if (lang.empty()) {
lang = getEnv("LANG");
if (lang.empty())
lang = "C";
}
}
char const * works = setlocale(LC_MESSAGES, lang_.c_str());
if (!works)
lyxerr << "Locale " << lang_ << " could not be
set" << std::endl;
// CTYPE controls what getmessage thinks what encoding
the po file uses
string oldCTYPE = setlocale(LC_CTYPE, NULL);
setlocale(LC_CTYPE, lang_.c_str());
errno = 0;
char const * c = bindtextdomain(PACKAGE,
package().locale_dir().c_str());
int e = errno;
if (e) {
lyxerr[Debug::DEBUG]
<< BOOST_CURRENT_FUNCTION << '\n'
<< "Error code: " << errno << '\n'
<< "Lang, mess: " << lang_ << " " << m
<< '\n'
<< "Directory : " <<
package().locale_dir() << '\n'
<< "Rtn value : " << c << std::endl;
}
textdomain(PACKAGE);
const char* msg = gettext(m.c_str());
string translated(works ? msg : m);
// Some english words have different translations, depending
// on context. In these cases the original string is
// augmented by context information (e.g.
// "To:[[as in 'From page x to page y']]" and
// "To:[[as in 'From format x to format y']]".
// This means that we need to filter out everything in
// double square brackets at the end of the string,
// otherwise the user sees bogus messages.
// If we are unable to honour the request we just
// return what we got in.
static boost::regex const
reg("^([^\\[]*)\\[\\[[^\\]]*\\]\\]$");
boost::smatch sub;
if (regex_match(translated, sub, reg))
translated = sub.str(1);
setlocale(LC_MESSAGES, lang.c_str());
setlocale(LC_CTYPE, oldCTYPE.c_str());
return translated;
}
private:
///
string lang_;
};