On Wed Nov 21 03:26:14 2012, GUIDO wrote:
Show quoted text>
http://www.gnu.org/software/gettext/manual/html_node/The-LANGUAGE-
> variable.html#The-LANGUAGE-variable
>
> Last paragraph:
>
> Note: The variable LANGUAGE is ignored if the locale is set to ‘C’.
> In
> other words, you have to first enable localization, by setting LANG
> (or
> LC_ALL) to a value other than ‘C’, before you can use a language
> priority list through the LANGUAGE variable.
That note is actually not completely correct. The setting of LANG is
irrelevant in that case. You _must_ set LC_ALL or LC_MESSAGES to a
valid locale other than the POSIX locale.
Internally, the condition in the GNU libc implementation of gettext
seems to be that
setlocale (LC_MESSAGES, NULL)
returns a value other than "C" or "POSIX". That is not the case if just
"LANG" is set.
I have fixed the pure Perl version in git (branch "v1"!) so that it
shows exactly the same behavior as the XS version on my (glibc/linux!)
system.
On systems that do not support LC_MESSAGES, the old behavior is
preserved. It would be possible to check that at least for LC_ALL
something other than "C" or "POSIX" is returned but that doesn't make
much sense imho.
I have attached a file "testenv.c". If you have the locales de_DE.utf-8
and fr_FR.utf-8, you can compile and run it, and pump the results for
different combinations for LANGUAGE, LANG, LC_ALL, and LC_MESSAGES into
an SQLite database. I have used a similar file for generating the test
cases in tests/03environment_{pp,xs}.t.
Guido
#include <stdio.h>
#include <libintl.h>
#include <locale.h>
#include <stdlib.h>
#include <string.h>
static const char *values[] = { NULL, "C", "de_DE.utf-8", "fr_FR.utf-8" };
static void mysetenv (const char *key, const char *value);
static char *quote (const char *arg);
main (int argc, char *argv[]) {
int i, j, k, l;
const char *translation;
const char *locale;
printf ("DROP TABLE IF EXISTS t;\n");
printf ("CREATE TABLE t (LANGUAGE text, LANG text,\n"
" LC_MESSAGES text, LC_ALL text,\n"
" trans text, locale text);\n");
unsetenv ("LANGUAGE");
unsetenv ("LANG");
unsetenv ("LC_ALL");
unsetenv ("LC_MESSAGES");
unsetenv ("LC_TIME");
unsetenv ("LC_MONETARY");
unsetenv ("LC_CTYPE");
unsetenv ("LC_NUMERIC");
for (i = 0; i < 4; ++i) {
mysetenv ("LANGUAGE", values[i]);
for (j = 0; j < 4; ++j) {
mysetenv ("LANG", values[j]);
for (k = 0; k < 4; ++k) {
mysetenv ("LC_MESSAGES", values[k]);
for (l = 0; l < 4; ++l) {
mysetenv ("LC_ALL", values[l]);
locale = setlocale (LC_MESSAGES, NULL);
translation = dcgettext ("libc",
"No such file or directory",
LC_MESSAGES);
printf ("INSERT INTO t (LANGUAGE, LANG,\n"
" LC_MESSAGES, LC_ALL,\n"
" trans, locale)\n"
" VALUES (%s, %s, %s, %s, %s, %s);\n",
quote (values[i]), quote (values[j]),
quote (values[k]), quote (values[l]),
quote (translation), quote (locale));
}
}
}
}
return 0;
}
static void
mysetenv (const char *key, const char *value)
{
if (value)
setenv (key, value, 1);
else
unsetenv (key);
}
static char *
quote (const char *arg)
{
char *retval;
if (!arg)
return "NULL";
retval = malloc (strlen (arg) + 3);
if (!retval)
exit (255);
sprintf (retval, "'%s'", arg);
return retval;
}