diff options
-rw-r--r-- | NEWS | 5 | ||||
-rw-r--r-- | gettext-runtime/NEWS | 6 | ||||
-rw-r--r-- | gettext-runtime/intl/ChangeLog | 19 | ||||
-rw-r--r-- | gettext-runtime/intl/Makefile.in | 8 | ||||
-rw-r--r-- | gettext-runtime/intl/gettextP.h | 5 | ||||
-rw-r--r-- | gettext-runtime/intl/libgnuintl.h.in | 23 | ||||
-rw-r--r-- | gettext-runtime/intl/localename.c | 70 | ||||
-rw-r--r-- | gettext-runtime/intl/setlocale.c | 1015 | ||||
-rw-r--r-- | gettext-runtime/m4/ChangeLog | 6 | ||||
-rw-r--r-- | gettext-runtime/m4/intl.m4 | 12 | ||||
-rw-r--r-- | gettext-tools/tests/ChangeLog | 6 | ||||
-rw-r--r-- | gettext-tools/tests/format-c-3-prg.c | 7 | ||||
-rw-r--r-- | gettext-tools/tests/format-c-4-prg.c | 7 | ||||
-rw-r--r-- | gettext-tools/tests/plural-1-prg.c | 7 |
14 files changed, 1179 insertions, 17 deletions
@@ -1,5 +1,10 @@ Version 0.18 - January 2008 +* Runtime behaviour: + On MacOS X and Windows systems, <libintl.h> now extends setlocale() and + newlocale() so that their determination of the default locale considers + the choice the user has made in the system control panels. + * PO file format: There is a new field 'Language' in the header entry. It denotes the language code (plus optional country code) for the PO file. This field can be used diff --git a/gettext-runtime/NEWS b/gettext-runtime/NEWS index 17a3ed2..06f504f 100644 --- a/gettext-runtime/NEWS +++ b/gettext-runtime/NEWS @@ -1,3 +1,9 @@ +Version 0.18 - December 2009 + +* On MacOS X and Windows systems, <libintl.h> now extends setlocale() and + newlocale() so that their determination of the default locale considers + the choice the user has made in the system control panels. + Version 0.16.1 - November 2006 * Bug fix in the gettext.m4 autoconf macros. diff --git a/gettext-runtime/intl/ChangeLog b/gettext-runtime/intl/ChangeLog index 32b5188..e425d34 100644 --- a/gettext-runtime/intl/ChangeLog +++ b/gettext-runtime/intl/ChangeLog @@ -1,5 +1,24 @@ 2009-12-21 Bruno Haible <bruno@clisp.org> + Define override of setlocale and newlocale functions. + * gettextP.h (gl_locale_name_environ): New macro. + (_nl_locale_name_environ): New declaration. + * localename.c (gl_locale_name_environ): New function, extracted from + gl_locale_name_posix. Ignore dummy LANG values on MacOS X and Cygwin. + (gl_locale_name_posix): Invoke it. + (gl_locale_name_default): Add comments. Use Windows native API also on + Cygwin. + * libgnuintl.h.in: On MacOS X, include <xlocale.h>. + (setlocale, newlocale): New overrides. + * setlocale.c: New file. + * Makefile.in (SOURCES): Add setlocale.c. + (OBJECTS): Add setlocale.$lo. + (setlocale.lo): New rule. + (libgnuintl.h, libintl.h): Substitute also HAVE_NEWLOCALE. + (setlocale.$lo): Define dependencies. + +2009-12-21 Bruno Haible <bruno@clisp.org> + Update list of Win32 locale ids. * localename.c (LANG_ROMANSH): Renamed from LANG_RHAETO_ROMANCE. (LANG_SAMI): Renamed from LANG_SAAMI. diff --git a/gettext-runtime/intl/Makefile.in b/gettext-runtime/intl/Makefile.in index d0a1f80..12390b7 100644 --- a/gettext-runtime/intl/Makefile.in +++ b/gettext-runtime/intl/Makefile.in @@ -157,6 +157,7 @@ SOURCES = \ localename.c \ log.c \ printf.c \ + setlocale.c \ version.c \ osdep.c \ os2compat.c \ @@ -188,6 +189,7 @@ OBJECTS = \ localename.$lo \ log.$lo \ printf.$lo \ + setlocale.$lo \ version.$lo \ osdep.$lo \ intl-compat.$lo @@ -293,6 +295,8 @@ log.lo: $(srcdir)/log.c $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC --mode=compile $(COMPILE) $(srcdir)/log.c printf.lo: $(srcdir)/printf.c $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC --mode=compile $(COMPILE) $(srcdir)/printf.c +setlocale.lo: $(srcdir)/setlocale.c + $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC --mode=compile $(COMPILE) $(srcdir)/setlocale.c version.lo: $(srcdir)/version.c $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC --mode=compile $(COMPILE) $(srcdir)/version.c osdep.lo: $(srcdir)/osdep.c @@ -341,6 +345,7 @@ libgnuintl.h: $(srcdir)/libgnuintl.h.in sed -e '/IN_LIBGLOCALE/d' \ -e 's,@''HAVE_POSIX_PRINTF''@,@HAVE_POSIX_PRINTF@,g' \ -e 's,@''HAVE_ASPRINTF''@,@HAVE_ASPRINTF@,g' \ + -e 's,@''HAVE_NEWLOCALE''@,@HAVE_NEWLOCALE@,g' \ -e 's,@''HAVE_SNPRINTF''@,@HAVE_SNPRINTF@,g' \ -e 's,@''HAVE_WPRINTF''@,@HAVE_WPRINTF@,g' \ < $(srcdir)/libgnuintl.h.in \ @@ -358,6 +363,7 @@ libintl.h: $(srcdir)/libgnuintl.h.in sed -e '/IN_LIBGLOCALE/d' \ -e 's,@''HAVE_POSIX_PRINTF''@,@HAVE_POSIX_PRINTF@,g' \ -e 's,@''HAVE_ASPRINTF''@,@HAVE_ASPRINTF@,g' \ + -e 's,@''HAVE_NEWLOCALE''@,@HAVE_NEWLOCALE@,g' \ -e 's,@''HAVE_SNPRINTF''@,@HAVE_SNPRINTF@,g' \ -e 's,@''HAVE_WPRINTF''@,@HAVE_WPRINTF@,g' \ < $(srcdir)/libgnuintl.h.in > libintl.h @@ -571,7 +577,7 @@ uninstall: info dvi ps pdf html: $(OBJECTS): ../config.h libgnuintl.h -bindtextdom.$lo dcgettext.$lo dcigettext.$lo dcngettext.$lo dgettext.$lo dngettext.$lo finddomain.$lo gettext.$lo intl-compat.$lo loadmsgcat.$lo localealias.$lo ngettext.$lo textdomain.$lo: $(srcdir)/gettextP.h $(srcdir)/gmo.h $(srcdir)/loadinfo.h +bindtextdom.$lo dcgettext.$lo dcigettext.$lo dcngettext.$lo dgettext.$lo dngettext.$lo finddomain.$lo gettext.$lo intl-compat.$lo loadmsgcat.$lo localealias.$lo ngettext.$lo setlocale.$lo textdomain.$lo: $(srcdir)/gettextP.h $(srcdir)/gmo.h $(srcdir)/loadinfo.h hash-string.$lo dcigettext.$lo loadmsgcat.$lo: $(srcdir)/hash-string.h explodename.$lo l10nflist.$lo: $(srcdir)/loadinfo.h dcigettext.$lo loadmsgcat.$lo plural.$lo plural-exp.$lo: $(srcdir)/plural-exp.h diff --git a/gettext-runtime/intl/gettextP.h b/gettext-runtime/intl/gettextP.h index 39af4a7..3555ede 100644 --- a/gettext-runtime/intl/gettextP.h +++ b/gettext-runtime/intl/gettextP.h @@ -1,5 +1,5 @@ /* Header describing internals of libintl library. - Copyright (C) 1995-1999, 2000-2007 Free Software Foundation, Inc. + Copyright (C) 1995-1999, 2000-2007, 2009 Free Software Foundation, Inc. Written by Ulrich Drepper <drepper@cygnus.com>, 1995. This program is free software; you can redistribute it and/or modify it @@ -238,6 +238,9 @@ extern void _nl_locale_name_canonicalize (char *name); # define gl_locale_name_posix _nl_locale_name_posix extern const char *_nl_locale_name_posix (int category, const char *categoryname); +# define gl_locale_name_environ _nl_locale_name_environ +extern const char *_nl_locale_name_environ (int category, + const char *categoryname); # define gl_locale_name_default _nl_locale_name_default extern const char *_nl_locale_name_default (void); # define gl_locale_name _nl_locale_name diff --git a/gettext-runtime/intl/libgnuintl.h.in b/gettext-runtime/intl/libgnuintl.h.in index 06ea95c..6973c3a 100644 --- a/gettext-runtime/intl/libgnuintl.h.in +++ b/gettext-runtime/intl/libgnuintl.h.in @@ -1,5 +1,5 @@ /* Message catalogs for internationalization. - Copyright (C) 1995-1997, 2000-2008 Free Software Foundation, Inc. + Copyright (C) 1995-1997, 2000-2009 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published @@ -20,6 +20,9 @@ #define _LIBINTL_H 1 #include <locale.h> +#if (defined __APPLE__ && defined __MACH__) && @HAVE_NEWLOCALE@ +# include <xlocale.h> +#endif /* The LC_MESSAGES locale category is the category used by the functions gettext() and dgettext(). It is specified in POSIX, but not in ANSI C. @@ -419,6 +422,24 @@ extern int vswprintf (wchar_t *, size_t, const wchar_t *, va_list); #endif +/* Support for the locale chosen by the user. */ +#if (defined __APPLE__ && defined __MACH__) || defined _WIN32 || defined __WIN32__ || defined __CYGWIN__ + +#undef setlocale +#define setlocale libintl_setlocale +extern char *setlocale (int, const char *); + +#if @HAVE_NEWLOCALE@ + +#undef newlocale +#define newlocale libintl_newlocale +extern locale_t newlocale (int, const char *, locale_t); + +#endif + +#endif + + /* Support for relocatable packages. */ /* Sets the original and the current installation prefix of the package. diff --git a/gettext-runtime/intl/localename.c b/gettext-runtime/intl/localename.c index 1310cb5..ceed70f 100644 --- a/gettext-runtime/intl/localename.c +++ b/gettext-runtime/intl/localename.c @@ -31,9 +31,9 @@ #include <stdlib.h> #include <locale.h> +#include <string.h> #if HAVE_CFLOCALECOPYCURRENT || HAVE_CFPREFERENCESCOPYAPPVALUE -# include <string.h> # include <CoreFoundation/CFString.h> # if HAVE_CFLOCALECOPYCURRENT # include <CoreFoundation/CFLocale.h> @@ -46,7 +46,7 @@ # define WIN32_NATIVE #endif -#ifdef WIN32_NATIVE +#if defined WIN32_NATIVE || defined __CYGWIN__ /* WIN32 or Cygwin */ # define WIN32_LEAN_AND_MEAN # include <windows.h> /* List of language codes, sorted by value: @@ -1394,7 +1394,7 @@ gl_locale_name_canonicalize (char *name) #endif -#ifdef WIN32_NATIVE +#if defined WIN32_NATIVE || defined __CYGWIN__ /* WIN32 or Cygwin */ /* Canonicalize a Win32 native locale name to a Unix locale name. NAME is a sufficiently large buffer. @@ -2518,6 +2518,30 @@ gl_locale_name_posix (int category, const char *categoryname) #if defined HAVE_SETLOCALE && defined HAVE_LC_MESSAGES && defined HAVE_LOCALE_NULL return setlocale (category, NULL); #else + /* On other systems we ignore what setlocale reports and instead look at the + environment variables directly. This is necessary + 1. on systems which have a facility for customizing the default locale + (MacOS X, native Windows, Cygwin) and where the system's setlocale() + function ignores this default locale (MacOS X, Cygwin), in two cases: + a. when the user missed to use the setlocale() override from libintl + (for example by not including <libintl.h>), + b. when setlocale supports only the "C" locale, such as on Cygwin + 1.5.x. In this case even the override from libintl cannot help. + 2. on all systems where setlocale supports only the "C" locale. */ + /* Strictly speaking, it is a POSIX violation to look at the environment + variables regardless whether setlocale has been called or not. POSIX + says: + "For C-language programs, the POSIX locale shall be the + default locale when the setlocale() function is not called." + But we assume that all programs that use internationalized APIs call + setlocale (LC_ALL, ""). */ + return gl_locale_name_environ (category, categoryname); +#endif +} + +const char * +gl_locale_name_environ (int category, const char *categoryname) +{ const char *retval; /* Setting of LC_ALL overrides all other. */ @@ -2531,10 +2555,21 @@ gl_locale_name_posix (int category, const char *categoryname) /* Last possibility is the LANG environment variable. */ retval = getenv ("LANG"); if (retval != NULL && retval[0] != '\0') - return retval; + { +#if HAVE_CFLOCALECOPYCURRENT || HAVE_CFPREFERENCESCOPYAPPVALUE + /* MacOS X 10.2 or newer. + Ignore invalid LANG value set by the Terminal application. */ + if (strcmp (retval, "UTF-8") != 0) +#endif +#if defined __CYGWIN__ + /* Cygwin. + Ignore dummy LANG value set by ~/.profile. */ + if (strcmp (retval, "C.UTF-8") != 0) +#endif + return retval; + } return NULL; -#endif } const char * @@ -2547,9 +2582,28 @@ gl_locale_name_default (void) implementation-defined locale. Some implementations may provide facilities for local installation administrators to set the default locale, customizing it for each location. POSIX:2001 does not require - such a facility. */ + such a facility. + + The systems with such a facility are MacOS X and Windows: They provide a + GUI that allows the user to choose a locale. + - On MacOS X, by default, none of LC_* or LANG are set. Starting with + MacOS X 10.4 or 10.5, LANG is set for processes launched by the + 'Terminal' application (but sometimes to an incorrect value "UTF-8"). + When no environment variable is set, setlocale (LC_ALL, "") uses the + "C" locale. + - On native Windows, by default, none of LC_* or LANG are set. + When no environment variable is set, setlocale (LC_ALL, "") uses the + locale chosen by the user. + - On Cygwin 1.5.x, by default, none of LC_* or LANG are set. + When no environment variable is set, setlocale (LC_ALL, "") uses the + "C" locale. + - On Cygwin 1.7, by default, LANG is set to "C.UTF-8" when the default + ~/.profile is executed. + When no environment variable is set, setlocale (LC_ALL, "") uses the + "C.UTF-8" locale, which operates in the same way as the "C" locale. + */ -#if !(HAVE_CFLOCALECOPYCURRENT || HAVE_CFPREFERENCESCOPYAPPVALUE || defined(WIN32_NATIVE)) +#if !(HAVE_CFLOCALECOPYCURRENT || HAVE_CFPREFERENCESCOPYAPPVALUE || defined WIN32_NATIVE || defined __CYGWIN__) /* The system does not have a way of setting the locale, other than the POSIX specified environment variables. We use C as default locale. */ @@ -2603,7 +2657,7 @@ gl_locale_name_default (void) # endif -# if defined(WIN32_NATIVE) /* WIN32, not Cygwin */ +# if defined WIN32_NATIVE || defined __CYGWIN__ /* WIN32 or Cygwin */ { LCID lcid; diff --git a/gettext-runtime/intl/setlocale.c b/gettext-runtime/intl/setlocale.c new file mode 100644 index 0000000..2a5e260 --- /dev/null +++ b/gettext-runtime/intl/setlocale.c @@ -0,0 +1,1015 @@ +/* setlocale() function that respects the locale chosen by the user. + Copyright (C) 2009 Free Software Foundation, Inc. + Written by Bruno Haible <bruno@clisp.org>, 2009. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU Library General Public License as published + by the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + USA. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +/* Override setlocale() and newlocale() so that when the default locale is + requested (locale = "") and no relevant environment variable is set, the + locale chosen by the user is used. + This matters on MacOS X 10 and Windows. + See the comments in localename.c, function gl_locale_name_default. */ + +#include <locale.h> +#include <stdlib.h> +#include <string.h> + +/* When building a DLL, we must export some functions. Note that because + the functions are only defined for binary backward compatibility, we + don't need to use __declspec(dllimport) in any case. */ +#if HAVE_VISIBILITY && BUILDING_DLL +# define DLL_EXPORTED __attribute__((__visibility__("default"))) +#elif defined _MSC_VER && BUILDING_DLL +# define DLL_EXPORTED __declspec(dllexport) +#else +# define DLL_EXPORTED +#endif + +#include "gettextP.h" + +#if (defined __APPLE__ && defined __MACH__) || defined _WIN32 || defined __WIN32__ || defined __CYGWIN__ + +# undef setlocale +# undef newlocale + +/* Return string representation of locale category CATEGORY. */ +static const char * +category_to_name (int category) +{ + const char *retval; + + switch (category) + { + case LC_COLLATE: + retval = "LC_COLLATE"; + break; + case LC_CTYPE: + retval = "LC_CTYPE"; + break; + case LC_MONETARY: + retval = "LC_MONETARY"; + break; + case LC_NUMERIC: + retval = "LC_NUMERIC"; + break; + case LC_TIME: + retval = "LC_TIME"; + break; + case LC_MESSAGES: + retval = "LC_MESSAGES"; + break; + default: + /* If you have a better idea for a default value let me know. */ + retval = "LC_XXX"; + } + + return retval; +} + +# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ + +/* The native Win32 setlocale() function expects locale names of the form + "German" or "German_Germany" or "DEU", but not "de" or "de_DE". We need + to convert the names from the form with ISO 639 language code and ISO 3166 + country code to the form with English names or with three-letter identifier. + The three-letter identifiers known by a Windows XP SP2 or SP3 are: + AFK Afrikaans_South Africa.1252 + ARA Arabic_Saudi Arabia.1256 + ARB Arabic_Lebanon.1256 + ARE Arabic_Egypt.1256 + ARG Arabic_Algeria.1256 + ARH Arabic_Bahrain.1256 + ARI Arabic_Iraq.1256 + ARJ Arabic_Jordan.1256 + ARK Arabic_Kuwait.1256 + ARL Arabic_Libya.1256 + ARM Arabic_Morocco.1256 + ARO Arabic_Oman.1256 + ARQ Arabic_Qatar.1256 + ARS Arabic_Syria.1256 + ART Arabic_Tunisia.1256 + ARU Arabic_U.A.E..1256 + ARY Arabic_Yemen.1256 + AZE Azeri (Latin)_Azerbaijan.1254 + BEL Belarusian_Belarus.1251 + BGR Bulgarian_Bulgaria.1251 + BSB Bosnian_Bosnia and Herzegovina.1250 + BSC Bosnian (Cyrillic)_Bosnia and Herzegovina.1250 (wrong encoding!) + CAT Catalan_Spain.1252 + CHH Chinese_Hong Kong S.A.R..950 + CHI Chinese_Singapore.936 + CHS Chinese_People's Republic of China.936 + CHT Chinese_Taiwan.950 + CSY Czech_Czech Republic.1250 + CYM Welsh_United Kingdom.1252 + DAN Danish_Denmark.1252 + DEA German_Austria.1252 + DEC German_Liechtenstein.1252 + DEL German_Luxembourg.1252 + DES German_Switzerland.1252 + DEU German_Germany.1252 + ELL Greek_Greece.1253 + ENA English_Australia.1252 + ENB English_Caribbean.1252 + ENC English_Canada.1252 + ENG English_United Kingdom.1252 + ENI English_Ireland.1252 + ENJ English_Jamaica.1252 + ENL English_Belize.1252 + ENP English_Republic of the Philippines.1252 + ENS English_South Africa.1252 + ENT English_Trinidad and Tobago.1252 + ENU English_United States.1252 + ENW English_Zimbabwe.1252 + ENZ English_New Zealand.1252 + ESA Spanish_Panama.1252 + ESB Spanish_Bolivia.1252 + ESC Spanish_Costa Rica.1252 + ESD Spanish_Dominican Republic.1252 + ESE Spanish_El Salvador.1252 + ESF Spanish_Ecuador.1252 + ESG Spanish_Guatemala.1252 + ESH Spanish_Honduras.1252 + ESI Spanish_Nicaragua.1252 + ESL Spanish_Chile.1252 + ESM Spanish_Mexico.1252 + ESN Spanish_Spain.1252 + ESO Spanish_Colombia.1252 + ESP Spanish_Spain.1252 + ESR Spanish_Peru.1252 + ESS Spanish_Argentina.1252 + ESU Spanish_Puerto Rico.1252 + ESV Spanish_Venezuela.1252 + ESY Spanish_Uruguay.1252 + ESZ Spanish_Paraguay.1252 + ETI Estonian_Estonia.1257 + EUQ Basque_Spain.1252 + FAR Farsi_Iran.1256 + FIN Finnish_Finland.1252 + FOS Faroese_Faroe Islands.1252 + FPO Filipino_Philippines.1252 + FRA French_France.1252 + FRB French_Belgium.1252 + FRC French_Canada.1252 + FRL French_Luxembourg.1252 + FRM French_Principality of Monaco.1252 + FRS French_Switzerland.1252 + FYN Frisian_Netherlands.1252 + GLC Galician_Spain.1252 + HEB Hebrew_Israel.1255 + HRB Croatian_Bosnia and Herzegovina.1250 + HRV Croatian_Croatia.1250 + HUN Hungarian_Hungary.1250 + IND Indonesian_Indonesia.1252 + IRE Irish_Ireland.1252 + ISL Icelandic_Iceland.1252 + ITA Italian_Italy.1252 + ITS Italian_Switzerland.1252 + IUK Inuktitut (Latin)_Canada.1252 + JPN Japanese_Japan.932 + KKZ Kazakh_Kazakhstan.1251 + KOR Korean_Korea.949 + KYR Kyrgyz_Kyrgyzstan.1251 + LBX Luxembourgish_Luxembourg.1252 + LTH Lithuanian_Lithuania.1257 + LVI Latvian_Latvia.1257 + MKI FYRO Macedonian_Former Yugoslav Republic of Macedonia.1251 + MON Mongolian_Mongolia.1251 + MPD Mapudungun_Chile.1252 + MSB Malay_Brunei Darussalam.1252 + MSL Malay_Malaysia.1252 + MWK Mohawk_Canada.1252 + NLB Dutch_Belgium.1252 + NLD Dutch_Netherlands.1252 + NON Norwegian-Nynorsk_Norway.1252 + NOR Norwegian (Bokmål)_Norway.1252 + NSO Northern Sotho_South Africa.1252 + PLK Polish_Poland.1250 + PTB Portuguese_Brazil.1252 + PTG Portuguese_Portugal.1252 + QUB Quechua_Bolivia.1252 + QUE Quechua_Ecuador.1252 + QUP Quechua_Peru.1252 + RMC Romansh_Switzerland.1252 + ROM Romanian_Romania.1250 + RUS Russian_Russia.1251 + SKY Slovak_Slovakia.1250 + SLV Slovenian_Slovenia.1250 + SMA Sami (Southern)_Norway.1252 + SMB Sami (Southern)_Sweden.1252 + SME Sami (Northern)_Norway.1252 + SMF Sami (Northern)_Sweden.1252 + SMG Sami (Northern)_Finland.1252 + SMJ Sami (Lule)_Norway.1252 + SMK Sami (Lule)_Sweden.1252 + SMN Sami (Inari)_Finland.1252 + SMS Sami (Skolt)_Finland.1252 + SQI Albanian_Albania.1250 + SRB Serbian (Cyrillic)_Serbia and Montenegro.1251 + SRL Serbian (Latin)_Serbia and Montenegro.1250 + SRN Serbian (Cyrillic)_Bosnia and Herzegovina.1251 + SRS Serbian (Latin)_Bosnia and Herzegovina.1250 + SVE Swedish_Sweden.1252 + SVF Swedish_Finland.1252 + SWK Swahili_Kenya.1252 + THA Thai_Thailand.874 + TRK Turkish_Turkey.1254 + TSN Tswana_South Africa.1252 + TTT Tatar_Russia.1251 + UKR Ukrainian_Ukraine.1251 + URD Urdu_Islamic Republic of Pakistan.1256 + USA English_United States.1252 + UZB Uzbek (Latin)_Uzbekistan.1254 + VIT Vietnamese_Viet Nam.1258 + XHO Xhosa_South Africa.1252 + ZHH Chinese_Hong Kong S.A.R..950 + ZHI Chinese_Singapore.936 + ZHM Chinese_Macau S.A.R..950 + ZUL Zulu_South Africa.1252 + */ + +/* Table from ISO 639 language code, optionally with country or script suffix, + to English name. + Keep in sync with the gl_locale_name_from_win32_LANGID function in + localename.c! */ +struct table_entry +{ + const char *code; + const char *english; +}; +static const struct table_entry language_table[] = + { + { "af", "Afrikaans" }, + { "am", "Amharic" }, + { "ar", "Arabic" }, + { "arn", "Mapudungun" }, + { "as", "Assamese" }, + { "az@cyrillic", "Azeri (Cyrillic)" }, + { "az@latin", "Azeri (Latin)" }, + { "ba", "Bashkir" }, + { "be", "Belarusian" }, + { "ber", "Tamazight" }, + { "ber@arabic", "Tamazight (Arabic)" }, + { "ber@latin", "Tamazight (Latin)" }, + { "bg", "Bulgarian" }, + { "bin", "Edo" }, + { "bn", "Bengali" }, + { "bn_BD", "Bengali (Bangladesh)" }, + { "bn_IN", "Bengali (India)" }, + { "bnt", "Sutu" }, + { "bo", "Tibetan" }, + { "br", "Breton" }, + { "bs", "BSB" }, /* "Bosnian (Latin)" */ + { "bs@cyrillic", "BSC" }, /* Bosnian (Cyrillic) */ + { "ca", "Catalan" }, + { "chr", "Cherokee" }, + { "co", "Corsican" }, + { "cpe", "Hawaiian" }, + { "cs", "Czech" }, + { "cy", "Welsh" }, + { "da", "Danish" }, + { "de", "German" }, + { "dsb", "Lower Sorbian" }, + { "dv", "Divehi" }, + { "el", "Greek" }, + { "en", "English" }, + { "es", "Spanish" }, + { "et", "Estonian" }, + { "eu", "Basque" }, + { "fa", "Farsi" }, + { "ff", "Fulfulde" }, + { "fi", "Finnish" }, + { "fo", "Faroese" }, /* "Faeroese" does not work */ + { "fr", "French" }, + { "fy", "Frisian" }, + { "ga", "IRE" }, /* Gaelic (Ireland) */ + { "gd", "Gaelic (Scotland)" }, + { "gd", "Scottish Gaelic" }, + { "gl", "Galician" }, + { "gn", "Guarani" }, + { "gsw", "Alsatian" }, + { "gu", "Gujarati" }, + { "ha", "Hausa" }, + { "he", "Hebrew" }, + { "hi", "Hindi" }, + { "hr", "Croatian" }, + { "hsb", "Upper Sorbian" }, + { "hu", "Hungarian" }, + { "hy", "Armenian" }, + { "id", "Indonesian" }, + { "ig", "Igbo" }, + { "ii", "Yi" }, + { "is", "Icelandic" }, + { "it", "Italian" }, + { "iu", "IUK" }, /* Inuktitut */ + { "ja", "Japanese" }, + { "ka", "Georgian" }, + { "kk", "Kazakh" }, + { "kl", "Greenlandic" }, + { "km", "Cambodian" }, + { "km", "Khmer" }, + { "kn", "Kannada" }, + { "ko", "Korean" }, + { "kok", "Konkani" }, + { "kr", "Kanuri" }, + { "ks", "Kashmiri" }, + { "ks_IN", "Kashmiri_India" }, + { "ks_PK", "Kashmiri (Arabic)_Pakistan" }, + { "ky", "Kyrgyz" }, + { "la", "Latin" }, + { "lb", "Luxembourgish" }, + { "lo", "Lao" }, + { "lt", "Lithuanian" }, + { "lv", "Latvian" }, + { "mi", "Maori" }, + { "mk", "FYRO Macedonian" }, + { "mk", "Macedonian" }, + { "ml", "Malayalam" }, + { "mn", "Mongolian" }, + { "mni", "Manipuri" }, + { "moh", "Mohawk" }, + { "mr", "Marathi" }, + { "ms", "Malay" }, + { "mt", "Maltese" }, + { "my", "Burmese" }, + { "nb", "NOR" }, /* Norwegian Bokmål */ + { "ne", "Nepali" }, + { "nic", "Ibibio" }, + { "nl", "Dutch" }, + { "nn", "NON" }, /* Norwegian Nynorsk */ + { "no", "Norwegian" }, + { "nso", "Northern Sotho" }, + { "nso", "Sepedi" }, + { "oc", "Occitan" }, + { "om", "Oromo" }, + { "or", "Oriya" }, + { "pa", "Punjabi" }, + { "pap", "Papiamentu" }, + { "pl", "Polish" }, + { "prs", "Dari" }, + { "ps", "Pashto" }, + { "pt", "Portuguese" }, + { "qu", "Quechua" }, + { "qut", "K'iche'" }, + { "rm", "Romansh" }, + { "ro", "Romanian" }, + { "ru", "Russian" }, + { "rw", "Kinyarwanda" }, + { "sa", "Sanskrit" }, + { "sah", "Yakut" }, + { "sd", "Sindhi" }, + { "se", "Sami (Northern)" }, + { "se", "Northern Sami" }, + { "si", "Sinhalese" }, + { "sk", "Slovak" }, + { "sl", "Slovenian" }, + { "sma", "Sami (Southern)" }, + { "sma", "Southern Sami" }, + { "smj", "Sami (Lule)" }, + { "smj", "Lule Sami" }, + { "smn", "Sami (Inari)" }, + { "smn", "Inari Sami" }, + { "sms", "Sami (Skolt)" }, + { "sms", "Skolt Sami" }, + { "so", "Somali" }, + { "sq", "Albanian" }, + { "sr", "Serbian (Latin)" }, + { "sr@cyrillic", "SRB" }, /* Serbian (Cyrillic) */ + { "sw", "Swahili" }, + { "syr", "Syriac" }, + { "ta", "Tamil" }, + { "te", "Telugu" }, + { "tg", "Tajik" }, + { "th", "Thai" }, + { "ti", "Tigrinya" }, + { "tk", "Turkmen" }, + { "tl", "Filipino" }, + { "tn", "Tswana" }, + { "tr", "Turkish" }, + { "ts", "Tsonga" }, + { "tt", "Tatar" }, + { "ug", "Uighur" }, + { "uk", "Ukrainian" }, + { "ur", "Urdu" }, + { "uz", "Uzbek" }, + { "uz", "Uzbek (Latin)" }, + { "uz@cyrillic", "Uzbek (Cyrillic)" }, + { "ve", "Venda" }, + { "vi", "Vietnamese" }, + { "wen", "Sorbian" }, + { "wo", "Wolof" }, + { "xh", "Xhosa" }, + { "yi", "Yiddish" }, + { "yo", "Yoruba" }, + { "zh", "Chinese" }, + { "zu", "Zulu" } + }; + +/* Table from ISO 3166 country code to English name. + Keep in sync with the gl_locale_name_from_win32_LANGID function in + localename.c! */ +static const struct table_entry country_table[] = + { + { "AE", "U.A.E." }, + { "AF", "Afghanistan" }, + { "AL", "Albania" }, + { "AM", "Armenia" }, + { "AN", "Netherlands Antilles" }, + { "AR", "Argentina" }, + { "AT", "Austria" }, + { "AU", "Australia" }, + { "AZ", "Azerbaijan" }, + { "BA", "Bosnia and Herzegovina" }, + { "BD", "Bangladesh" }, + { "BE", "Belgium" }, + { "BG", "Bulgaria" }, + { "BH", "Bahrain" }, + { "BN", "Brunei Darussalam" }, + { "BO", "Bolivia" }, + { "BR", "Brazil" }, + { "BT", "Bhutan" }, + { "BY", "Belarus" }, + { "BZ", "Belize" }, + { "CA", "Canada" }, + { "CG", "Congo" }, + { "CH", "Switzerland" }, + { "CI", "Cote d'Ivoire" }, + { "CL", "Chile" }, + { "CM", "Cameroon" }, + { "CN", "People's Republic of China" }, + { "CO", "Colombia" }, + { "CR", "Costa Rica" }, + { "CS", "Serbia and Montenegro" }, + { "CZ", "Czech Republic" }, + { "DE", "Germany" }, + { "DK", "Denmark" }, + { "DO", "Dominican Republic" }, + { "DZ", "Algeria" }, + { "EC", "Ecuador" }, + { "EE", "Estonia" }, + { "EG", "Egypt" }, + { "ER", "Eritrea" }, + { "ES", "Spain" }, + { "ET", "Ethiopia" }, + { "FI", "Finland" }, + { "FO", "Faroe Islands" }, + { "FR", "France" }, + { "GB", "United Kingdom" }, + { "GD", "Caribbean" }, + { "GE", "Georgia" }, + { "GL", "Greenland" }, + { "GR", "Greece" }, + { "GT", "Guatemala" }, + { "HK", "Hong Kong" }, + { "HK", "Hong Kong S.A.R." }, + { "HN", "Honduras" }, + { "HR", "Croatia" }, + { "HT", "Haiti" }, + { "HU", "Hungary" }, + { "ID", "Indonesia" }, + { "IE", "Ireland" }, + { "IL", "Israel" }, + { "IN", "India" }, + { "IQ", "Iraq" }, + { "IR", "Iran" }, + { "IS", "Iceland" }, + { "IT", "Italy" }, + { "JM", "Jamaica" }, + { "JO", "Jordan" }, + { "JP", "Japan" }, + { "KE", "Kenya" }, + { "KG", "Kyrgyzstan" }, + { "KH", "Cambodia" }, + { "KR", "South Korea" }, + { "KW", "Kuwait" }, + { "KZ", "Kazakhstan" }, + { "LA", "Laos" }, + { "LB", "Lebanon" }, + { "LI", "Liechtenstein" }, + { "LK", "Sri Lanka" }, + { "LT", "Lithuania" }, + { "LU", "Luxembourg" }, + { "LV", "Latvia" }, + { "LY", "Libya" }, + { "MA", "Morocco" }, + { "MC", "Principality of Monaco" }, + { "MD", "Moldava" }, + { "MD", "Moldova" }, + { "ME", "Montenegro" }, + { "MK", "Former Yugoslav Republic of Macedonia" }, + { "ML", "Mali" }, + { "MM", "Myanmar" }, + { "MN", "Mongolia" }, + { "MO", "Macau S.A.R." }, + { "MT", "Malta" }, + { "MV", "Maldives" }, + { "MX", "Mexico" }, + { "MY", "Malaysia" }, + { "NG", "Nigeria" }, + { "NI", "Nicaragua" }, + { "NL", "Netherlands" }, + { "NO", "Norway" }, + { "NP", "Nepal" }, + { "NZ", "New Zealand" }, + { "OM", "Oman" }, + { "PA", "Panama" }, + { "PE", "Peru" }, + { "PH", "Philippines" }, + { "PK", "Islamic Republic of Pakistan" }, + { "PL", "Poland" }, + { "PR", "Puerto Rico" }, + { "PT", "Portugal" }, + { "PY", "Paraguay" }, + { "QA", "Qatar" }, + { "RE", "Reunion" }, + { "RO", "Romania" }, + { "RS", "Serbia" }, + { "RU", "Russia" }, + { "RW", "Rwanda" }, + { "SA", "Saudi Arabia" }, + { "SE", "Sweden" }, + { "SG", "Singapore" }, + { "SI", "Slovenia" }, + { "SK", "Slovak" }, + { "SN", "Senegal" }, + { "SO", "Somalia" }, + { "SR", "Suriname" }, + { "SV", "El Salvador" }, + { "SY", "Syria" }, + { "TH", "Thailand" }, + { "TJ", "Tajikistan" }, + { "TM", "Turkmenistan" }, + { "TN", "Tunisia" }, + { "TR", "Turkey" }, + { "TT", "Trinidad and Tobago" }, + { "TW", "Taiwan" }, + { "TZ", "Tanzania" }, + { "UA", "Ukraine" }, + { "US", "United States" }, + { "UY", "Uruguay" }, + { "VA", "Vatican" }, + { "VE", "Venezuela" }, + { "VN", "Viet Nam" }, + { "YE", "Yemen" }, + { "ZA", "South Africa" }, + { "ZW", "Zimbabwe" } + }; + +/* Given a string STRING, find the set of indices i such that TABLE[i].code is + the given STRING. It is a range [lo,hi-1]. */ +typedef struct { size_t lo; size_t hi; } range_t; +static void +search (const struct table_entry *table, size_t table_size, const char *string, + range_t *result) +{ + /* The table is sorted. Perform a binary search. */ + size_t hi = table_size; + size_t lo = 0; + while (lo < hi) + { + /* Invariant: + for i < lo, strcmp (table[i].code, string) < 0, + for i >= hi, strcmp (table[i].code, string) > 0. */ + size_t mid = (hi + lo) >> 1; /* >= lo, < hi */ + int cmp = strcmp (table[mid].code, string); + if (cmp < 0) + lo = mid + 1; + else if (cmp > 0) + hi = mid; + else + { + /* Found an i with + strcmp (language_table[i].code, string) == 0. + Find the entire interval of such i. */ + { + size_t i; + + for (i = mid; i > lo; ) + { + i--; + if (strcmp (table[i].code, string) < 0) + { + lo = i + 1; + break; + } + } + } + { + size_t i; + + for (i = mid; i < hi; i++) + { + if (strcmp (table[i].code, string) > 0) + { + hi = i; + break; + } + } + } + /* The set of i with + strcmp (language_table[i].code, string) == 0 + is the interval [lo, hi-1]. */ + break; + } + } + result->lo = lo; + result->hi = hi; +} + +/* Like setlocale, but accept also locale names in the form ll or ll_CC, + where ll is an ISO 639 language code and CC is an ISO 3166 country code. */ +static char * +setlocale_unixlike (int category, const char *locale) +{ + char *result; + char llCC_buf[64]; + char ll_buf[64]; + char CC_buf[64]; + + /* First, try setlocale with the original argument unchanged. */ + result = setlocale (category, locale); + if (result != NULL) + return result; + + /* Otherwise, assume the argument is in the form + language[_territory][.codeset][@modifier] + and try to map it using the tables. */ + if (strlen (locale) < sizeof (llCC_buf)) + { + /* Second try: Remove the codeset part. */ + { + const char *p = locale; + char *q = llCC_buf; + + /* Copy the part before the dot. */ + for (; *p != '\0' && *p != '.'; p++, q++) + *q = *p; + if (*p == '.') + /* Skip the part up to the '@', if any. */ + for (; *p != '\0' && *p != '@'; p++) + ; + /* Copy the part starting with '@', if any. */ + for (; *p != '\0'; p++, q++) + *q = *p; + *q = '\0'; + } + /* llCC_buf now contains + language[_territory][@modifier] + */ + if (strcmp (llCC_buf, locale) != 0) + { + result = setlocale (category, llCC_buf); + if (result != NULL) + return result; + } + /* Look it up in language_table. */ + { + range_t range; + size_t i; + + search (language_table, + sizeof (language_table) / sizeof (language_table[0]), + llCC_buf, + &range); + + for (i = range.lo; i < range.hi; i++) + { + /* Try the replacement in language_table[i]. */ + result = setlocale (category, language_table[i].english); + if (result != NULL) + return result; + } + } + /* Split language[_territory][@modifier] + into ll_buf = language[@modifier] + and CC_buf = territory + */ + { + const char *underscore = strchr (llCC_buf, '_'); + if (underscore != NULL) + { + const char *territory_start = underscore + 1; + const char *territory_end = strchr (territory_start, '@'); + if (territory_end == NULL) + territory_end = territory_start + strlen (territory_start); + + memcpy (ll_buf, llCC_buf, underscore - llCC_buf); + strcpy (ll_buf + (underscore - llCC_buf), territory_end); + + memcpy (CC_buf, territory_start, territory_end - territory_start); + CC_buf[territory_end - territory_start] = '\0'; + + { + /* Look up ll_buf in language_table + and CC_buf in country_table. */ + range_t language_range; + + search (language_table, + sizeof (language_table) / sizeof (language_table[0]), + ll_buf, + &language_range); + if (language_range.lo < language_range.hi) + { + range_t country_range; + + search (country_table, + sizeof (country_table) / sizeof (country_table[0]), + CC_buf, + &country_range); + if (country_range.lo < country_range.hi) + { + size_t i; + size_t j; + + for (i = language_range.lo; i < language_range.hi; i++) + for (j = country_range.lo; j < country_range.hi; j++) + { + /* Concatenate the replacements. */ + const char *part1 = language_table[i].english; + size_t part1_len = strlen (part1); + const char *part2 = country_table[j].english; + size_t part2_len = strlen (part2) + 1; + char buf[64+64]; + + if (!(part1_len + 1 + part2_len <= sizeof (buf))) + abort (); + memcpy (buf, part1, part1_len); + buf[part1_len] = '_'; + memcpy (buf + part1_len + 1, part2, part2_len); + + /* Try the concatenated replacements. */ + result = setlocale (category, buf); + if (result != NULL) + return result; + } + } + + /* Try omitting the country entirely. This may set a locale + corresponding to the wrong country, but is better than + failing entirely. */ + { + size_t i; + + for (i = language_range.lo; i < language_range.hi; i++) + { + /* Try only the language replacement. */ + result = + setlocale (category, language_table[i].english); + if (result != NULL) + return result; + } + } + } + } + } + } + } + + /* Failed. */ + return NULL; +} + +# else +# define setlocale_unixlike setlocale +# endif + +# if LC_MESSAGES == 1729 + +/* The system does not store an LC_MESSAGES locale category. Do it here. */ +static char lc_messages_name[64] = "C"; + +/* Like setlocale, but support also LC_MESSAGES. */ +static char * +setlocale_single (int category, const char *locale) +{ + if (category == LC_MESSAGES) + { + if (locale != NULL) + { + lc_messages_name[sizeof (lc_messages_name) - 1] = '\0'; + strncpy (lc_messages_name, locale, sizeof (lc_messages_name) - 1); + } + return lc_messages_name; + } + else + return setlocale_unixlike (category, locale); +} + +# else +# define setlocale_single setlocale_unixlike +# endif + +DLL_EXPORTED +char * +libintl_setlocale (int category, const char *locale) +{ + if (locale != NULL && locale[0] == '\0') + { + /* A request to the set the current locale to the default locale. */ + if (category == LC_ALL) + { + /* Set LC_CTYPE first. Then the other categories. */ + static int const categories[] = + { + LC_NUMERIC, + LC_TIME, + LC_COLLATE, + LC_MONETARY, + LC_MESSAGES + }; + char *saved_locale; + const char *base_name; + unsigned int i; + + /* Back up the old locale, in case one of the steps fails. */ + saved_locale = setlocale (LC_ALL, NULL); + if (saved_locale == NULL) + return NULL; + saved_locale = strdup (saved_locale); + if (saved_locale == NULL) + return NULL; + + /* Set LC_CTYPE category. Set all other categories (except possibly + LC_MESSAGES) to the same value in the same call; this is likely to + save calls. */ + base_name = + gl_locale_name_environ (LC_CTYPE, category_to_name (LC_CTYPE)); + if (base_name == NULL) + base_name = gl_locale_name_default (); + + if (setlocale_unixlike (LC_ALL, base_name) == NULL) + goto fail; + + for (i = 0; i < sizeof (categories) / sizeof (categories[0]); i++) + { + int cat = categories[i]; + const char *name; + + name = gl_locale_name_environ (cat, category_to_name (cat)); + if (name == NULL) + name = gl_locale_name_default (); + + /* If name is the same as base_name, it has already been set + through the setlocale call before the loop. */ + if (strcmp (name, base_name) != 0 +# if LC_MESSAGES == 1729 + || cat == LC_MESSAGES +# endif + ) + if (setlocale_single (cat, name) == NULL) + goto fail; + } + + /* All steps were successful. */ + free (saved_locale); + return setlocale (LC_ALL, NULL); + + fail: + if (saved_locale[0] != '\0') /* don't risk an endless recursion */ + setlocale (LC_ALL, saved_locale); + free (saved_locale); + return NULL; + } + else + { + const char *name = + gl_locale_name_environ (category, category_to_name (category)); + if (name == NULL) + name = gl_locale_name_default (); + + return setlocale_single (category, name); + } + } + else + return setlocale_single (category, locale); +} + +# if HAVE_NEWLOCALE + +DLL_EXPORTED +locale_t +libintl_newlocale (int category_mask, const char *locale, locale_t base) +{ + if (category_mask != 0 && locale != NULL && locale[0] == '\0') + { + /* A request to construct a locale_t object that refers to the default + locale. */ + + /* Set LC_CTYPE first. Then the other categories. */ + static struct { int cat; int mask; } const categories[] = + { + { LC_CTYPE, LC_CTYPE_MASK }, + { LC_NUMERIC, LC_NUMERIC_MASK }, + { LC_TIME, LC_TIME_MASK }, + { LC_COLLATE, LC_COLLATE_MASK }, + { LC_MONETARY, LC_MONETARY_MASK }, + { LC_MESSAGES, LC_MESSAGES_MASK } + }; + + locale_t orig_base = base; + + if ((LC_ALL_MASK & ~category_mask) == 0) + { + const char *base_name; + unsigned int i; + + /* Set LC_CTYPE category. Set all other categories (except possibly + LC_MESSAGES) to the same value in the same call; this is likely to + save calls. */ + base_name = + gl_locale_name_environ (LC_CTYPE, category_to_name (LC_CTYPE)); + if (base_name == NULL) + base_name = gl_locale_name_default (); + + base = newlocale (LC_ALL_MASK, base_name, base); + if (base == NULL) + return NULL; + + for (i = 1; i < sizeof (categories) / sizeof (categories[0]); i++) + { + int category = categories[i].cat; + int category_mask = categories[i].mask; + const char *name; + + name = + gl_locale_name_environ (category, category_to_name (category)); + if (name == NULL) + name = gl_locale_name_default (); + + /* If name is the same as base_name, it has already been set + through the setlocale call before the loop. */ + if (strcmp (name, base_name) != 0) + { + locale_t copy = newlocale (category_mask, name, base); + if (copy == NULL) + goto fail; + /* No need to call freelocale (base) if copy != base; the + newlocale function already takes care of doing it. */ + base = copy; + } + } + } + else + { + unsigned int i; + + for (i = 0; i < sizeof (categories) / sizeof (categories[0]); i++) + { + int cat_mask = categories[i].mask; + + if ((category_mask & cat_mask) != 0) + { + int cat = categories[i].cat; + const char *name; + locale_t copy; + + name = gl_locale_name_environ (cat, category_to_name (cat)); + if (name == NULL) + name = gl_locale_name_default (); + + copy = newlocale (cat_mask, name, base); + if (copy == NULL) + goto fail; + /* No need to call freelocale (base) if copy != base; the + newlocale function already takes care of doing it. */ + base = copy; + } + } + } + + /* All steps were successful. */ + return base; + + fail: + if (base != NULL && orig_base == NULL) + { + int saved_errno = errno; + freelocale (base); + errno = saved_errno; + } + return NULL; + } + else + return newlocale (category_mask, locale, base); +} + +# endif + +#endif diff --git a/gettext-runtime/m4/ChangeLog b/gettext-runtime/m4/ChangeLog index 21ca5af..7631ec3 100644 --- a/gettext-runtime/m4/ChangeLog +++ b/gettext-runtime/m4/ChangeLog @@ -1,3 +1,9 @@ +2009-12-21 Bruno Haible <bruno@clisp.org> + + Define override of setlocale and newlocale functions. + * intl.m4 (AM_INTL_SUBDIR): Check also for newlocale. Set + HAVE_NEWLOCALE. + 2009-12-12 Bruno Haible <bruno@clisp.org> * fcntl_h.m4: Untabify. diff --git a/gettext-runtime/m4/intl.m4 b/gettext-runtime/m4/intl.m4 index a0325c3..3abacd6 100644 --- a/gettext-runtime/m4/intl.m4 +++ b/gettext-runtime/m4/intl.m4 @@ -1,4 +1,4 @@ -# intl.m4 serial 14 (gettext-0.18) +# intl.m4 serial 15 (gettext-0.18) dnl Copyright (C) 1995-2009 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -56,8 +56,8 @@ AC_DEFUN([AM_INTL_SUBDIR], [Define as the type of the result of subtracting two pointers, if the system doesn't define it.]) ]) AC_CHECK_HEADERS([stddef.h stdlib.h string.h]) - AC_CHECK_FUNCS([asprintf fwprintf putenv setenv setlocale snprintf \ - strnlen wcslen wcsnlen mbrtowc wcrtomb]) + AC_CHECK_FUNCS([asprintf fwprintf newlocale putenv setenv setlocale \ + snprintf strnlen wcslen wcsnlen mbrtowc wcrtomb]) dnl Use the _snprintf function only if it is declared (because on NetBSD it dnl is defined as a weak alias of snprintf; we prefer to use the latter). @@ -88,6 +88,12 @@ AC_DEFUN([AM_INTL_SUBDIR], HAVE_SNPRINTF=0 fi AC_SUBST([HAVE_SNPRINTF]) + if test "$ac_cv_func_newlocale" = yes; then + HAVE_NEWLOCALE=1 + else + HAVE_NEWLOCALE=0 + fi + AC_SUBST([HAVE_NEWLOCALE]) if test "$ac_cv_func_wprintf" = yes; then HAVE_WPRINTF=1 else diff --git a/gettext-tools/tests/ChangeLog b/gettext-tools/tests/ChangeLog index 50edabf..f646996 100644 --- a/gettext-tools/tests/ChangeLog +++ b/gettext-tools/tests/ChangeLog @@ -1,3 +1,9 @@ +2009-12-21 Bruno Haible <bruno@clisp.org> + + * format-c-3-prg.c: Don't use setlocale override. + * format-c-4-prg.c: Likewise. + * plural-1-prg.c: Likewise. + 2009-12-13 Bruno Haible <bruno@clisp.org> Avoid a test failure on MacOS X 10.5. diff --git a/gettext-tools/tests/format-c-3-prg.c b/gettext-tools/tests/format-c-3-prg.c index ea8997e..d448311 100644 --- a/gettext-tools/tests/format-c-3-prg.c +++ b/gettext-tools/tests/format-c-3-prg.c @@ -1,5 +1,5 @@ /* Test program, used by the format-c-3 test. - Copyright (C) 2002 Free Software Foundation, Inc. + Copyright (C) 2002, 2009 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -31,6 +31,11 @@ #undef _LIBINTL_H #include "libgnuintl.h" +/* Disable the override of setlocale that libgnuintl.h activates on MacOS X + and Windows. This test relies on the fake setlocale function in + setlocale.c. */ +#undef setlocale + #define _(string) gettext (string) /* Fallback definition. */ diff --git a/gettext-tools/tests/format-c-4-prg.c b/gettext-tools/tests/format-c-4-prg.c index 007f853..45a222b 100644 --- a/gettext-tools/tests/format-c-4-prg.c +++ b/gettext-tools/tests/format-c-4-prg.c @@ -1,5 +1,5 @@ /* Test program, used by the format-c-4 test. - Copyright (C) 2002 Free Software Foundation, Inc. + Copyright (C) 2002, 2009 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -31,6 +31,11 @@ #undef _LIBINTL_H #include "libgnuintl.h" +/* Disable the override of setlocale that libgnuintl.h activates on MacOS X + and Windows. This test relies on the fake setlocale function in + setlocale.c. */ +#undef setlocale + #define _(string) gettext (string) /* Fallback definition. */ diff --git a/gettext-tools/tests/plural-1-prg.c b/gettext-tools/tests/plural-1-prg.c index 2bbd315..88e2467 100644 --- a/gettext-tools/tests/plural-1-prg.c +++ b/gettext-tools/tests/plural-1-prg.c @@ -1,5 +1,5 @@ /* Test program, used by the plural-1 test. - Copyright (C) 2001-2002 Free Software Foundation, Inc. + Copyright (C) 2001-2002, 2009 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -27,6 +27,11 @@ #undef _LIBINTL_H #include "libgnuintl.h" +/* Disable the override of setlocale that libgnuintl.h activates on MacOS X + and Windows. This test relies on the fake setlocale function in + setlocale.c. */ +#undef setlocale + int main (int argc, char *argv[]) { |