1 /*-----------------------------------------------------------------------
3 * PostgreSQL locale utilities
5 * $Header: /cvsroot/pgsql/src/backend/utils/adt/pg_locale.c,v 1.16 2002/04/03 05:39:31 petere Exp $
7 * Portions Copyright (c) 2002, PostgreSQL Global Development Group
9 *-----------------------------------------------------------------------
13 #include "utils/pg_locale.h"
17 /* GUC storage area */
19 char * locale_messages;
20 char * locale_monetary;
21 char * locale_numeric;
26 bool locale_messages_check(const char *proposed)
29 return chklocale(LC_MESSAGES, proposed);
31 /* We return true here so LC_MESSAGES can be set in the
32 configuration file on every system. */
37 bool locale_monetary_check(const char *proposed)
39 return chklocale(LC_MONETARY, proposed);
42 bool locale_numeric_check(const char *proposed)
44 return chklocale(LC_NUMERIC, proposed);
47 bool locale_time_check(const char *proposed)
49 return chklocale(LC_TIME, proposed);
52 /* GUC assign hooks */
54 void locale_messages_assign(const char *value)
57 setlocale(LC_MESSAGES, value);
61 void locale_monetary_assign(const char *value)
63 setlocale(LC_MONETARY, value);
66 void locale_numeric_assign(const char *value)
68 setlocale(LC_NUMERIC, value);
71 void locale_time_assign(const char *value)
73 setlocale(LC_TIME, value);
78 * Returns true if the proposed string represents a valid locale of
79 * the given category. This is probably pretty slow, but it's not
80 * called in critical places.
83 chklocale(int category, const char *proposed)
87 save = setlocale(category, NULL);
91 if (!setlocale(category, proposed))
94 setlocale(category, save);
100 * We'd like to cache whether LC_COLLATE is C (or POSIX), so we can
101 * optimize a few code paths in various places.
104 lc_collate_is_c(void)
106 /* Cache result so we only have to compute it once */
107 static int result = -1;
111 return (bool) result;
112 localeptr = setlocale(LC_COLLATE, NULL);
114 elog(PANIC, "Invalid LC_COLLATE setting");
116 if (strcmp(localeptr, "C") == 0)
118 else if (strcmp(localeptr, "POSIX") == 0)
122 return (bool) result;
128 * Return the POSIX lconv struct (contains number/money formatting
129 * information) with locale information for all categories.
132 PGLC_localeconv(void)
134 struct lconv *extlconv;
135 static bool CurrentLocaleConvValid = false;
136 static struct lconv CurrentLocaleConv;
138 /* Did we do it already? */
139 if (CurrentLocaleConvValid)
140 return &CurrentLocaleConv;
142 /* Get formatting information for the external environment */
143 extlconv = localeconv();
146 * Must copy all values since restoring internal settings may
149 CurrentLocaleConv = *extlconv;
150 CurrentLocaleConv.currency_symbol = strdup(extlconv->currency_symbol);
151 CurrentLocaleConv.decimal_point = strdup(extlconv->decimal_point);
152 CurrentLocaleConv.grouping = strdup(extlconv->grouping);
153 CurrentLocaleConv.thousands_sep = strdup(extlconv->thousands_sep);
154 CurrentLocaleConv.int_curr_symbol = strdup(extlconv->int_curr_symbol);
155 CurrentLocaleConv.mon_decimal_point = strdup(extlconv->mon_decimal_point);
156 CurrentLocaleConv.mon_grouping = strdup(extlconv->mon_grouping);
157 CurrentLocaleConv.mon_thousands_sep = strdup(extlconv->mon_thousands_sep);
158 CurrentLocaleConv.negative_sign = strdup(extlconv->negative_sign);
159 CurrentLocaleConv.positive_sign = strdup(extlconv->positive_sign);
161 CurrentLocaleConvValid = true;
162 return &CurrentLocaleConv;