2000-02-08 16:57:01 +01:00
|
|
|
/* -----------------------------------------------------------------------
|
2000-01-07 18:22:47 +01:00
|
|
|
* pg_locale.c
|
|
|
|
*
|
2000-11-25 23:43:08 +01:00
|
|
|
* The PostgreSQL locale utils.
|
2000-01-07 18:22:47 +01:00
|
|
|
*
|
|
|
|
*
|
2001-03-22 05:01:46 +01:00
|
|
|
* $Header: /cvsroot/pgsql/src/backend/utils/adt/pg_locale.c,v 1.9 2001/03/22 03:59:52 momjian Exp $
|
2000-02-08 16:57:01 +01:00
|
|
|
*
|
2001-01-24 20:43:33 +01:00
|
|
|
* Portions Copyright (c) 1999-2000, PostgreSQL Global Development Group
|
2000-02-08 16:57:01 +01:00
|
|
|
*
|
|
|
|
* Karel Zak - Zakkr
|
|
|
|
*
|
|
|
|
* -----------------------------------------------------------------------
|
2000-01-07 18:22:47 +01:00
|
|
|
*/
|
2000-04-12 19:17:23 +02:00
|
|
|
|
2000-01-07 18:22:47 +01:00
|
|
|
#include "postgres.h"
|
2000-04-12 19:17:23 +02:00
|
|
|
|
2000-01-07 18:22:47 +01:00
|
|
|
#ifdef USE_LOCALE
|
|
|
|
|
|
|
|
#include <locale.h>
|
|
|
|
#include "utils/pg_locale.h"
|
|
|
|
|
|
|
|
/* #define DEBUG_LOCALE_UTILS */
|
|
|
|
|
|
|
|
|
2000-08-29 06:41:48 +02:00
|
|
|
static struct lconv *CurrentLocaleConv = NULL;
|
|
|
|
|
2000-11-25 23:43:08 +01:00
|
|
|
static void PGLC_setlocale(PG_LocaleCategories * lc);
|
|
|
|
|
2000-01-07 18:22:47 +01:00
|
|
|
/*------
|
2000-11-25 23:43:08 +01:00
|
|
|
* Return in PG_LocaleCategories the current locale settings
|
2000-01-07 18:22:47 +01:00
|
|
|
*------
|
2000-04-12 19:17:23 +02:00
|
|
|
*/
|
2000-11-25 23:43:08 +01:00
|
|
|
void
|
2000-04-12 19:17:23 +02:00
|
|
|
PGLC_current(PG_LocaleCategories * lc)
|
2000-01-07 18:22:47 +01:00
|
|
|
{
|
2000-04-12 19:17:23 +02:00
|
|
|
lc->lang = getenv("LANG");
|
|
|
|
|
|
|
|
lc->lc_ctype = setlocale(LC_CTYPE, NULL);
|
|
|
|
lc->lc_numeric = setlocale(LC_NUMERIC, NULL);
|
|
|
|
lc->lc_time = setlocale(LC_TIME, NULL);
|
|
|
|
lc->lc_collate = setlocale(LC_COLLATE, NULL);
|
|
|
|
lc->lc_monetary = setlocale(LC_MONETARY, NULL);
|
2000-06-29 03:19:36 +02:00
|
|
|
#ifdef LC_MESSAGES
|
2000-04-12 19:17:23 +02:00
|
|
|
lc->lc_messages = setlocale(LC_MESSAGES, NULL);
|
2000-06-29 03:19:36 +02:00
|
|
|
#endif
|
2000-04-12 19:17:23 +02:00
|
|
|
}
|
2000-01-07 18:22:47 +01:00
|
|
|
|
|
|
|
|
2000-04-12 19:17:23 +02:00
|
|
|
#ifdef DEBUG_LOCALE_UTILS
|
2000-01-07 18:22:47 +01:00
|
|
|
|
|
|
|
/*------
|
|
|
|
* Print a PG_LocaleCategories struct as DEBUG
|
|
|
|
*------
|
|
|
|
*/
|
2000-11-25 23:43:08 +01:00
|
|
|
static void
|
2000-04-12 19:17:23 +02:00
|
|
|
PGLC_debug_lc(PG_LocaleCategories * lc)
|
2000-01-07 18:22:47 +01:00
|
|
|
{
|
2000-06-29 03:19:36 +02:00
|
|
|
#ifdef LC_MESSAGES
|
2000-01-07 18:22:47 +01:00
|
|
|
elog(DEBUG, "CURRENT LOCALE ENVIRONMENT:\n\nLANG: \t%s\nLC_CTYPE:\t%s\nLC_NUMERIC:\t%s\nLC_TIME:\t%s\nLC_COLLATE:\t%s\nLC_MONETARY:\t%s\nLC_MESSAGES:\t%s\n",
|
2000-06-29 03:19:36 +02:00
|
|
|
#else
|
|
|
|
elog(DEBUG, "CURRENT LOCALE ENVIRONMENT:\n\nLANG: \t%s\nLC_CTYPE:\t%s\nLC_NUMERIC:\t%s\nLC_TIME:\t%s\nLC_COLLATE:\t%s\nLC_MONETARY:\t%s\n",
|
|
|
|
#endif
|
2000-04-12 19:17:23 +02:00
|
|
|
lc->lang,
|
|
|
|
lc->lc_ctype,
|
|
|
|
lc->lc_numeric,
|
|
|
|
lc->lc_time,
|
|
|
|
lc->lc_collate,
|
2000-06-29 03:19:36 +02:00
|
|
|
lc->lc_monetary
|
|
|
|
#ifdef LC_MESSAGES
|
2001-03-22 05:01:46 +01:00
|
|
|
,lc->lc_messages
|
2000-06-29 03:19:36 +02:00
|
|
|
#endif
|
2000-01-07 18:22:47 +01:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/*------
|
2000-04-12 19:17:23 +02:00
|
|
|
* Set locales via a PG_LocaleCategories struct
|
2000-11-25 23:43:08 +01:00
|
|
|
*
|
|
|
|
* NB: it would be very dangerous to set the locale values to any random
|
|
|
|
* choice of locale, since that could cause indexes to become corrupt, etc.
|
|
|
|
* Therefore this routine is NOT exported from this module. It should be
|
|
|
|
* used only to restore previous locale settings during PGLC_localeconv.
|
2000-01-07 18:22:47 +01:00
|
|
|
*------
|
|
|
|
*/
|
2000-11-25 23:43:08 +01:00
|
|
|
static void
|
2000-04-12 19:17:23 +02:00
|
|
|
PGLC_setlocale(PG_LocaleCategories * lc)
|
2000-01-07 18:22:47 +01:00
|
|
|
{
|
2000-11-25 23:43:08 +01:00
|
|
|
if (!setlocale(LC_COLLATE, lc->lc_collate))
|
|
|
|
elog(NOTICE, "pg_setlocale(): 'LC_COLLATE=%s' cannot be honored.",
|
|
|
|
lc->lc_collate);
|
|
|
|
|
2000-04-12 19:17:23 +02:00
|
|
|
if (!setlocale(LC_CTYPE, lc->lc_ctype))
|
2000-11-25 23:43:08 +01:00
|
|
|
elog(NOTICE, "pg_setlocale(): 'LC_CTYPE=%s' cannot be honored.",
|
|
|
|
lc->lc_ctype);
|
2000-04-12 19:17:23 +02:00
|
|
|
|
|
|
|
if (!setlocale(LC_NUMERIC, lc->lc_numeric))
|
2000-11-25 23:43:08 +01:00
|
|
|
elog(NOTICE, "pg_setlocale(): 'LC_NUMERIC=%s' cannot be honored.",
|
|
|
|
lc->lc_numeric);
|
2000-04-12 19:17:23 +02:00
|
|
|
|
|
|
|
if (!setlocale(LC_TIME, lc->lc_time))
|
2000-11-25 23:43:08 +01:00
|
|
|
elog(NOTICE, "pg_setlocale(): 'LC_TIME=%s' cannot be honored.",
|
|
|
|
lc->lc_time);
|
2000-01-07 18:22:47 +01:00
|
|
|
|
2000-04-12 19:17:23 +02:00
|
|
|
if (!setlocale(LC_MONETARY, lc->lc_monetary))
|
2000-11-25 23:43:08 +01:00
|
|
|
elog(NOTICE, "pg_setlocale(): 'LC_MONETARY=%s' cannot be honored.",
|
|
|
|
lc->lc_monetary);
|
|
|
|
|
2000-06-29 03:19:36 +02:00
|
|
|
#ifdef LC_MESSAGES
|
2000-04-12 19:17:23 +02:00
|
|
|
if (!setlocale(LC_MESSAGES, lc->lc_messages))
|
2000-11-25 23:43:08 +01:00
|
|
|
elog(NOTICE, "pg_setlocale(): 'LC_MESSAGE=%s' cannot be honored.",
|
|
|
|
lc->lc_messages);
|
2000-06-29 03:19:36 +02:00
|
|
|
#endif
|
2000-01-07 18:22:47 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*------
|
|
|
|
* Return the POSIX lconv struct (contains number/money formatting information)
|
2001-03-22 05:01:46 +01:00
|
|
|
* with locale information for all categories. Note that returned lconv
|
2000-11-25 23:43:08 +01:00
|
|
|
* does not depend on currently active category settings, but on external
|
|
|
|
* environment variables for locale.
|
|
|
|
*
|
|
|
|
* XXX we assume that restoring old category settings via setlocale() will
|
|
|
|
* not immediately corrupt the static data returned by localeconv().
|
|
|
|
* How portable is this?
|
2000-01-07 18:22:47 +01:00
|
|
|
*
|
2000-11-25 23:43:08 +01:00
|
|
|
* XXX in any case, there certainly must not be any other calls to
|
|
|
|
* localeconv() anywhere in the backend, else the values reported here
|
|
|
|
* will be overwritten with the Postgres-internal locale settings.
|
2000-01-07 18:22:47 +01:00
|
|
|
*------
|
|
|
|
*/
|
|
|
|
struct lconv *
|
2000-03-18 19:57:16 +01:00
|
|
|
PGLC_localeconv(void)
|
2000-01-07 18:22:47 +01:00
|
|
|
{
|
2000-04-12 19:17:23 +02:00
|
|
|
PG_LocaleCategories lc;
|
2000-11-25 23:43:08 +01:00
|
|
|
|
|
|
|
/* Did we do it already? */
|
2000-08-29 06:41:48 +02:00
|
|
|
if (CurrentLocaleConv)
|
|
|
|
return CurrentLocaleConv;
|
2000-01-07 18:22:47 +01:00
|
|
|
|
|
|
|
/* Save current locale setting to lc */
|
2000-04-12 19:17:23 +02:00
|
|
|
PGLC_current(&lc);
|
|
|
|
|
2000-11-25 23:43:08 +01:00
|
|
|
/* Set all locale categories based on postmaster's environment vars */
|
2000-01-07 18:22:47 +01:00
|
|
|
setlocale(LC_ALL, "");
|
2000-04-12 19:17:23 +02:00
|
|
|
|
2000-11-25 23:43:08 +01:00
|
|
|
/* Get formatting information for the external environment */
|
2000-08-29 06:41:48 +02:00
|
|
|
CurrentLocaleConv = localeconv();
|
2000-04-12 19:17:23 +02:00
|
|
|
|
2000-11-25 23:43:08 +01:00
|
|
|
/* Restore Postgres' internal locale settings */
|
2000-01-07 18:22:47 +01:00
|
|
|
PGLC_setlocale(&lc);
|
|
|
|
|
2000-08-29 06:41:48 +02:00
|
|
|
return CurrentLocaleConv;
|
2000-01-07 18:22:47 +01:00
|
|
|
}
|
|
|
|
|
2000-04-12 19:17:23 +02:00
|
|
|
#endif /* USE_LOCALE */
|