[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Bug-gnulib] c-strtod.c patch for non-glibc mixed-locale encodings
From: |
Bruno Haible |
Subject: |
Re: [Bug-gnulib] c-strtod.c patch for non-glibc mixed-locale encodings |
Date: |
Wed, 8 Sep 2004 20:21:22 +0200 |
User-agent: |
KMail/1.5 |
Paul Eggert wrote:
> I installed this obvious little patch in both gnulib and coreutils:
>
> 2004-09-08 Paul Eggert <address@hidden>
>
> * c-strtod.c (C_STRTOD) [!defined LC_ALL_MASK]: Set LC_ALL to "C",
> not just LC_NUMERIC, to avoid the unlikely possibility of mixed
> locales screwing things up. This removes an inconsistency with
> the LC_ALL_MASK case.
It has the effect of changing the locale in an undesired way, when a mixed
locale is in effect. At least on AIX (all tested versions) and, if I recall
it correctly, also on Linux/libc5.
To reproduce: The appended program prints the locale before and after the
saved_locale thing.
AIX 3.2.5:
$ unset LC_ALL LC_MESSAGES ; LANG=fr_FR.ISO8859-1 LC_NUMERIC=C ./a.out
setlocale(LC_NUMERIC,NULL) = C
setlocale(LC_MESSAGES,NULL) = fr_FR.ISO8859-1
setlocale(LC_ALL,NULL) = fr_FR.ISO8859-1 fr_FR.ISO8859-1 fr_FR.ISO8859-1 C
fr_FR.ISO8859-1 fr_FR.ISO8859-1
setlocale(LC_NUMERIC,NULL) = fr_FR.ISO8859-1
setlocale(LC_MESSAGES,NULL) = fr_FR.ISO8859-1
setlocale(LC_ALL,NULL) = fr_FR.ISO8859-1 fr_FR.ISO8859-1 fr_FR.ISO8859-1
fr_FR.ISO8859-1 fr_FR.ISO8859-1 fr_FR.ISO8859-1
AIX 4.3, 5.1:
$ unset LC_ALL LC_MESSAGES ; LANG=de_DE LC_NUMERIC=C ./a.out
setlocale(LC_NUMERIC,NULL) = C
setlocale(LC_MESSAGES,NULL) = de_DE
setlocale(LC_ALL,NULL) = de_DE de_DE de_DE C de_DE de_DE
setlocale(LC_NUMERIC,NULL) = de_DE
setlocale(LC_MESSAGES,NULL) = de_DE
setlocale(LC_ALL,NULL) = de_DE de_DE de_DE de_DE de_DE de_DE
The workaround, that works on AIX, is to save the name of each locale facets
individually.
Bruno
====================== savedlocale-test.c ======================
#include <locale.h>
#include <stdio.h>
int main () {
char *saved_locale;
setlocale(LC_ALL,"");
printf("setlocale(LC_NUMERIC,NULL) = %s\n", setlocale(LC_NUMERIC,NULL));
printf("setlocale(LC_MESSAGES,NULL) = %s\n", setlocale(LC_MESSAGES,NULL));
printf("setlocale(LC_ALL,NULL) = %s\n", setlocale(LC_ALL,NULL));
printf("\n");
saved_locale = setlocale (LC_ALL, NULL);
if (saved_locale) setlocale (LC_ALL, saved_locale);
printf("setlocale(LC_NUMERIC,NULL) = %s\n", setlocale(LC_NUMERIC,NULL));
printf("setlocale(LC_MESSAGES,NULL) = %s\n", setlocale(LC_MESSAGES,NULL));
printf("setlocale(LC_ALL,NULL) = %s\n", setlocale(LC_ALL,NULL));
printf("\n");
return 0;
}
====================== savedlocale that works on AIX ======================
#include <locale.h>
#include <stdio.h>
#include <string.h>
int main () {
char *saved_locale1;
char *saved_locale2;
setlocale(LC_ALL,"");
printf("setlocale(LC_NUMERIC,NULL) = %s\n", setlocale(LC_NUMERIC,NULL));
printf("setlocale(LC_MESSAGES,NULL) = %s\n", setlocale(LC_MESSAGES,NULL));
printf("setlocale(LC_ALL,NULL) = %s\n", setlocale(LC_ALL,NULL));
printf("\n");
saved_locale1 = setlocale (LC_NUMERIC, NULL);
if (saved_locale1) saved_locale1 = strdup (saved_locale1);
saved_locale2 = setlocale (LC_MESSAGES, NULL);
if (saved_locale2) saved_locale2 = strdup (saved_locale2);
if (saved_locale1) setlocale (LC_NUMERIC, saved_locale1);
if (saved_locale2) setlocale (LC_MESSAGES, saved_locale2);
printf("setlocale(LC_NUMERIC,NULL) = %s\n", setlocale(LC_NUMERIC,NULL));
printf("setlocale(LC_MESSAGES,NULL) = %s\n", setlocale(LC_MESSAGES,NULL));
printf("setlocale(LC_ALL,NULL) = %s\n", setlocale(LC_ALL,NULL));
printf("\n");
return 0;
}