On Sun, Oct 09, 2005 at 03:21:07PM +0200, Michael Gerz wrote:
> 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

From the setlocale man page:

        char *setlocale(int category, const char *locale);

        The setlocale() function is used to set or query the program's current
        locale.

        If locale is NULL, the current locale is only queried, not modified.

So, it queries the current locale in environment variables like, in this
case, LC_MESSAGES. If you don't have this variable set, you'll get
returned a NULL.

On Linux at least, LC_LOCALE is implicitly set if LANG is set. Issue the
'locale' shell command to see what your settings are. 

HTH Martin

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

Attachment: pgpqwk8D0uSb5.pgp
Description: PGP signature

Reply via email to