[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: macOS 12 - cannot override LC_ALL=C setting from environment
From: |
Gavin Smith |
Subject: |
Re: macOS 12 - cannot override LC_ALL=C setting from environment |
Date: |
Sun, 1 Dec 2024 12:07:14 +0000 |
On Sun, Dec 01, 2024 at 02:41:43AM +0100, Bruno Haible wrote:
> > So even though we try to override LC_ALL by calling setlocale in the
> > program, nothing happens.
>
> The reason why it does not work is that this program is not following
> the documented requirement from
> https://www.gnu.org/software/gettext/manual/html_node/C.html :
> "Programmer must call setlocale (LC_ALL, "")"
>
> In other words, instead of doing
> setlocale (LC_ALL, "en_US.UTF-8");
> you need to do
> setenv ("LC_ALL", "en_US.UTF-8", 1);
> setlocale (LC_ALL, "");
Thanks, this appears to do the job. (In the test program I sent, I
also needed to set LANGUAGE.)
We had "adapted" the requirement from the gettext manual, as we don't
want to use the user's locale settings for translated strings.
> It's unfortunate that your code is working as expected on GNU, FreeBSD,
> NetBSD,
> Solaris systems but not on macOS, Windows, AIX, and OpenBSD. But there are
> (complicated) reasons for it, see
> https://git.savannah.gnu.org/gitweb/?p=gnulib.git;a=blob;f=lib/localename-unsafe.c;h=0a2654d8a3fcd025c80d4ad6eb34ce02c13879e5;hb=HEAD#l3202
I don't understand from this why using the locale name as the second
argument to setlocale doesn't work, but providing exactly the same string
as the argument to setenv does. I couldn't see anywhere in the "gettext"
or "libc" manuals to say that the second argument to setlocale should
only be "" and not the locale name. Could the gettext manual have a
note of the possibility of calling setenv before calling setlocale?
In texi2any, we use LC_MESSAGES instead of LC_ALL to try to avoid
disturbing other parts of the program. However, the gettext manual also
says that LC_CTYPE should be set.
"Remember that gettext will act as a no-op if the LC_MESSAGES and LC_CTYPE
locale categories are not both set."
https://www.gnu.org/software/gettext/manual/html_node/Language-Implementors.html
The gettext manual also has an example of setting both LC_MESSAGES and
LC_CTYPE, instead of LC_ALL.
So it is sometimes necessary to replace the ‘LC_ALL’ line in the code
above by a sequence of ‘setlocale’ lines
{
...
setlocale (LC_CTYPE, "");
setlocale (LC_MESSAGES, "");
...
}
https://www.gnu.org/software/gettext/manual/html_node/Triggering.html
We have a comment in the program:
/*
We need to set LC_MESSAGES to a valid locale other than "C" or "POSIX"
for translation via LANGUAGE to work. (The locale is "C" if the
tests are being run.)
LC_MESSAGES was reported not to exist for Perl on MS-Windows. We
could use LC_ALL instead, but (a) it's not clear if this would help,
and (b) this could interfere with the LC_CTYPE setting in XSParagraph.
*/
So I expect we need to change LC_CTYPE as well. Patrice reported that
just setting LC_MESSAGES wasn't enough in his testing.
We avoid calling this locale-switching code on MS-Windows, where LC_MESSAGES
does not exist.
Here's the change I applied for texi2any:
diff --git a/tp/Texinfo/XS/main/translations.c
b/tp/Texinfo/XS/main/translations.c
index 6748cdb612..19020bda23 100644
--- a/tp/Texinfo/XS/main/translations.c
+++ b/tp/Texinfo/XS/main/translations.c
@@ -104,18 +104,24 @@ switch_messages_locale (void)
if (working_locale)
{
- setenv_status = setenv ("LANG", working_locale, 1);
- locale = setlocale (LC_MESSAGES, working_locale);
+ setenv_status = setenv ("LC_MESSAGES", working_locale, 1);
+ || setenv ("LANG", working_locale, 1);
+ locale = setlocale (LC_MESSAGES, "");
+
+ /* Note that running "setlocale (LC_MESSAGES, working_locale)" directly
+ may not work depending on platform and/or gettext version. */
}
if (!locale || setenv_status)
{
- setenv_status = setenv ("LANG", "en_US.UTF-8", 1);
- locale = setlocale (LC_MESSAGES, "en_US.UTF-8");
+ setenv_status = setenv ("LC_MESSAGES", "en_US.UTF-8", 1);
+ || setenv ("LANG", "en_US.UTF-8", 1);
+ locale = setlocale (LC_MESSAGES, "");
}
if (!locale || setenv_status)
{
- setenv_status = setenv ("LANG", "en_US", 1);
- locale = setlocale (LC_MESSAGES, "en_US");
+ setenv_status = setenv ("LC_MESSAGES", "en_US", 1);
+ || setenv ("LANG", "en_US", 1);
+ locale = setlocale (LC_MESSAGES, "");
}
if ((!locale || setenv_status) && !locale_command)
{
@@ -143,8 +149,9 @@ switch_messages_locale (void)
free (line);
continue;
}
- setenv_status = setenv ("LANG", line, 1);
- locale = setlocale (LC_MESSAGES, line);
+ setenv_status = setenv ("LC_MESSAGES", line, 1);
+ || setenv ("LANG", line, 1);
+ locale = setlocale (LC_MESSAGES, "");
if (locale && !setenv_status)
{
free (line);
- Re: macOS 12 - cannot override LC_ALL=C setting from environment,
Gavin Smith <=