]> git.saurik.com Git - wxWidgets.git/blame - src/common/xlocale.cpp
correct test for wxDEBUG_LEVEL in last commit
[wxWidgets.git] / src / common / xlocale.cpp
CommitLineData
6e4ae332
VZ
1//////////////////////////////////////////////////////////////////////////////
2// Name: src/common/xlocale.cpp
3// Purpose: xlocale wrappers/impl to provide some xlocale wrappers
4// Author: Brian Vanderburg II, Vadim Zeitlin
5// Created: 2008-01-07
6// RCS-ID: $Id$
7// Copyright: (c) 2008 Brian Vanderburg II
8// 2008 Vadim Zeitlin <vadim@wxwidgets.org>
9// Licence: wxWindows licence
10///////////////////////////////////////////////////////////////////////////////
11
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
20#include "wx/wxprec.h"
21
22#ifdef __BORLANDC__
23 #pragma hdrstop
24#endif
25
26#if wxUSE_XLOCALE
27
28#ifndef WX_PRECOMP
29 #include "wx/module.h"
30#endif
31
32#include "wx/xlocale.h"
33
28e0798f
FM
34#include <errno.h>
35
6e4ae332
VZ
36// ----------------------------------------------------------------------------
37// module globals
38// ----------------------------------------------------------------------------
39
40// This is the C locale object, it is created on demand
41static wxXLocale *gs_cLocale = NULL;
42
dad013ac
FM
43wxXLocale wxNullXLocale;
44
45
6e4ae332
VZ
46// ============================================================================
47// implementation
48// ============================================================================
49
50// ----------------------------------------------------------------------------
51// Module for gs_cLocale cleanup
52// ----------------------------------------------------------------------------
53
54class wxXLocaleModule : public wxModule
55{
56public:
57 virtual bool OnInit() { return true; }
58 virtual void OnExit() { wxDELETE(gs_cLocale); }
59
60 DECLARE_DYNAMIC_CLASS(wxXLocaleModule)
61};
62
63IMPLEMENT_DYNAMIC_CLASS(wxXLocaleModule, wxModule)
64
65
66// ============================================================================
67// wxXLocale implementation
68// ============================================================================
69
70// ----------------------------------------------------------------------------
71// common parts
72// ----------------------------------------------------------------------------
73
74// Get the C locale
75wxXLocale& wxXLocale::GetCLocale()
76{
77 if ( !gs_cLocale )
78 {
5c33522f 79 gs_cLocale = new wxXLocale(static_cast<wxXLocaleCTag *>(NULL));
6e4ae332
VZ
80 }
81
82 return *gs_cLocale;
83}
84
45f5fbd4
VZ
85#ifdef wxHAS_XLOCALE_SUPPORT
86
6e4ae332
VZ
87wxXLocale::wxXLocale(wxLanguage lang)
88{
89 const wxLanguageInfo * const info = wxLocale::GetLanguageInfo(lang);
90 if ( !info )
91 {
92 m_locale = NULL;
93 }
94 else
95 {
e340b786 96 Init(info->GetLocaleName().c_str());
6e4ae332
VZ
97 }
98}
99
6e4ae332
VZ
100#if wxCHECK_VISUALC_VERSION(8)
101
102// ----------------------------------------------------------------------------
103// implementation using MSVC locale API
104// ----------------------------------------------------------------------------
105
106void wxXLocale::Init(const char *loc)
107{
dad013ac
FM
108 if (!loc || *loc == '\0')
109 return;
110
6e4ae332
VZ
111 m_locale = _create_locale(LC_ALL, loc);
112}
113
114void wxXLocale::Free()
115{
116 if ( m_locale )
117 _free_locale(m_locale);
118}
119
120#elif defined(HAVE_LOCALE_T)
121
122// ----------------------------------------------------------------------------
123// implementation using xlocale API
124// ----------------------------------------------------------------------------
125
126void wxXLocale::Init(const char *loc)
127{
dad013ac
FM
128 if (!loc || *loc == '\0')
129 return;
130
6e4ae332 131 m_locale = newlocale(LC_ALL_MASK, loc, NULL);
dad013ac
FM
132 if (!m_locale)
133 {
134 // NOTE: here we do something similar to what wxSetLocaleTryUTF8() does
135 // in wxLocale code (but with newlocale() calls instead of wxSetlocale())
136 wxString buf(loc);
137 wxString buf2;
138 buf2 = buf + wxS(".UTF-8");
5337ab1b 139 m_locale = newlocale(LC_ALL_MASK, buf2.c_str(), NULL);
dad013ac
FM
140 if ( !m_locale )
141 {
142 buf2 = buf + wxS(".utf-8");
5337ab1b 143 m_locale = newlocale(LC_ALL_MASK, buf2.c_str(), NULL);
dad013ac
FM
144 }
145 if ( !m_locale )
146 {
147 buf2 = buf + wxS(".UTF8");
5337ab1b 148 m_locale = newlocale(LC_ALL_MASK, buf2.c_str(), NULL);
dad013ac
FM
149 }
150 if ( !m_locale )
151 {
152 buf2 = buf + wxS(".utf8");
5337ab1b 153 m_locale = newlocale(LC_ALL_MASK, buf2.c_str(), NULL);
dad013ac
FM
154 }
155 }
156
157 // TODO: wxLocale performs many more manipulations of the given locale
158 // string in the attempt to set a valid locale; reusing that code
159 // (changing it to take a generic wxTryLocale callback) would be nice
6e4ae332
VZ
160}
161
162void wxXLocale::Free()
163{
164 if ( m_locale )
165 freelocale(m_locale);
166}
167
168#else
169 #error "Unknown xlocale support."
170#endif
171
172#endif // wxHAS_XLOCALE_SUPPORT
173
174#ifndef wxHAS_XLOCALE_SUPPORT
175
176// ============================================================================
177// Implementation of wxFoo_l() functions for "C" locale without xlocale support
178// ============================================================================
179
180// ----------------------------------------------------------------------------
181// character classification and transformation functions
182// ----------------------------------------------------------------------------
183
184// lookup table and macros for character type functions
185#define CTYPE_ALNUM 0x0001
186#define CTYPE_ALPHA 0x0002
187#define CTYPE_CNTRL 0x0004
188#define CTYPE_DIGIT 0x0008
189#define CTYPE_GRAPH 0x0010
190#define CTYPE_LOWER 0x0020
191#define CTYPE_PRINT 0x0040
192#define CTYPE_PUNCT 0x0080
193#define CTYPE_SPACE 0x0100
194#define CTYPE_UPPER 0x0200
195#define CTYPE_XDIGIT 0x0400
196
197static unsigned int gs_lookup[] =
198{
199 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004,
200 0x0004, 0x0104, 0x0104, 0x0104, 0x0104, 0x0104, 0x0004, 0x0004,
201 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004,
202 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004,
203 0x0140, 0x00D0, 0x00D0, 0x00D0, 0x00D0, 0x00D0, 0x00D0, 0x00D0,
204 0x00D0, 0x00D0, 0x00D0, 0x00D0, 0x00D0, 0x00D0, 0x00D0, 0x00D0,
205 0x0459, 0x0459, 0x0459, 0x0459, 0x0459, 0x0459, 0x0459, 0x0459,
206 0x0459, 0x0459, 0x00D0, 0x00D0, 0x00D0, 0x00D0, 0x00D0, 0x00D0,
207 0x00D0, 0x0653, 0x0653, 0x0653, 0x0653, 0x0653, 0x0653, 0x0253,
208 0x0253, 0x0253, 0x0253, 0x0253, 0x0253, 0x0253, 0x0253, 0x0253,
209 0x0253, 0x0253, 0x0253, 0x0253, 0x0253, 0x0253, 0x0253, 0x0253,
210 0x0253, 0x0253, 0x0253, 0x00D0, 0x00D0, 0x00D0, 0x00D0, 0x00D0,
211 0x00D0, 0x0473, 0x0473, 0x0473, 0x0473, 0x0473, 0x0473, 0x0073,
212 0x0073, 0x0073, 0x0073, 0x0073, 0x0073, 0x0073, 0x0073, 0x0073,
213 0x0073, 0x0073, 0x0073, 0x0073, 0x0073, 0x0073, 0x0073, 0x0073,
214 0x0073, 0x0073, 0x0073, 0x00D0, 0x00D0, 0x00D0, 0x00D0, 0x0004
215};
216
217
218#define CTYPE_TEST(c, t) ( (c) <= 127 && (gs_lookup[(c)] & (t)) )
219
220
221// ctype functions
222#define GEN_ISFUNC(name, test) \
223int name(const wxUniChar& c, const wxXLocale& loc) \
224{ \
225 wxCHECK(loc.IsOk(), false); \
226 return CTYPE_TEST(c.GetValue(), test); \
227}
228
229GEN_ISFUNC(wxIsalnum_l, CTYPE_ALNUM)
230GEN_ISFUNC(wxIsalpha_l, CTYPE_ALPHA)
231GEN_ISFUNC(wxIscntrl_l, CTYPE_CNTRL)
232GEN_ISFUNC(wxIsdigit_l, CTYPE_DIGIT)
233GEN_ISFUNC(wxIsgraph_l, CTYPE_GRAPH)
234GEN_ISFUNC(wxIslower_l, CTYPE_LOWER)
235GEN_ISFUNC(wxIsprint_l, CTYPE_PRINT)
236GEN_ISFUNC(wxIspunct_l, CTYPE_PUNCT)
237GEN_ISFUNC(wxIsspace_l, CTYPE_SPACE)
238GEN_ISFUNC(wxIsupper_l, CTYPE_UPPER)
239GEN_ISFUNC(wxIsxdigit_l, CTYPE_XDIGIT)
240
a4e53d46 241int wxTolower_l(const wxUniChar& c, const wxXLocale& loc)
6e4ae332
VZ
242{
243 wxCHECK(loc.IsOk(), false);
244
45f5fbd4 245 if(CTYPE_TEST(c.GetValue(), CTYPE_UPPER))
6e4ae332
VZ
246 {
247 return c - 'A' + 'a';
248 }
249
250 return c;
251}
252
a4e53d46 253int wxToupper_l(const wxUniChar& c, const wxXLocale& loc)
6e4ae332
VZ
254{
255 wxCHECK(loc.IsOk(), false);
256
45f5fbd4 257 if(CTYPE_TEST(c.GetValue(), CTYPE_LOWER))
6e4ae332
VZ
258 {
259 return c - 'a' + 'A';
260 }
261
262 return c;
263}
264
28e0798f
FM
265
266// ----------------------------------------------------------------------------
267// string --> number conversion functions
268// ----------------------------------------------------------------------------
269
270/*
271 WARNING: the implementation of the wxStrtoX_l() functions below is unsafe
272 in a multi-threaded environment as we temporary change the locale
273 and if in the meanwhile an other thread performs some locale-dependent
274 operation, it may get unexpected results...
275 However this is the best we can do without reinventing the wheel in the
276 case !wxHAS_XLOCALE_SUPPORT...
277*/
278
797a2706
FM
279/*
280 Note that this code is similar to (a portion of) wxLocale::IsAvailable code
281*/
28e0798f
FM
282#define IMPLEMENT_STRTOX_L_START \
283 wxCHECK(loc.IsOk(), 0); \
284 \
375330ac
FM
285 /* (Try to) temporary set the 'C' locale */ \
286 const char *oldLocale = wxSetlocale(LC_NUMERIC, "C"); \
287 if ( !oldLocale ) \
28e0798f 288 { \
375330ac
FM
289 /* the current locale was not changed; no need to */ \
290 /* restore the previous one... */ \
28e0798f
FM
291 errno = EINVAL; \
292 /* signal an error (better than nothing) */ \
293 return 0; \
797a2706 294 }
28e0798f
FM
295
296#define IMPLEMENT_STRTOX_L_END \
297 /* restore the original locale */ \
298 wxSetlocale(LC_NUMERIC, oldLocale); \
299 return ret;
300
301double wxStrtod_l(const wchar_t* str, wchar_t **endptr, const wxXLocale& loc)
302{
303 IMPLEMENT_STRTOX_L_START
304 double ret = wxStrtod(str, endptr);
305 IMPLEMENT_STRTOX_L_END
306}
307
308double wxStrtod_l(const char* str, char **endptr, const wxXLocale& loc)
309{
310 IMPLEMENT_STRTOX_L_START
311 double ret = wxStrtod(str, endptr);
312 IMPLEMENT_STRTOX_L_END
313}
314
315long wxStrtol_l(const wchar_t* str, wchar_t **endptr, int base, const wxXLocale& loc)
316{
317 IMPLEMENT_STRTOX_L_START
318 long ret = wxStrtol(str, endptr, base);
319 IMPLEMENT_STRTOX_L_END
320}
321
322long wxStrtol_l(const char* str, char **endptr, int base, const wxXLocale& loc)
323{
324 IMPLEMENT_STRTOX_L_START
325 long ret = wxStrtol(str, endptr, base);
326 IMPLEMENT_STRTOX_L_END
327}
328
329unsigned long wxStrtoul_l(const wchar_t* str, wchar_t **endptr, int base, const wxXLocale& loc)
330{
331 IMPLEMENT_STRTOX_L_START
332 unsigned long ret = wxStrtoul(str, endptr, base);
333 IMPLEMENT_STRTOX_L_END
334}
335
336unsigned long wxStrtoul_l(const char* str, char **endptr, int base, const wxXLocale& loc)
337{
338 IMPLEMENT_STRTOX_L_START
339 unsigned long ret = wxStrtoul(str, endptr, base);
340 IMPLEMENT_STRTOX_L_END
341}
342
343
6e4ae332
VZ
344#endif // !defined(wxHAS_XLOCALE_SUPPORT)
345
346#endif // wxUSE_XLOCALE