1
-
2
1
/* -----------------------------------------------------------------------
3
2
* pg_locale.c
4
3
*
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.
6
5
*
7
6
*
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 $
9
8
*
10
- * The PostgreSQL locale utils.
9
+ * Portions Copyright (c) 1999-2000, PostgreSQL, Inc
11
10
*
12
11
* Karel Zak - Zakkr
13
12
*
14
13
* -----------------------------------------------------------------------
15
14
*/
16
15
17
- #include <stdio.h>
18
-
19
16
#include "postgres.h"
20
17
21
18
#ifdef USE_LOCALE
28
25
29
26
static struct lconv * CurrentLocaleConv = NULL ;
30
27
28
+ static void PGLC_setlocale (PG_LocaleCategories * lc );
29
+
31
30
/*------
32
- * Return in PG_LocaleCategories current locale setting
31
+ * Return in PG_LocaleCategories the current locale settings
33
32
*------
34
33
*/
35
- PG_LocaleCategories *
34
+ void
36
35
PGLC_current (PG_LocaleCategories * lc )
37
36
{
38
37
lc -> lang = getenv ("LANG" );
@@ -45,7 +44,6 @@ PGLC_current(PG_LocaleCategories * lc)
45
44
#ifdef LC_MESSAGES
46
45
lc -> lc_messages = setlocale (LC_MESSAGES , NULL );
47
46
#endif
48
- return lc ;
49
47
}
50
48
51
49
@@ -55,7 +53,7 @@ PGLC_current(PG_LocaleCategories * lc)
55
53
* Print a PG_LocaleCategories struct as DEBUG
56
54
*------
57
55
*/
58
- PG_LocaleCategories *
56
+ static void
59
57
PGLC_debug_lc (PG_LocaleCategories * lc )
60
58
{
61
59
#ifdef LC_MESSAGES
@@ -73,72 +71,86 @@ PGLC_debug_lc(PG_LocaleCategories * lc)
73
71
, lc -> lc_messages
74
72
#endif
75
73
);
76
-
77
- return lc ;
78
74
}
79
75
80
76
#endif
81
77
82
78
/*------
83
79
* 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.
84
85
*------
85
86
*/
86
- PG_LocaleCategories *
87
+ static void
87
88
PGLC_setlocale (PG_LocaleCategories * lc )
88
89
{
90
+ if (!setlocale (LC_COLLATE , lc -> lc_collate ))
91
+ elog (NOTICE , "pg_setlocale(): 'LC_COLLATE=%s' cannot be honored." ,
92
+ lc -> lc_collate );
93
+
89
94
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 );
91
97
92
98
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 );
94
101
95
102
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 );
100
105
101
106
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
+
103
110
#ifdef LC_MESSAGES
104
111
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 );
106
114
#endif
107
- return lc ;
108
115
}
109
116
110
117
/*------
111
118
* 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?
115
126
*
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.
118
130
*------
119
131
*/
120
132
struct lconv *
121
133
PGLC_localeconv (void )
122
134
{
123
135
PG_LocaleCategories lc ;
124
-
136
+
137
+ /* Did we do it already? */
125
138
if (CurrentLocaleConv )
126
139
return CurrentLocaleConv ;
127
140
128
141
/* Save current locale setting to lc */
129
142
PGLC_current (& lc );
130
143
131
- /* Set all locale category for current lang */
144
+ /* Set all locale categories based on postmaster's environment vars */
132
145
setlocale (LC_ALL , "" );
133
146
134
- /* Get numeric formatting information */
147
+ /* Get formatting information for the external environment */
135
148
CurrentLocaleConv = localeconv ();
136
149
137
- /* Set previous original locale */
150
+ /* Restore Postgres' internal locale settings */
138
151
PGLC_setlocale (& lc );
139
152
140
153
return CurrentLocaleConv ;
141
154
}
142
155
143
-
144
156
#endif /* USE_LOCALE */
0 commit comments