1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
|
/*------
* pg_locale.c
*
* The PostgreSQL locale utils.
*
* 2000 Karel Zak - Zakkr
*
*------
*/
#include <stdio.h>
#include "postgres.h"
#ifdef USE_LOCALE
#include <locale.h>
#include "utils/pg_locale.h"
/* #define DEBUG_LOCALE_UTILS */
/*------
* Return in PG_LocaleCategories current locale setting
*------
*/
PG_LocaleCategories *
PGLC_current( PG_LocaleCategories *lc )
{
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);
lc->lc_messages = setlocale(LC_MESSAGES, NULL);
return lc;
}
#ifdef DEBUG_LOCALE_UTILS
/*------
* Print a PG_LocaleCategories struct as DEBUG
*------
*/
PG_LocaleCategories *
PGLC_debug_lc( PG_LocaleCategories *lc )
{
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",
lc->lang,
lc->lc_ctype,
lc->lc_numeric,
lc->lc_time,
lc->lc_collate,
lc->lc_monetary,
lc->lc_messages
);
return lc;
}
#endif
/*------
* Set locales via a PG_LocaleCategories struct
*------
*/
PG_LocaleCategories *
PGLC_setlocale( PG_LocaleCategories *lc )
{
if (!setlocale(LC_CTYPE, lc->lc_ctype ))
elog(NOTICE, "pg_setlocale(): 'LC_CTYPE=%s' cannot be honored.", lc->lc_ctype);
if (!setlocale(LC_NUMERIC, lc->lc_numeric ))
elog(NOTICE, "pg_setlocale(): 'LC_NUMERIC=%s' cannot be honored.", lc->lc_numeric);
if (!setlocale(LC_TIME, lc->lc_time ))
elog(NOTICE, "pg_setlocale(): 'LC_TIME=%s' cannot be honored.", lc->lc_time);
if (!setlocale(LC_COLLATE, lc->lc_collate ))
elog(NOTICE, "pg_setlocale(): 'LC_COLLATE=%s' cannot be honored.", lc->lc_collate);
if (!setlocale(LC_MONETARY, lc->lc_monetary ))
elog(NOTICE, "pg_setlocale(): 'LC_MONETARY=%s' cannot be honored.", lc->lc_monetary);
if (!setlocale(LC_MESSAGES, lc->lc_messages ))
elog(NOTICE, "pg_setlocale(): 'LC_MESSAGE=%s' cannot be honored.", lc->lc_messages);
return lc;
}
/*------
* Return the POSIX lconv struct (contains number/money formatting information)
* with locale information for *all* categories.
* => Returned lconv is *independent* on current locale catogories setting - in
* contrast to standard localeconv().
*
* ! libc prepare memory space for lconv itself and all returned strings in
* lconv are *static strings*.
*------
*/
struct lconv *
PGLC_localeconv()
{
PG_LocaleCategories lc;
struct lconv *lconv;
/* Save current locale setting to lc */
PGLC_current(&lc);
/* Set all locale category for current lang */
setlocale(LC_ALL, "");
/* Get numeric formatting information */
lconv = localeconv();
/* Set previous original locale */
PGLC_setlocale(&lc);
return lconv;
}
#endif /* USE_LOCALE */
|