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_;
};

Reply via email to