]>
git.saurik.com Git - wxWidgets.git/blob - src/common/xlocale.cpp
1 //////////////////////////////////////////////////////////////////////////////
2 // Name: src/common/xlocale.cpp
3 // Purpose: xlocale wrappers/impl to provide some xlocale wrappers
4 // Author: Brian Vanderburg II, Vadim Zeitlin
7 // Copyright: (c) 2008 Brian Vanderburg II
8 // 2008 Vadim Zeitlin <vadim@wxwidgets.org>
9 // Licence: wxWindows licence
10 ///////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
14 // ============================================================================
16 // ----------------------------------------------------------------------------
18 // ----------------------------------------------------------------------------
20 #include "wx/wxprec.h"
29 #include "wx/module.h"
32 #include "wx/xlocale.h"
37 // ----------------------------------------------------------------------------
39 // ----------------------------------------------------------------------------
41 // This is the C locale object, it is created on demand
42 static wxXLocale
*gs_cLocale
= NULL
;
44 wxXLocale wxNullXLocale
;
47 // ============================================================================
49 // ============================================================================
51 // ----------------------------------------------------------------------------
52 // Module for gs_cLocale cleanup
53 // ----------------------------------------------------------------------------
55 class wxXLocaleModule
: public wxModule
58 virtual bool OnInit() { return true; }
59 virtual void OnExit() { wxDELETE(gs_cLocale
); }
61 DECLARE_DYNAMIC_CLASS(wxXLocaleModule
)
64 IMPLEMENT_DYNAMIC_CLASS(wxXLocaleModule
, wxModule
)
67 // ============================================================================
68 // wxXLocale implementation
69 // ============================================================================
71 // ----------------------------------------------------------------------------
73 // ----------------------------------------------------------------------------
76 wxXLocale
& wxXLocale::GetCLocale()
80 // NOTE: bcc551 has trouble doing static_cast with incomplete
81 // type definition. reinterpret_cast used as workaround
82 gs_cLocale
= new wxXLocale( reinterpret_cast<wxXLocaleCTag
*>(NULL
) );
88 #ifdef wxHAS_XLOCALE_SUPPORT
90 wxXLocale::wxXLocale(wxLanguage lang
)
92 const wxLanguageInfo
* const info
= wxLocale::GetLanguageInfo(lang
);
99 Init(info
->GetLocaleName().c_str());
103 #if wxCHECK_VISUALC_VERSION(8)
105 // ----------------------------------------------------------------------------
106 // implementation using MSVC locale API
107 // ----------------------------------------------------------------------------
109 void wxXLocale::Init(const char *loc
)
111 if (!loc
|| *loc
== '\0')
114 m_locale
= _create_locale(LC_ALL
, loc
);
117 void wxXLocale::Free()
120 _free_locale(m_locale
);
123 #elif defined(HAVE_LOCALE_T)
125 // ----------------------------------------------------------------------------
126 // implementation using xlocale API
127 // ----------------------------------------------------------------------------
129 void wxXLocale::Init(const char *loc
)
131 if (!loc
|| *loc
== '\0')
134 m_locale
= newlocale(LC_ALL_MASK
, loc
, NULL
);
137 // NOTE: here we do something similar to what wxSetLocaleTryUTF8() does
138 // in wxLocale code (but with newlocale() calls instead of wxSetlocale())
141 buf2
= buf
+ wxS(".UTF-8");
142 m_locale
= newlocale(LC_ALL_MASK
, buf2
.c_str(), NULL
);
145 buf2
= buf
+ wxS(".utf-8");
146 m_locale
= newlocale(LC_ALL_MASK
, buf2
.c_str(), NULL
);
150 buf2
= buf
+ wxS(".UTF8");
151 m_locale
= newlocale(LC_ALL_MASK
, buf2
.c_str(), NULL
);
155 buf2
= buf
+ wxS(".utf8");
156 m_locale
= newlocale(LC_ALL_MASK
, buf2
.c_str(), NULL
);
160 // TODO: wxLocale performs many more manipulations of the given locale
161 // string in the attempt to set a valid locale; reusing that code
162 // (changing it to take a generic wxTryLocale callback) would be nice
165 void wxXLocale::Free()
168 freelocale(m_locale
);
172 #error "Unknown xlocale support."
175 #endif // wxHAS_XLOCALE_SUPPORT
177 #ifndef wxHAS_XLOCALE_SUPPORT
179 // ============================================================================
180 // Implementation of wxFoo_l() functions for "C" locale without xlocale support
181 // ============================================================================
183 // ----------------------------------------------------------------------------
184 // character classification and transformation functions
185 // ----------------------------------------------------------------------------
187 // lookup table and macros for character type functions
188 #define CTYPE_ALNUM 0x0001
189 #define CTYPE_ALPHA 0x0002
190 #define CTYPE_CNTRL 0x0004
191 #define CTYPE_DIGIT 0x0008
192 #define CTYPE_GRAPH 0x0010
193 #define CTYPE_LOWER 0x0020
194 #define CTYPE_PRINT 0x0040
195 #define CTYPE_PUNCT 0x0080
196 #define CTYPE_SPACE 0x0100
197 #define CTYPE_UPPER 0x0200
198 #define CTYPE_XDIGIT 0x0400
200 static const unsigned int gs_lookup
[] =
202 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004,
203 0x0004, 0x0104, 0x0104, 0x0104, 0x0104, 0x0104, 0x0004, 0x0004,
204 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004,
205 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004,
206 0x0140, 0x00D0, 0x00D0, 0x00D0, 0x00D0, 0x00D0, 0x00D0, 0x00D0,
207 0x00D0, 0x00D0, 0x00D0, 0x00D0, 0x00D0, 0x00D0, 0x00D0, 0x00D0,
208 0x0459, 0x0459, 0x0459, 0x0459, 0x0459, 0x0459, 0x0459, 0x0459,
209 0x0459, 0x0459, 0x00D0, 0x00D0, 0x00D0, 0x00D0, 0x00D0, 0x00D0,
210 0x00D0, 0x0653, 0x0653, 0x0653, 0x0653, 0x0653, 0x0653, 0x0253,
211 0x0253, 0x0253, 0x0253, 0x0253, 0x0253, 0x0253, 0x0253, 0x0253,
212 0x0253, 0x0253, 0x0253, 0x0253, 0x0253, 0x0253, 0x0253, 0x0253,
213 0x0253, 0x0253, 0x0253, 0x00D0, 0x00D0, 0x00D0, 0x00D0, 0x00D0,
214 0x00D0, 0x0473, 0x0473, 0x0473, 0x0473, 0x0473, 0x0473, 0x0073,
215 0x0073, 0x0073, 0x0073, 0x0073, 0x0073, 0x0073, 0x0073, 0x0073,
216 0x0073, 0x0073, 0x0073, 0x0073, 0x0073, 0x0073, 0x0073, 0x0073,
217 0x0073, 0x0073, 0x0073, 0x00D0, 0x00D0, 0x00D0, 0x00D0, 0x0004
221 #define CTYPE_TEST(c, t) ( (c) <= 127 && (gs_lookup[(c)] & (t)) )
225 #define GEN_ISFUNC(name, test) \
226 int name(const wxUniChar& c, const wxXLocale& loc) \
228 wxCHECK(loc.IsOk(), false); \
229 return CTYPE_TEST(c.GetValue(), test); \
232 GEN_ISFUNC(wxIsalnum_l
, CTYPE_ALNUM
)
233 GEN_ISFUNC(wxIsalpha_l
, CTYPE_ALPHA
)
234 GEN_ISFUNC(wxIscntrl_l
, CTYPE_CNTRL
)
235 GEN_ISFUNC(wxIsdigit_l
, CTYPE_DIGIT
)
236 GEN_ISFUNC(wxIsgraph_l
, CTYPE_GRAPH
)
237 GEN_ISFUNC(wxIslower_l
, CTYPE_LOWER
)
238 GEN_ISFUNC(wxIsprint_l
, CTYPE_PRINT
)
239 GEN_ISFUNC(wxIspunct_l
, CTYPE_PUNCT
)
240 GEN_ISFUNC(wxIsspace_l
, CTYPE_SPACE
)
241 GEN_ISFUNC(wxIsupper_l
, CTYPE_UPPER
)
242 GEN_ISFUNC(wxIsxdigit_l
, CTYPE_XDIGIT
)
244 int wxTolower_l(const wxUniChar
& c
, const wxXLocale
& loc
)
246 wxCHECK(loc
.IsOk(), false);
248 if(CTYPE_TEST(c
.GetValue(), CTYPE_UPPER
))
250 return c
- 'A' + 'a';
256 int wxToupper_l(const wxUniChar
& c
, const wxXLocale
& loc
)
258 wxCHECK(loc
.IsOk(), false);
260 if(CTYPE_TEST(c
.GetValue(), CTYPE_LOWER
))
262 return c
- 'a' + 'A';
269 // ----------------------------------------------------------------------------
270 // string --> number conversion functions
271 // ----------------------------------------------------------------------------
274 WARNING: the implementation of the wxStrtoX_l() functions below is unsafe
275 in a multi-threaded environment as we temporary change the locale
276 and if in the meanwhile an other thread performs some locale-dependent
277 operation, it may get unexpected results...
278 However this is the best we can do without reinventing the wheel in the
279 case !wxHAS_XLOCALE_SUPPORT...
283 Note that this code is similar to (a portion of) wxLocale::IsAvailable code
285 #define IMPLEMENT_STRTOX_L_START \
286 wxCHECK(loc.IsOk(), 0); \
288 /* (Try to) temporary set the 'C' locale */ \
289 const char *oldLocale = wxSetlocale(LC_NUMERIC, "C"); \
292 /* the current locale was not changed; no need to */ \
293 /* restore the previous one... */ \
295 /* signal an error (better than nothing) */ \
299 #define IMPLEMENT_STRTOX_L_END \
300 /* restore the original locale */ \
301 wxSetlocale(LC_NUMERIC, oldLocale); \
304 double wxStrtod_l(const wchar_t* str
, wchar_t **endptr
, const wxXLocale
& loc
)
306 IMPLEMENT_STRTOX_L_START
307 double ret
= wxStrtod(str
, endptr
);
308 IMPLEMENT_STRTOX_L_END
311 double wxStrtod_l(const char* str
, char **endptr
, const wxXLocale
& loc
)
313 IMPLEMENT_STRTOX_L_START
314 double ret
= wxStrtod(str
, endptr
);
315 IMPLEMENT_STRTOX_L_END
318 long wxStrtol_l(const wchar_t* str
, wchar_t **endptr
, int base
, const wxXLocale
& loc
)
320 IMPLEMENT_STRTOX_L_START
321 long ret
= wxStrtol(str
, endptr
, base
);
322 IMPLEMENT_STRTOX_L_END
325 long wxStrtol_l(const char* str
, char **endptr
, int base
, const wxXLocale
& loc
)
327 IMPLEMENT_STRTOX_L_START
328 long ret
= wxStrtol(str
, endptr
, base
);
329 IMPLEMENT_STRTOX_L_END
332 unsigned long wxStrtoul_l(const wchar_t* str
, wchar_t **endptr
, int base
, const wxXLocale
& loc
)
334 IMPLEMENT_STRTOX_L_START
335 unsigned long ret
= wxStrtoul(str
, endptr
, base
);
336 IMPLEMENT_STRTOX_L_END
339 unsigned long wxStrtoul_l(const char* str
, char **endptr
, int base
, const wxXLocale
& loc
)
341 IMPLEMENT_STRTOX_L_START
342 unsigned long ret
= wxStrtoul(str
, endptr
, base
);
343 IMPLEMENT_STRTOX_L_END
347 #endif // !defined(wxHAS_XLOCALE_SUPPORT)
349 #endif // wxUSE_XLOCALE