[MPlayer-dev-eng] Re: [PATCH] print appropriate error when failing to open a file

Tobias Diedrich ranma at tdiedrich.de
Wed Dec 14 17:37:51 CET 2005


Rich Felker wrote:

> The problem is that setlocale is banned in MPlayer for good reason.
> It's a completely broken approach to handling locale.

Elaborating a bit more on this, I think you refer to this patch:

"remove all setlocale calls, they break the behaviour of sscanf and
strcasecmp, especially with tr_TR locale - and do not seem to be
good for anything."
http://archives.free.net.ph/message/20050120.062255.59c150a1.en.html

This is wrong because it
a) assumes that the only option is removing all setlocale calls
b) it was good for something, with the the setlocale call in place
   strerror()-messages were translated into the locale-specific
   language.

How does the locale system work?

>From a user's perspective there are a few environment variables
controlling program behaviour:

LC_ALL: overrides all others
LANG:   default value (POSIX if unset)
LC_X:   specific 'subsystem' values, overrides LANG if set,
        where X can be:
  CTYPE: Character encoding type for input and output
  NUMERIC: Numeric format (except monetary)
  TIME: Time/Date format
  COLLATE: String sorting order
  MONETARY: Monetary format
  MESSAGES: Message language
  Miscellanious formats:
    PAPER, NAME, ADDRESS, TELEPHONE, MEASUREMENT, IDENTIFICATION

A user can use the 'locale' utility to verify those from the
application POV, those displayed in quotes are implicitly set by
LANG or LC_ALL.

Out of those only LC_CTYPE and LC_MESSAGES are interesting for
MPlayer AFAICS.

>From an application's perspective the usage is managed by the
setlocale()-call.

You have 3 basic options:
1) To not use setlocale()
2) Use localisation for everything: 'setlocale(LC_ALL, "");'
3) Use localisation only where it's interesting and 
   doesn't break anything:
   'setlocale(LC_SOMETHING, "");
    setlocale(LC_SOMETHING2, "");'

Before the above-mentioned patch, MPlayer was using
'setlocale(LC_ALL, "");' and thus using localisation in places where
it would break expected behaviour.

I'd assume most developers (myself included) use MPlayers in an
environment, where en_US is the standard locale, which is mostly
(completely?) the same as the 'C' locale (which 'POSIX' seems to be
an alias for).

Now, the remainings question is:

Out of the interesting localisation options LC_CTYPE and
LC_MESSAGES, what do we want them for and are they safe to use?

IMHO we want LC_MESSAGES for localised strerror() (and would also
need it for gettext() AFAICS), we only need LC_CTYPE to determine
the character set in use (using 'nl_langinfo(CODESET)'), so it would
be possible to briefly set LC_CTYPE, use nl_langinfo to get the
character encoding name and reset LC_CTYPE (we don't want LC_CTYPE
set since it affects strcasecmp).

There is only one problem with this:
If LC_MESSAGES is set, but LC_CTYPE is not set, strerror will return
the localised message in default (ISO-8859-1) encoding.  Ugh.
This can of course be worked around by using a wrapper, which calls
setlocale before and after the strerror call (at which point we no
longer need to set LC_MESSAGES globally).

So, in the end, I agree with you that setlocale is messy, but I
also think that we should use the existing error message
translations, if possible.

char *mp_strerror(int errnum)
{
	char *old_ctype, *old_messages, *res;

	old_ctype = setlocale(LC_CTYPE, NULL);
	old_messages = setlocale(LC_MESSAGES, NULL);
	setlocale(LC_CTYPE, "");
	setlocale(LC_MESSAGES, "");

	res = strerror(EINVAL);

	setlocale(LC_MESSAGES, old_messages);
	setlocale(LC_CTYPE, old_ctype);

	return res;
}

Hmm, this may still be problematic with threads.
AFAICS in the glibc source it's thread-safe (takes a global data
lock), but still modifies _global_ data, thus changing settings for
all threads, which would break a strcasecmp that just so happens to
be call in between... *sigh*

So.  It seems you are perfectly right and using setlocale is out of
the question. ^_^;

-- 
Tobias						PGP: http://9ac7e0bc.uguu.de




More information about the MPlayer-dev-eng mailing list