1-
21/* -----------------------------------------------------------------------
32 * pg_locale.c
43 *
5- * $Header: /cvsroot/pgsql/src/backend/utils/adt/pg_locale.c,v 1.6 2000/08/29 04:41:47 momjian Exp $
4+ * The PostgreSQL locale utils.
65 *
76 *
8- * Portions Copyright (c) 1999- 2000, PostgreSQL, Inc
7+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/pg_locale.c,v 1.7 2000/11/25 22:43:08 tgl Exp $
98 *
10- * The PostgreSQL locale utils.
9+ * Portions Copyright (c) 1999-2000, PostgreSQL, Inc
1110 *
1211 * Karel Zak - Zakkr
1312 *
1413 * -----------------------------------------------------------------------
1514 */
1615
17- #include <stdio.h>
18-
1916#include "postgres.h"
2017
2118#ifdef USE_LOCALE
2825
2926static struct lconv * CurrentLocaleConv = NULL ;
3027
28+ static void PGLC_setlocale (PG_LocaleCategories * lc );
29+
3130/*------
32- * Return in PG_LocaleCategories current locale setting
31+ * Return in PG_LocaleCategories the current locale settings
3332 *------
3433 */
35- PG_LocaleCategories *
34+ void
3635PGLC_current (PG_LocaleCategories * lc )
3736{
3837 lc -> lang = getenv ("LANG" );
@@ -45,7 +44,6 @@ PGLC_current(PG_LocaleCategories * lc)
4544#ifdef LC_MESSAGES
4645 lc -> lc_messages = setlocale (LC_MESSAGES , NULL );
4746#endif
48- return lc ;
4947}
5048
5149
@@ -55,7 +53,7 @@ PGLC_current(PG_LocaleCategories * lc)
5553 * Print a PG_LocaleCategories struct as DEBUG
5654 *------
5755 */
58- PG_LocaleCategories *
56+ static void
5957PGLC_debug_lc (PG_LocaleCategories * lc )
6058{
6159#ifdef LC_MESSAGES
@@ -73,72 +71,86 @@ PGLC_debug_lc(PG_LocaleCategories * lc)
7371 , lc -> lc_messages
7472#endif
7573 );
76-
77- return lc ;
7874}
7975
8076#endif
8177
8278/*------
8379 * Set locales via a PG_LocaleCategories struct
80+ *
81+ * NB: it would be very dangerous to set the locale values to any random
82+ * choice of locale, since that could cause indexes to become corrupt, etc.
83+ * Therefore this routine is NOT exported from this module. It should be
84+ * used only to restore previous locale settings during PGLC_localeconv.
8485 *------
8586 */
86- PG_LocaleCategories *
87+ static void
8788PGLC_setlocale (PG_LocaleCategories * lc )
8889{
90+ if (!setlocale (LC_COLLATE , lc -> lc_collate ))
91+ elog (NOTICE , "pg_setlocale(): 'LC_COLLATE=%s' cannot be honored." ,
92+ lc -> lc_collate );
93+
8994 if (!setlocale (LC_CTYPE , lc -> lc_ctype ))
90- elog (NOTICE , "pg_setlocale(): 'LC_CTYPE=%s' cannot be honored." , lc -> lc_ctype );
95+ elog (NOTICE , "pg_setlocale(): 'LC_CTYPE=%s' cannot be honored." ,
96+ lc -> lc_ctype );
9197
9298 if (!setlocale (LC_NUMERIC , lc -> lc_numeric ))
93- elog (NOTICE , "pg_setlocale(): 'LC_NUMERIC=%s' cannot be honored." , lc -> lc_numeric );
99+ elog (NOTICE , "pg_setlocale(): 'LC_NUMERIC=%s' cannot be honored." ,
100+ lc -> lc_numeric );
94101
95102 if (!setlocale (LC_TIME , lc -> lc_time ))
96- elog (NOTICE , "pg_setlocale(): 'LC_TIME=%s' cannot be honored." , lc -> lc_time );
97-
98- if (!setlocale (LC_COLLATE , lc -> lc_collate ))
99- elog (NOTICE , "pg_setlocale(): 'LC_COLLATE=%s' cannot be honored." , lc -> lc_collate );
103+ elog (NOTICE , "pg_setlocale(): 'LC_TIME=%s' cannot be honored." ,
104+ lc -> lc_time );
100105
101106 if (!setlocale (LC_MONETARY , lc -> lc_monetary ))
102- elog (NOTICE , "pg_setlocale(): 'LC_MONETARY=%s' cannot be honored." , lc -> lc_monetary );
107+ elog (NOTICE , "pg_setlocale(): 'LC_MONETARY=%s' cannot be honored." ,
108+ lc -> lc_monetary );
109+
103110#ifdef LC_MESSAGES
104111 if (!setlocale (LC_MESSAGES , lc -> lc_messages ))
105- elog (NOTICE , "pg_setlocale(): 'LC_MESSAGE=%s' cannot be honored." , lc -> lc_messages );
112+ elog (NOTICE , "pg_setlocale(): 'LC_MESSAGE=%s' cannot be honored." ,
113+ lc -> lc_messages );
106114#endif
107- return lc ;
108115}
109116
110117/*------
111118 * Return the POSIX lconv struct (contains number/money formatting information)
112- * with locale information for *all* categories.
113- * => Returned lconv is *independent* on current locale catogories setting - in
114- * contrast to standard localeconv().
119+ * with locale information for all categories. Note that returned lconv
120+ * does not depend on currently active category settings, but on external
121+ * environment variables for locale.
122+ *
123+ * XXX we assume that restoring old category settings via setlocale() will
124+ * not immediately corrupt the static data returned by localeconv().
125+ * How portable is this?
115126 *
116- * ! libc prepare memory space for lconv itself and all returned strings in
117- * lconv are *static strings*.
127+ * XXX in any case, there certainly must not be any other calls to
128+ * localeconv() anywhere in the backend, else the values reported here
129+ * will be overwritten with the Postgres-internal locale settings.
118130 *------
119131 */
120132struct lconv *
121133PGLC_localeconv (void )
122134{
123135 PG_LocaleCategories lc ;
124-
136+
137+ /* Did we do it already? */
125138 if (CurrentLocaleConv )
126139 return CurrentLocaleConv ;
127140
128141 /* Save current locale setting to lc */
129142 PGLC_current (& lc );
130143
131- /* Set all locale category for current lang */
144+ /* Set all locale categories based on postmaster's environment vars */
132145 setlocale (LC_ALL , "" );
133146
134- /* Get numeric formatting information */
147+ /* Get formatting information for the external environment */
135148 CurrentLocaleConv = localeconv ();
136149
137- /* Set previous original locale */
150+ /* Restore Postgres' internal locale settings */
138151 PGLC_setlocale (& lc );
139152
140153 return CurrentLocaleConv ;
141154}
142155
143-
144156#endif /* USE_LOCALE */
0 commit comments