1 //////////////////////////////////////////////////////////////////////////////
3 // Purpose: Header 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 ///////////////////////////////////////////////////////////////////////////////
13 This header defines portable wrappers around xlocale foo_l() functions or
14 their MSVC proprietary _foo_l() equivalents when they are available and
15 implements these functions for the "C" locale [only] if they are not. This
16 allows the program running under the default user locale to still use "C"
17 locale for operations such as reading data from files where they are stored
18 using decimal point &c.
20 TODO: Currently only the character classification and transformation
21 functions are implemented, we also need at least
22 - numbers: atof_l(), strtod_l() &c
23 - formatted IO: scanf_l(), printf_l() &c
24 - time: strftime_l(), strptime_l()
27 #ifndef _WX_XLOCALE_H_
28 #define _WX_XLOCALE_H_
30 #include "wx/defs.h" // wxUSE_XLOCALE
34 #include "wx/crt.h" // Includes wx/chartype.h, wx/wxcrt.h(wx/string.h)
35 #include "wx/intl.h" // wxLanguage
37 // The platform-specific locale type
38 // If wxXLocale_t is not defined, then only "C" locale support is provided
39 #ifdef wxHAS_XLOCALE_SUPPORT
40 #if wxCHECK_VISUALC_VERSION(8) && !defined(__WXWINCE__)
41 typedef _locale_t wxXLocale_t
;
42 #define wxXLOCALE_IDENT(name) _ ## name
43 #elif defined(HAVE_LOCALE_T)
52 // Locale type and identifier name
53 typedef locale_t wxXLocale_t
;
55 #define wxXLOCALE_IDENT(name) name
57 #error "Unknown xlocale support"
59 #endif // wxHAS_XLOCALE_SUPPORT
62 // wxXLocale is a wrapper around the native type representing a locale.
64 // It is not to be confused with wxLocale, which handles actually changing the
65 // locale, loading message catalogs, etc. This just stores a locale value.
66 // The similarity of names is unfortunate, but there doesn't seem to be any
67 // better alternative right now. Perhaps by wxWidgets 4.0 better naming could
68 // be used, or this class could become wxLocale (a wrapper for the value), and
69 // some other class could be used to load the language catalogs or something
70 // that would be clearer
71 #ifdef wxHAS_XLOCALE_SUPPORT
73 class WXDLLIMPEXP_BASE wxXLocale
76 // Construct an uninitialized locale
77 wxXLocale() { m_locale
= NULL
; }
79 // Construct from a symbolic language constant
80 wxXLocale(wxLanguage lang
);
82 // Construct from the given language string
83 wxXLocale(const char *loc
) { Init(loc
); }
86 ~wxXLocale() { Free(); }
89 // Get the global "C" locale object
90 static wxXLocale
& GetCLocale();
92 // Check if the object represents a valid locale (notice that without
93 // wxHAS_XLOCALE_SUPPORT the only valid locale is the "C" one)
94 bool IsOk() const { return m_locale
!= NULL
; }
97 wxXLocale_t
Get() const { return m_locale
; }
100 // Special ctor for the "C" locale, it's only used internally as the user
101 // code is supposed to use GetCLocale()
102 wxXLocale(struct wxXLocaleCTag
* WXUNUSED(dummy
)) { Init("C"); }
104 // Create from the given language string (called from ctors)
105 void Init(const char *loc
);
107 // Free the locale if it's non-NULL
111 // The corresponding locale handle, NULL if invalid
112 wxXLocale_t m_locale
;
115 // POSIX xlocale API provides a duplocale() function but MSVC locale API
116 // doesn't give us any means to copy a _locale_t object so we reduce the
117 // functionality to least common denominator here -- it shouldn't be a
118 // problem as copying the locale objects shouldn't be often needed
119 DECLARE_NO_COPY_CLASS(wxXLocale
)
122 #else // !wxHAS_XLOCALE_SUPPORT
124 // Skeleton version supporting only the "C" locale for the systems without
126 class WXDLLIMPEXP_BASE wxXLocale
129 // Construct an uninitialized locale
130 wxXLocale() { m_isC
= false; }
132 // Construct from a symbolic language constant: unless the language is
133 // wxLANGUAGE_ENGLISH_US (which we suppose to be the same as "C" locale)
134 // the object will be invalid
135 wxXLocale(wxLanguage lang
)
137 m_isC
= lang
== wxLANGUAGE_ENGLISH_US
;
140 // Construct from the given language string: unless the string is "C" or
141 // "POSIX" the object will be invalid
142 wxXLocale(const char *loc
)
144 m_isC
= loc
&& (strcmp(loc
, "C") == 0 || strcmp(loc
, "POSIX") == 0);
147 // Default copy ctor, assignment operator and dtor are ok (or would be if
148 // we didn't use DECLARE_NO_COPY_CLASS() for consistency with the xlocale
152 // Get the global "C" locale object
153 static wxXLocale
& GetCLocale();
155 // Check if the object represents a valid locale (notice that without
156 // wxHAS_XLOCALE_SUPPORT the only valid locale is the "C" one)
157 bool IsOk() const { return m_isC
; }
160 // Special ctor for the "C" locale, it's only used internally as the user
161 // code is supposed to use GetCLocale()
162 wxXLocale(struct wxXLocaleCTag
* WXUNUSED(dummy
)) { m_isC
= true; }
164 // Without xlocale support this class can only represent "C" locale, if
165 // this is false the object is invalid
169 // although it's not a problem to copy the objects of this class, we use
170 // this macro in this implementation for consistency with the xlocale-based
171 // one which can't be copied when using MSVC locale API
172 DECLARE_NO_COPY_CLASS(wxXLocale
)
175 #endif // wxHAS_XLOCALE_SUPPORT/!wxHAS_XLOCALE_SUPPORT
178 // A shorter synonym for the most commonly used locale object
179 #define wxCLocale (wxXLocale::GetCLocale())
182 // Wrappers for various functions:
183 #ifdef wxHAS_XLOCALE_SUPPORT
186 #define wxCRT_Isalnum_lA wxXLOCALE_IDENT(isalnum_l)
187 #define wxCRT_Isalpha_lA wxXLOCALE_IDENT(isalpha_l)
188 #define wxCRT_Iscntrl_lA wxXLOCALE_IDENT(iscntrl_l)
189 #define wxCRT_Isdigit_lA wxXLOCALE_IDENT(isdigit_l)
190 #define wxCRT_Isgraph_lA wxXLOCALE_IDENT(isgraph_l)
191 #define wxCRT_Islower_lA wxXLOCALE_IDENT(islower_l)
192 #define wxCRT_Isprint_lA wxXLOCALE_IDENT(isprint_l)
193 #define wxCRT_Ispunct_lA wxXLOCALE_IDENT(ispunct_l)
194 #define wxCRT_Isspace_lA wxXLOCALE_IDENT(isspace_l)
195 #define wxCRT_Isupper_lA wxXLOCALE_IDENT(isupper_l)
196 #define wxCRT_Isxdigit_lA wxXLOCALE_IDENT(isxdigit_l)
197 #define wxCRT_Tolower_lA wxXLOCALE_IDENT(tolower_l)
198 #define wxCRT_Toupper_lA wxXLOCALE_IDENT(toupper_l)
200 inline int wxIsalnum_l(char c
, const wxXLocale
& loc
)
201 { return wxCRT_Isalnum_lA(wx_static_cast(unsigned char, c
), loc
.Get()); }
202 inline int wxIsalpha_l(char c
, const wxXLocale
& loc
)
203 { return wxCRT_Isalpha_lA(wx_static_cast(unsigned char, c
), loc
.Get()); }
204 inline int wxIscntrl_l(char c
, const wxXLocale
& loc
)
205 { return wxCRT_Iscntrl_lA(wx_static_cast(unsigned char, c
), loc
.Get()); }
206 inline int wxIsdigit_l(char c
, const wxXLocale
& loc
)
207 { return wxCRT_Isdigit_lA(wx_static_cast(unsigned char, c
), loc
.Get()); }
208 inline int wxIsgraph_l(char c
, const wxXLocale
& loc
)
209 { return wxCRT_Isgraph_lA(wx_static_cast(unsigned char, c
), loc
.Get()); }
210 inline int wxIslower_l(char c
, const wxXLocale
& loc
)
211 { return wxCRT_Islower_lA(wx_static_cast(unsigned char, c
), loc
.Get()); }
212 inline int wxIsprint_l(char c
, const wxXLocale
& loc
)
213 { return wxCRT_Isprint_lA(wx_static_cast(unsigned char, c
), loc
.Get()); }
214 inline int wxIspunct_l(char c
, const wxXLocale
& loc
)
215 { return wxCRT_Ispunct_lA(wx_static_cast(unsigned char, c
), loc
.Get()); }
216 inline int wxIsspace_l(char c
, const wxXLocale
& loc
)
217 { return wxCRT_Isspace_lA(wx_static_cast(unsigned char, c
), loc
.Get()); }
218 inline int wxIsupper_l(char c
, const wxXLocale
& loc
)
219 { return wxCRT_Isupper_lA(wx_static_cast(unsigned char, c
), loc
.Get()); }
220 inline int wxIsxdigit_l(char c
, const wxXLocale
& loc
)
221 { return wxCRT_Isxdigit_lA(wx_static_cast(unsigned char, c
), loc
.Get()); }
222 inline int wxTolower_l(char c
, const wxXLocale
& loc
)
223 { return wxCRT_Tolower_lA(wx_static_cast(unsigned char, c
), loc
.Get()); }
224 inline int wxToupper_l(char c
, const wxXLocale
& loc
)
225 { return wxCRT_Toupper_lA(wx_static_cast(unsigned char, c
), loc
.Get()); }
228 #define wxCRT_Isalnum_lW wxXLOCALE_IDENT(iswalnum_l)
229 #define wxCRT_Isalpha_lW wxXLOCALE_IDENT(iswalpha_l)
230 #define wxCRT_Iscntrl_lW wxXLOCALE_IDENT(iswcntrl_l)
231 #define wxCRT_Isdigit_lW wxXLOCALE_IDENT(iswdigit_l)
232 #define wxCRT_Isgraph_lW wxXLOCALE_IDENT(iswgraph_l)
233 #define wxCRT_Islower_lW wxXLOCALE_IDENT(iswlower_l)
234 #define wxCRT_Isprint_lW wxXLOCALE_IDENT(iswprint_l)
235 #define wxCRT_Ispunct_lW wxXLOCALE_IDENT(iswpunct_l)
236 #define wxCRT_Isspace_lW wxXLOCALE_IDENT(iswspace_l)
237 #define wxCRT_Isupper_lW wxXLOCALE_IDENT(iswupper_l)
238 #define wxCRT_Isxdigit_lW wxXLOCALE_IDENT(iswxdigit_l)
239 #define wxCRT_Tolower_lW wxXLOCALE_IDENT(towlower_l)
240 #define wxCRT_Toupper_lW wxXLOCALE_IDENT(towupper_l)
242 inline int wxIsalnum_l(wchar_t c
, const wxXLocale
& loc
)
243 { return wxCRT_Isalnum_lW(c
, loc
.Get()); }
244 inline int wxIsalpha_l(wchar_t c
, const wxXLocale
& loc
)
245 { return wxCRT_Isalpha_lW(c
, loc
.Get()); }
246 inline int wxIscntrl_l(wchar_t c
, const wxXLocale
& loc
)
247 { return wxCRT_Iscntrl_lW(c
, loc
.Get()); }
248 inline int wxIsdigit_l(wchar_t c
, const wxXLocale
& loc
)
249 { return wxCRT_Isdigit_lW(c
, loc
.Get()); }
250 inline int wxIsgraph_l(wchar_t c
, const wxXLocale
& loc
)
251 { return wxCRT_Isgraph_lW(c
, loc
.Get()); }
252 inline int wxIslower_l(wchar_t c
, const wxXLocale
& loc
)
253 { return wxCRT_Islower_lW(c
, loc
.Get()); }
254 inline int wxIsprint_l(wchar_t c
, const wxXLocale
& loc
)
255 { return wxCRT_Isprint_lW(c
, loc
.Get()); }
256 inline int wxIspunct_l(wchar_t c
, const wxXLocale
& loc
)
257 { return wxCRT_Ispunct_lW(c
, loc
.Get()); }
258 inline int wxIsspace_l(wchar_t c
, const wxXLocale
& loc
)
259 { return wxCRT_Isspace_lW(c
, loc
.Get()); }
260 inline int wxIsupper_l(wchar_t c
, const wxXLocale
& loc
)
261 { return wxCRT_Isupper_lW(c
, loc
.Get()); }
262 inline int wxIsxdigit_l(wchar_t c
, const wxXLocale
& loc
)
263 { return wxCRT_Isxdigit_lW(c
, loc
.Get()); }
264 inline wchar_t wxTolower_l(wchar_t c
, const wxXLocale
& loc
)
265 { return wxCRT_Tolower_lW(c
, loc
.Get()); }
266 inline wchar_t wxToupper_l(wchar_t c
, const wxXLocale
& loc
)
267 { return wxCRT_Toupper_lW(c
, loc
.Get()); }
269 #endif // wxUSE_UNICDE (ctype functions)
270 #else // !wxHAS_XLOCALE_SUPPORT
272 int WXDLLIMPEXP_BASE
wxIsalnum_l(const wxUniChar
& c
, const wxXLocale
& loc
);
273 int WXDLLIMPEXP_BASE
wxIsalpha_l(const wxUniChar
& c
, const wxXLocale
& loc
);
274 int WXDLLIMPEXP_BASE
wxIscntrl_l(const wxUniChar
& c
, const wxXLocale
& loc
);
275 int WXDLLIMPEXP_BASE
wxIsdigit_l(const wxUniChar
& c
, const wxXLocale
& loc
);
276 int WXDLLIMPEXP_BASE
wxIsgraph_l(const wxUniChar
& c
, const wxXLocale
& loc
);
277 int WXDLLIMPEXP_BASE
wxIslower_l(const wxUniChar
& c
, const wxXLocale
& loc
);
278 int WXDLLIMPEXP_BASE
wxIsprint_l(const wxUniChar
& c
, const wxXLocale
& loc
);
279 int WXDLLIMPEXP_BASE
wxIspunct_l(const wxUniChar
& c
, const wxXLocale
& loc
);
280 int WXDLLIMPEXP_BASE
wxIsspace_l(const wxUniChar
& c
, const wxXLocale
& loc
);
281 int WXDLLIMPEXP_BASE
wxIsupper_l(const wxUniChar
& c
, const wxXLocale
& loc
);
282 int WXDLLIMPEXP_BASE
wxIsxdigit_l(const wxUniChar
& c
, const wxXLocale
& loc
);
283 int WXDLLIMPEXP_BASE
wxTolower_l(const wxUniChar
& c
, const wxXLocale
& loc
);
284 int WXDLLIMPEXP_BASE
wxToupper_l(const wxUniChar
& c
, const wxXLocale
& loc
);
285 #endif // wxHAS_XLOCALE_SUPPORT/!wxHAS_XLOCALE_SUPPORT
287 #endif // wxUSE_XLOCALE
289 #endif // _WX_XLOCALE_H_