]>
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"
36 // ----------------------------------------------------------------------------
38 // ----------------------------------------------------------------------------
40 // This is the C locale object, it is created on demand
41 static wxXLocale
*gs_cLocale
= NULL
;
43 wxXLocale wxNullXLocale
;
46 // ============================================================================
48 // ============================================================================
50 // ----------------------------------------------------------------------------
51 // Module for gs_cLocale cleanup
52 // ----------------------------------------------------------------------------
54 class wxXLocaleModule
: public wxModule
57 virtual bool OnInit() { return true; }
58 virtual void OnExit() { wxDELETE(gs_cLocale
); }
60 DECLARE_DYNAMIC_CLASS(wxXLocaleModule
)
63 IMPLEMENT_DYNAMIC_CLASS(wxXLocaleModule
, wxModule
)
66 // ============================================================================
67 // wxXLocale implementation
68 // ============================================================================
70 // ----------------------------------------------------------------------------
72 // ----------------------------------------------------------------------------
75 wxXLocale
& wxXLocale::GetCLocale()
79 gs_cLocale
= new wxXLocale(static_cast<wxXLocaleCTag
*>(NULL
));
85 #ifdef wxHAS_XLOCALE_SUPPORT
87 wxXLocale::wxXLocale(wxLanguage lang
)
89 const wxLanguageInfo
* const info
= wxLocale::GetLanguageInfo(lang
);
96 Init(info
->GetLocaleName().c_str());
100 #if wxCHECK_VISUALC_VERSION(8)
102 // ----------------------------------------------------------------------------
103 // implementation using MSVC locale API
104 // ----------------------------------------------------------------------------
106 void wxXLocale::Init(const char *loc
)
108 if (!loc
|| *loc
== '\0')
111 m_locale
= _create_locale(LC_ALL
, loc
);
114 void wxXLocale::Free()
117 _free_locale(m_locale
);
120 #elif defined(HAVE_LOCALE_T)
122 // ----------------------------------------------------------------------------
123 // implementation using xlocale API
124 // ----------------------------------------------------------------------------
126 void wxXLocale::Init(const char *loc
)
128 if (!loc
|| *loc
== '\0')
131 m_locale
= newlocale(LC_ALL_MASK
, loc
, NULL
);
134 // NOTE: here we do something similar to what wxSetLocaleTryUTF8() does
135 // in wxLocale code (but with newlocale() calls instead of wxSetlocale())
138 buf2
= buf
+ wxS(".UTF-8");
139 m_locale
= newlocale(LC_ALL_MASK
, buf2
.c_str(), NULL
);
142 buf2
= buf
+ wxS(".utf-8");
143 m_locale
= newlocale(LC_ALL_MASK
, buf2
.c_str(), NULL
);
147 buf2
= buf
+ wxS(".UTF8");
148 m_locale
= newlocale(LC_ALL_MASK
, buf2
.c_str(), NULL
);
152 buf2
= buf
+ wxS(".utf8");
153 m_locale
= newlocale(LC_ALL_MASK
, buf2
.c_str(), NULL
);
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
162 void wxXLocale::Free()
165 freelocale(m_locale
);
169 #error "Unknown xlocale support."
172 #endif // wxHAS_XLOCALE_SUPPORT
174 #ifndef wxHAS_XLOCALE_SUPPORT
176 // ============================================================================
177 // Implementation of wxFoo_l() functions for "C" locale without xlocale support
178 // ============================================================================
180 // ----------------------------------------------------------------------------
181 // character classification and transformation functions
182 // ----------------------------------------------------------------------------
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
197 static const unsigned int gs_lookup
[] =
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
218 #define CTYPE_TEST(c, t) ( (c) <= 127 && (gs_lookup[(c)] & (t)) )
222 #define GEN_ISFUNC(name, test) \
223 int name(const wxUniChar& c, const wxXLocale& loc) \
225 wxCHECK(loc.IsOk(), false); \
226 return CTYPE_TEST(c.GetValue(), test); \
229 GEN_ISFUNC(wxIsalnum_l
, CTYPE_ALNUM
)
230 GEN_ISFUNC(wxIsalpha_l
, CTYPE_ALPHA
)
231 GEN_ISFUNC(wxIscntrl_l
, CTYPE_CNTRL
)
232 GEN_ISFUNC(wxIsdigit_l
, CTYPE_DIGIT
)
233 GEN_ISFUNC(wxIsgraph_l
, CTYPE_GRAPH
)
234 GEN_ISFUNC(wxIslower_l
, CTYPE_LOWER
)
235 GEN_ISFUNC(wxIsprint_l
, CTYPE_PRINT
)
236 GEN_ISFUNC(wxIspunct_l
, CTYPE_PUNCT
)
237 GEN_ISFUNC(wxIsspace_l
, CTYPE_SPACE
)
238 GEN_ISFUNC(wxIsupper_l
, CTYPE_UPPER
)
239 GEN_ISFUNC(wxIsxdigit_l
, CTYPE_XDIGIT
)
241 int wxTolower_l(const wxUniChar
& c
, const wxXLocale
& loc
)
243 wxCHECK(loc
.IsOk(), false);
245 if(CTYPE_TEST(c
.GetValue(), CTYPE_UPPER
))
247 return c
- 'A' + 'a';
253 int wxToupper_l(const wxUniChar
& c
, const wxXLocale
& loc
)
255 wxCHECK(loc
.IsOk(), false);
257 if(CTYPE_TEST(c
.GetValue(), CTYPE_LOWER
))
259 return c
- 'a' + 'A';
266 // ----------------------------------------------------------------------------
267 // string --> number conversion functions
268 // ----------------------------------------------------------------------------
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...
280 Note that this code is similar to (a portion of) wxLocale::IsAvailable code
282 #define IMPLEMENT_STRTOX_L_START \
283 wxCHECK(loc.IsOk(), 0); \
285 /* (Try to) temporary set the 'C' locale */ \
286 const char *oldLocale = wxSetlocale(LC_NUMERIC, "C"); \
289 /* the current locale was not changed; no need to */ \
290 /* restore the previous one... */ \
292 /* signal an error (better than nothing) */ \
296 #define IMPLEMENT_STRTOX_L_END \
297 /* restore the original locale */ \
298 wxSetlocale(LC_NUMERIC, oldLocale); \
301 double wxStrtod_l(const wchar_t* str
, wchar_t **endptr
, const wxXLocale
& loc
)
303 IMPLEMENT_STRTOX_L_START
304 double ret
= wxStrtod(str
, endptr
);
305 IMPLEMENT_STRTOX_L_END
308 double wxStrtod_l(const char* str
, char **endptr
, const wxXLocale
& loc
)
310 IMPLEMENT_STRTOX_L_START
311 double ret
= wxStrtod(str
, endptr
);
312 IMPLEMENT_STRTOX_L_END
315 long wxStrtol_l(const wchar_t* str
, wchar_t **endptr
, int base
, const wxXLocale
& loc
)
317 IMPLEMENT_STRTOX_L_START
318 long ret
= wxStrtol(str
, endptr
, base
);
319 IMPLEMENT_STRTOX_L_END
322 long wxStrtol_l(const char* str
, char **endptr
, int base
, const wxXLocale
& loc
)
324 IMPLEMENT_STRTOX_L_START
325 long ret
= wxStrtol(str
, endptr
, base
);
326 IMPLEMENT_STRTOX_L_END
329 unsigned long wxStrtoul_l(const wchar_t* str
, wchar_t **endptr
, int base
, const wxXLocale
& loc
)
331 IMPLEMENT_STRTOX_L_START
332 unsigned long ret
= wxStrtoul(str
, endptr
, base
);
333 IMPLEMENT_STRTOX_L_END
336 unsigned long wxStrtoul_l(const char* str
, char **endptr
, int base
, const wxXLocale
& loc
)
338 IMPLEMENT_STRTOX_L_START
339 unsigned long ret
= wxStrtoul(str
, endptr
, base
);
340 IMPLEMENT_STRTOX_L_END
344 #endif // !defined(wxHAS_XLOCALE_SUPPORT)
346 #endif // wxUSE_XLOCALE