bug-gnulib
[Top][All Lists]
Advanced

[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;
}





reply via email to

[Prev in Thread] Current Thread [Next in Thread]