1 /* -----------------------------------------------------------------------
4 * The PostgreSQL locale utils.
7 * $Header: /cvsroot/pgsql/src/backend/utils/adt/pg_locale.c,v 1.14 2002/03/02 21:39:32 momjian Exp $
9 * Portions Copyright (c) 1999-2000, PostgreSQL Global Development Group
13 * -----------------------------------------------------------------------
22 #include "utils/pg_locale.h"
24 /* #define DEBUG_LOCALE_UTILS */
27 static bool CurrentLocaleConvValid = false;
28 static struct lconv CurrentLocaleConv;
31 static void PGLC_setlocale(PG_LocaleCategories *lc);
34 * Frees memory used in PG_LocaleCategories -- this memory is
35 * allocated in PGLC_current().
39 PGLC_free_categories(PG_LocaleCategories *lc)
44 pfree(lc->lc_numeric);
48 pfree(lc->lc_collate);
50 pfree(lc->lc_monetary);
53 pfree(lc->lc_messages);
58 * Return in PG_LocaleCategories the current locale settings.
60 * NB: strings are allocated in the current memory context!
64 PGLC_current(PG_LocaleCategories *lc)
66 lc->lang = getenv("LANG");
68 lc->lc_ctype = pstrdup(setlocale(LC_CTYPE, NULL));
69 lc->lc_numeric = pstrdup(setlocale(LC_NUMERIC, NULL));
70 lc->lc_time = pstrdup(setlocale(LC_TIME, NULL));
71 lc->lc_collate = pstrdup(setlocale(LC_COLLATE, NULL));
72 lc->lc_monetary = pstrdup(setlocale(LC_MONETARY, NULL));
74 lc->lc_messages = pstrdup(setlocale(LC_MESSAGES, NULL));
79 #ifdef DEBUG_LOCALE_UTILS
82 * Print a PG_LocaleCategories struct as DEBUG
86 PGLC_debug_lc(PG_LocaleCategories *lc)
89 elog(LOG, "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",
98 elog(LOG, "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",
110 * Set locales via a PG_LocaleCategories struct
112 * NB: it would be very dangerous to set the locale values to any random
113 * choice of locale, since that could cause indexes to become corrupt, etc.
114 * Therefore this routine is NOT exported from this module. It should be
115 * used only to restore previous locale settings during PGLC_localeconv.
119 PGLC_setlocale(PG_LocaleCategories *lc)
121 if (!setlocale(LC_COLLATE, lc->lc_collate))
122 elog(NOTICE, "pg_setlocale(): 'LC_COLLATE=%s' cannot be honored.",
125 if (!setlocale(LC_CTYPE, lc->lc_ctype))
126 elog(NOTICE, "pg_setlocale(): 'LC_CTYPE=%s' cannot be honored.",
129 if (!setlocale(LC_NUMERIC, lc->lc_numeric))
130 elog(NOTICE, "pg_setlocale(): 'LC_NUMERIC=%s' cannot be honored.",
133 if (!setlocale(LC_TIME, lc->lc_time))
134 elog(NOTICE, "pg_setlocale(): 'LC_TIME=%s' cannot be honored.",
137 if (!setlocale(LC_MONETARY, lc->lc_monetary))
138 elog(NOTICE, "pg_setlocale(): 'LC_MONETARY=%s' cannot be honored.",
142 if (!setlocale(LC_MESSAGES, lc->lc_messages))
143 elog(NOTICE, "pg_setlocale(): 'LC_MESSAGES=%s' cannot be honored.",
149 * Return the POSIX lconv struct (contains number/money formatting information)
150 * with locale information for all categories. Note that returned lconv
151 * does not depend on currently active category settings, but on external
152 * environment variables for locale.
156 PGLC_localeconv(void)
158 PG_LocaleCategories lc;
159 struct lconv *extlconv;
161 /* Did we do it already? */
162 if (CurrentLocaleConvValid)
163 return &CurrentLocaleConv;
165 /* Save current locale setting to lc */
168 /* Set all locale categories based on postmaster's environment vars */
169 setlocale(LC_ALL, "");
171 /* Get formatting information for the external environment */
172 extlconv = localeconv();
175 * Must copy all values since restoring internal settings may
178 CurrentLocaleConv = *extlconv;
179 CurrentLocaleConv.currency_symbol = strdup(extlconv->currency_symbol);
180 CurrentLocaleConv.decimal_point = strdup(extlconv->decimal_point);
181 CurrentLocaleConv.grouping = strdup(extlconv->grouping);
182 CurrentLocaleConv.thousands_sep = strdup(extlconv->thousands_sep);
183 CurrentLocaleConv.int_curr_symbol = strdup(extlconv->int_curr_symbol);
184 CurrentLocaleConv.mon_decimal_point = strdup(extlconv->mon_decimal_point);
185 CurrentLocaleConv.mon_grouping = strdup(extlconv->mon_grouping);
186 CurrentLocaleConv.mon_thousands_sep = strdup(extlconv->mon_thousands_sep);
187 CurrentLocaleConv.negative_sign = strdup(extlconv->negative_sign);
188 CurrentLocaleConv.positive_sign = strdup(extlconv->positive_sign);
190 /* Restore Postgres' internal locale settings */
193 /* Deallocate category settings allocated in PGLC_current() */
194 PGLC_free_categories(&lc);
196 CurrentLocaleConvValid = true;
197 return &CurrentLocaleConv;
200 #endif /* USE_LOCALE */