]>
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 gs_cLocale
= new wxXLocale(static_cast<wxXLocaleCTag
*>(NULL
));
86 #ifdef wxHAS_XLOCALE_SUPPORT
88 wxXLocale::wxXLocale(wxLanguage lang
)
90 const wxLanguageInfo
* const info
= wxLocale::GetLanguageInfo(lang
);
97 Init(info
->GetLocaleName().c_str());
101 #if wxCHECK_VISUALC_VERSION(8)
103 // ----------------------------------------------------------------------------
104 // implementation using MSVC locale API
105 // ----------------------------------------------------------------------------
107 void wxXLocale::Init(const char *loc
)
109 if (!loc
|| *loc
== '\0')
112 m_locale
= _create_locale(LC_ALL
, loc
);
115 void wxXLocale::Free()
118 _free_locale(m_locale
);
121 #elif defined(HAVE_LOCALE_T)
123 // ----------------------------------------------------------------------------
124 // implementation using xlocale API
125 // ----------------------------------------------------------------------------
127 void wxXLocale::Init(const char *loc
)
129 if (!loc
|| *loc
== '\0')
132 m_locale
= newlocale(LC_ALL_MASK
, loc
, NULL
);
135 // NOTE: here we do something similar to what wxSetLocaleTryUTF8() does
136 // in wxLocale code (but with newlocale() calls instead of wxSetlocale())
139 buf2
= buf
+ wxS(".UTF-8");
140 m_locale
= newlocale(LC_ALL_MASK
, buf2
.c_str(), NULL
);
143 buf2
= buf
+ wxS(".utf-8");
144 m_locale
= newlocale(LC_ALL_MASK
, buf2
.c_str(), NULL
);
148 buf2
= buf
+ wxS(".UTF8");
149 m_locale
= newlocale(LC_ALL_MASK
, buf2
.c_str(), NULL
);
153 buf2
= buf
+ wxS(".utf8");
154 m_locale
= newlocale(LC_ALL_MASK
, buf2
.c_str(), NULL
);
158 // TODO: wxLocale performs many more manipulations of the given locale
159 // string in the attempt to set a valid locale; reusing that code
160 // (changing it to take a generic wxTryLocale callback) would be nice
163 void wxXLocale::Free()
166 freelocale(m_locale
);
170 #error "Unknown xlocale support."
173 #endif // wxHAS_XLOCALE_SUPPORT
175 #ifndef wxHAS_XLOCALE_SUPPORT
177 // ============================================================================
178 // Implementation of wxFoo_l() functions for "C" locale without xlocale support
179 // ============================================================================
181 // ----------------------------------------------------------------------------
182 // character classification and transformation functions
183 // ----------------------------------------------------------------------------
185 // lookup table and macros for character type functions
186 #define CTYPE_ALNUM 0x0001
187 #define CTYPE_ALPHA 0x0002
188 #define CTYPE_CNTRL 0x0004
189 #define CTYPE_DIGIT 0x0008
190 #define CTYPE_GRAPH 0x0010
191 #define CTYPE_LOWER 0x0020
192 #define CTYPE_PRINT 0x0040
193 #define CTYPE_PUNCT 0x0080
194 #define CTYPE_SPACE 0x0100
195 #define CTYPE_UPPER 0x0200
196 #define CTYPE_XDIGIT 0x0400
198 static const unsigned int gs_lookup
[] =
200 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004,
201 0x0004, 0x0104, 0x0104, 0x0104, 0x0104, 0x0104, 0x0004, 0x0004,
202 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004,
203 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004,
204 0x0140, 0x00D0, 0x00D0, 0x00D0, 0x00D0, 0x00D0, 0x00D0, 0x00D0,
205 0x00D0, 0x00D0, 0x00D0, 0x00D0, 0x00D0, 0x00D0, 0x00D0, 0x00D0,
206 0x0459, 0x0459, 0x0459, 0x0459, 0x0459, 0x0459, 0x0459, 0x0459,
207 0x0459, 0x0459, 0x00D0, 0x00D0, 0x00D0, 0x00D0, 0x00D0, 0x00D0,
208 0x00D0, 0x0653, 0x0653, 0x0653, 0x0653, 0x0653, 0x0653, 0x0253,
209 0x0253, 0x0253, 0x0253, 0x0253, 0x0253, 0x0253, 0x0253, 0x0253,
210 0x0253, 0x0253, 0x0253, 0x0253, 0x0253, 0x0253, 0x0253, 0x0253,
211 0x0253, 0x0253, 0x0253, 0x00D0, 0x00D0, 0x00D0, 0x00D0, 0x00D0,
212 0x00D0, 0x0473, 0x0473, 0x0473, 0x0473, 0x0473, 0x0473, 0x0073,
213 0x0073, 0x0073, 0x0073, 0x0073, 0x0073, 0x0073, 0x0073, 0x0073,
214 0x0073, 0x0073, 0x0073, 0x0073, 0x0073, 0x0073, 0x0073, 0x0073,
215 0x0073, 0x0073, 0x0073, 0x00D0, 0x00D0, 0x00D0, 0x00D0, 0x0004
219 #define CTYPE_TEST(c, t) ( (c) <= 127 && (gs_lookup[(c)] & (t)) )
223 #define GEN_ISFUNC(name, test) \
224 int name(const wxUniChar& c, const wxXLocale& loc) \
226 wxCHECK(loc.IsOk(), false); \
227 return CTYPE_TEST(c.GetValue(), test); \
230 GEN_ISFUNC(wxIsalnum_l
, CTYPE_ALNUM
)
231 GEN_ISFUNC(wxIsalpha_l
, CTYPE_ALPHA
)
232 GEN_ISFUNC(wxIscntrl_l
, CTYPE_CNTRL
)
233 GEN_ISFUNC(wxIsdigit_l
, CTYPE_DIGIT
)
234 GEN_ISFUNC(wxIsgraph_l
, CTYPE_GRAPH
)
235 GEN_ISFUNC(wxIslower_l
, CTYPE_LOWER
)
236 GEN_ISFUNC(wxIsprint_l
, CTYPE_PRINT
)
237 GEN_ISFUNC(wxIspunct_l
, CTYPE_PUNCT
)
238 GEN_ISFUNC(wxIsspace_l
, CTYPE_SPACE
)
239 GEN_ISFUNC(wxIsupper_l
, CTYPE_UPPER
)
240 GEN_ISFUNC(wxIsxdigit_l
, CTYPE_XDIGIT
)
242 int wxTolower_l(const wxUniChar
& c
, const wxXLocale
& loc
)
244 wxCHECK(loc
.IsOk(), false);
246 if(CTYPE_TEST(c
.GetValue(), CTYPE_UPPER
))
248 return c
- 'A' + 'a';
254 int wxToupper_l(const wxUniChar
& c
, const wxXLocale
& loc
)
256 wxCHECK(loc
.IsOk(), false);
258 if(CTYPE_TEST(c
.GetValue(), CTYPE_LOWER
))
260 return c
- 'a' + 'A';
267 // ----------------------------------------------------------------------------
268 // string --> number conversion functions
269 // ----------------------------------------------------------------------------
272 WARNING: the implementation of the wxStrtoX_l() functions below is unsafe
273 in a multi-threaded environment as we temporary change the locale
274 and if in the meanwhile an other thread performs some locale-dependent
275 operation, it may get unexpected results...
276 However this is the best we can do without reinventing the wheel in the
277 case !wxHAS_XLOCALE_SUPPORT...
281 Note that this code is similar to (a portion of) wxLocale::IsAvailable code
283 #define IMPLEMENT_STRTOX_L_START \
284 wxCHECK(loc.IsOk(), 0); \
286 /* (Try to) temporary set the 'C' locale */ \
287 const char *oldLocale = wxSetlocale(LC_NUMERIC, "C"); \
290 /* the current locale was not changed; no need to */ \
291 /* restore the previous one... */ \
293 /* signal an error (better than nothing) */ \
297 #define IMPLEMENT_STRTOX_L_END \
298 /* restore the original locale */ \
299 wxSetlocale(LC_NUMERIC, oldLocale); \
302 double wxStrtod_l(const wchar_t* str
, wchar_t **endptr
, const wxXLocale
& loc
)
304 IMPLEMENT_STRTOX_L_START
305 double ret
= wxStrtod(str
, endptr
);
306 IMPLEMENT_STRTOX_L_END
309 double wxStrtod_l(const char* str
, char **endptr
, const wxXLocale
& loc
)
311 IMPLEMENT_STRTOX_L_START
312 double ret
= wxStrtod(str
, endptr
);
313 IMPLEMENT_STRTOX_L_END
316 long wxStrtol_l(const wchar_t* str
, wchar_t **endptr
, int base
, const wxXLocale
& loc
)
318 IMPLEMENT_STRTOX_L_START
319 long ret
= wxStrtol(str
, endptr
, base
);
320 IMPLEMENT_STRTOX_L_END
323 long wxStrtol_l(const char* str
, char **endptr
, int base
, const wxXLocale
& loc
)
325 IMPLEMENT_STRTOX_L_START
326 long ret
= wxStrtol(str
, endptr
, base
);
327 IMPLEMENT_STRTOX_L_END
330 unsigned long wxStrtoul_l(const wchar_t* str
, wchar_t **endptr
, int base
, const wxXLocale
& loc
)
332 IMPLEMENT_STRTOX_L_START
333 unsigned long ret
= wxStrtoul(str
, endptr
, base
);
334 IMPLEMENT_STRTOX_L_END
337 unsigned long wxStrtoul_l(const char* str
, char **endptr
, int base
, const wxXLocale
& loc
)
339 IMPLEMENT_STRTOX_L_START
340 unsigned long ret
= wxStrtoul(str
, endptr
, base
);
341 IMPLEMENT_STRTOX_L_END
345 #endif // !defined(wxHAS_XLOCALE_SUPPORT)
347 #endif // wxUSE_XLOCALE