1 //////////////////////////////////////////////////////////////////////////////
3 // Purpose: Header to provide some xlocale wrappers
4 // Author: Brian Vanderburg II, Vadim Zeitlin
6 // Copyright: (c) 2008 Brian Vanderburg II
7 // 2008 Vadim Zeitlin <vadim@wxwidgets.org>
8 // Licence: wxWindows licence
9 ///////////////////////////////////////////////////////////////////////////////
12 This header defines portable wrappers around xlocale foo_l() functions or
13 their MSVC proprietary _foo_l() equivalents when they are available and
14 implements these functions for the "C" locale [only] if they are not. This
15 allows the program running under the default user locale to still use "C"
16 locale for operations such as reading data from files where they are stored
17 using decimal point &c.
19 TODO: Currently only the character classification and transformation
20 functions and number <-> string functions, are implemented,
22 - formatted IO: scanf_l(), printf_l() &c
23 - time: strftime_l(), strptime_l()
26 #ifndef _WX_XLOCALE_H_
27 #define _WX_XLOCALE_H_
29 #include "wx/defs.h" // wxUSE_XLOCALE
33 #include "wx/crt.h" // Includes wx/chartype.h, wx/wxcrt.h(wx/string.h)
34 #include "wx/intl.h" // wxLanguage
36 // The platform-specific locale type
37 // If wxXLocale_t is not defined, then only "C" locale support is provided
38 #ifdef wxHAS_XLOCALE_SUPPORT
39 #if wxCHECK_VISUALC_VERSION(8) && !defined(__WXWINCE__)
40 typedef _locale_t wxXLocale_t
;
41 #define wxXLOCALE_IDENT(name) _ ## name
42 #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
; }
99 bool operator== (const wxXLocale
& loc
) const
100 { return m_locale
== loc
.m_locale
; }
103 // Special ctor for the "C" locale, it's only used internally as the user
104 // code is supposed to use GetCLocale()
105 wxXLocale(struct wxXLocaleCTag
* WXUNUSED(dummy
)) { Init("C"); }
107 // Create from the given language string (called from ctors)
108 void Init(const char *loc
);
110 // Free the locale if it's non-NULL
114 // The corresponding locale handle, NULL if invalid
115 wxXLocale_t m_locale
;
118 // POSIX xlocale API provides a duplocale() function but MSVC locale API
119 // doesn't give us any means to copy a _locale_t object so we reduce the
120 // functionality to least common denominator here -- it shouldn't be a
121 // problem as copying the locale objects shouldn't be often needed
122 wxDECLARE_NO_COPY_CLASS(wxXLocale
);
125 #else // !wxHAS_XLOCALE_SUPPORT
127 // Skeleton version supporting only the "C" locale for the systems without
129 class WXDLLIMPEXP_BASE wxXLocale
132 // Construct an uninitialized locale
133 wxXLocale() { m_isC
= false; }
135 // Construct from a symbolic language constant: unless the language is
136 // wxLANGUAGE_ENGLISH_US (which we suppose to be the same as "C" locale)
137 // the object will be invalid
138 wxXLocale(wxLanguage lang
)
140 m_isC
= lang
== wxLANGUAGE_ENGLISH_US
;
143 // Construct from the given language string: unless the string is "C" or
144 // "POSIX" the object will be invalid
145 wxXLocale(const char *loc
)
147 m_isC
= loc
&& (strcmp(loc
, "C") == 0 || strcmp(loc
, "POSIX") == 0);
150 // Default copy ctor, assignment operator and dtor are ok (or would be if
151 // we didn't use DECLARE_NO_COPY_CLASS() for consistency with the xlocale
155 // Get the global "C" locale object
156 static wxXLocale
& GetCLocale();
158 // Check if the object represents a valid locale (notice that without
159 // wxHAS_XLOCALE_SUPPORT the only valid locale is the "C" one)
160 bool IsOk() const { return m_isC
; }
163 // Special ctor for the "C" locale, it's only used internally as the user
164 // code is supposed to use GetCLocale()
165 wxXLocale(struct wxXLocaleCTag
* WXUNUSED(dummy
)) { m_isC
= true; }
167 // Without xlocale support this class can only represent "C" locale, if
168 // this is false the object is invalid
172 // although it's not a problem to copy the objects of this class, we use
173 // this macro in this implementation for consistency with the xlocale-based
174 // one which can't be copied when using MSVC locale API
175 wxDECLARE_NO_COPY_CLASS(wxXLocale
);
178 #endif // wxHAS_XLOCALE_SUPPORT/!wxHAS_XLOCALE_SUPPORT
181 // A shorter synonym for the most commonly used locale object
182 #define wxCLocale (wxXLocale::GetCLocale())
183 extern WXDLLIMPEXP_DATA_BASE(wxXLocale
) wxNullXLocale
;
185 // Wrappers for various functions:
186 #ifdef wxHAS_XLOCALE_SUPPORT
189 #define wxCRT_Isalnum_lA wxXLOCALE_IDENT(isalnum_l)
190 #define wxCRT_Isalpha_lA wxXLOCALE_IDENT(isalpha_l)
191 #define wxCRT_Iscntrl_lA wxXLOCALE_IDENT(iscntrl_l)
192 #define wxCRT_Isdigit_lA wxXLOCALE_IDENT(isdigit_l)
193 #define wxCRT_Isgraph_lA wxXLOCALE_IDENT(isgraph_l)
194 #define wxCRT_Islower_lA wxXLOCALE_IDENT(islower_l)
195 #define wxCRT_Isprint_lA wxXLOCALE_IDENT(isprint_l)
196 #define wxCRT_Ispunct_lA wxXLOCALE_IDENT(ispunct_l)
197 #define wxCRT_Isspace_lA wxXLOCALE_IDENT(isspace_l)
198 #define wxCRT_Isupper_lA wxXLOCALE_IDENT(isupper_l)
199 #define wxCRT_Isxdigit_lA wxXLOCALE_IDENT(isxdigit_l)
200 #define wxCRT_Tolower_lA wxXLOCALE_IDENT(tolower_l)
201 #define wxCRT_Toupper_lA wxXLOCALE_IDENT(toupper_l)
203 inline int wxIsalnum_l(char c
, const wxXLocale
& loc
)
204 { return wxCRT_Isalnum_lA(static_cast<unsigned char>(c
), loc
.Get()); }
205 inline int wxIsalpha_l(char c
, const wxXLocale
& loc
)
206 { return wxCRT_Isalpha_lA(static_cast<unsigned char>(c
), loc
.Get()); }
207 inline int wxIscntrl_l(char c
, const wxXLocale
& loc
)
208 { return wxCRT_Iscntrl_lA(static_cast<unsigned char>(c
), loc
.Get()); }
209 inline int wxIsdigit_l(char c
, const wxXLocale
& loc
)
210 { return wxCRT_Isdigit_lA(static_cast<unsigned char>(c
), loc
.Get()); }
211 inline int wxIsgraph_l(char c
, const wxXLocale
& loc
)
212 { return wxCRT_Isgraph_lA(static_cast<unsigned char>(c
), loc
.Get()); }
213 inline int wxIslower_l(char c
, const wxXLocale
& loc
)
214 { return wxCRT_Islower_lA(static_cast<unsigned char>(c
), loc
.Get()); }
215 inline int wxIsprint_l(char c
, const wxXLocale
& loc
)
216 { return wxCRT_Isprint_lA(static_cast<unsigned char>(c
), loc
.Get()); }
217 inline int wxIspunct_l(char c
, const wxXLocale
& loc
)
218 { return wxCRT_Ispunct_lA(static_cast<unsigned char>(c
), loc
.Get()); }
219 inline int wxIsspace_l(char c
, const wxXLocale
& loc
)
220 { return wxCRT_Isspace_lA(static_cast<unsigned char>(c
), loc
.Get()); }
221 inline int wxIsupper_l(char c
, const wxXLocale
& loc
)
222 { return wxCRT_Isupper_lA(static_cast<unsigned char>(c
), loc
.Get()); }
223 inline int wxIsxdigit_l(char c
, const wxXLocale
& loc
)
224 { return wxCRT_Isxdigit_lA(static_cast<unsigned char>(c
), loc
.Get()); }
225 inline int wxTolower_l(char c
, const wxXLocale
& loc
)
226 { return wxCRT_Tolower_lA(static_cast<unsigned char>(c
), loc
.Get()); }
227 inline int wxToupper_l(char c
, const wxXLocale
& loc
)
228 { return wxCRT_Toupper_lA(static_cast<unsigned char>(c
), loc
.Get()); }
231 // stdlib functions for numeric <-> string conversion
232 // NOTE: GNU libc does not have ato[fil]_l functions;
233 // MSVC++8 does not have _strto[u]ll_l functions;
234 // thus we take the minimal set of functions provided in both environments:
236 #define wxCRT_Strtod_lA wxXLOCALE_IDENT(strtod_l)
237 #define wxCRT_Strtol_lA wxXLOCALE_IDENT(strtol_l)
238 #define wxCRT_Strtoul_lA wxXLOCALE_IDENT(strtoul_l)
240 inline double wxStrtod_lA(const char *c
, char **endptr
, const wxXLocale
& loc
)
241 { return wxCRT_Strtod_lA(c
, endptr
, loc
.Get()); }
242 inline long wxStrtol_lA(const char *c
, char **endptr
, int base
, const wxXLocale
& loc
)
243 { return wxCRT_Strtol_lA(c
, endptr
, base
, loc
.Get()); }
244 inline unsigned long wxStrtoul_lA(const char *c
, char **endptr
, int base
, const wxXLocale
& loc
)
245 { return wxCRT_Strtoul_lA(c
, endptr
, base
, loc
.Get()); }
250 #define wxCRT_Isalnum_lW wxXLOCALE_IDENT(iswalnum_l)
251 #define wxCRT_Isalpha_lW wxXLOCALE_IDENT(iswalpha_l)
252 #define wxCRT_Iscntrl_lW wxXLOCALE_IDENT(iswcntrl_l)
253 #define wxCRT_Isdigit_lW wxXLOCALE_IDENT(iswdigit_l)
254 #define wxCRT_Isgraph_lW wxXLOCALE_IDENT(iswgraph_l)
255 #define wxCRT_Islower_lW wxXLOCALE_IDENT(iswlower_l)
256 #define wxCRT_Isprint_lW wxXLOCALE_IDENT(iswprint_l)
257 #define wxCRT_Ispunct_lW wxXLOCALE_IDENT(iswpunct_l)
258 #define wxCRT_Isspace_lW wxXLOCALE_IDENT(iswspace_l)
259 #define wxCRT_Isupper_lW wxXLOCALE_IDENT(iswupper_l)
260 #define wxCRT_Isxdigit_lW wxXLOCALE_IDENT(iswxdigit_l)
261 #define wxCRT_Tolower_lW wxXLOCALE_IDENT(towlower_l)
262 #define wxCRT_Toupper_lW wxXLOCALE_IDENT(towupper_l)
264 inline int wxIsalnum_l(wchar_t c
, const wxXLocale
& loc
)
265 { return wxCRT_Isalnum_lW(c
, loc
.Get()); }
266 inline int wxIsalpha_l(wchar_t c
, const wxXLocale
& loc
)
267 { return wxCRT_Isalpha_lW(c
, loc
.Get()); }
268 inline int wxIscntrl_l(wchar_t c
, const wxXLocale
& loc
)
269 { return wxCRT_Iscntrl_lW(c
, loc
.Get()); }
270 inline int wxIsdigit_l(wchar_t c
, const wxXLocale
& loc
)
271 { return wxCRT_Isdigit_lW(c
, loc
.Get()); }
272 inline int wxIsgraph_l(wchar_t c
, const wxXLocale
& loc
)
273 { return wxCRT_Isgraph_lW(c
, loc
.Get()); }
274 inline int wxIslower_l(wchar_t c
, const wxXLocale
& loc
)
275 { return wxCRT_Islower_lW(c
, loc
.Get()); }
276 inline int wxIsprint_l(wchar_t c
, const wxXLocale
& loc
)
277 { return wxCRT_Isprint_lW(c
, loc
.Get()); }
278 inline int wxIspunct_l(wchar_t c
, const wxXLocale
& loc
)
279 { return wxCRT_Ispunct_lW(c
, loc
.Get()); }
280 inline int wxIsspace_l(wchar_t c
, const wxXLocale
& loc
)
281 { return wxCRT_Isspace_lW(c
, loc
.Get()); }
282 inline int wxIsupper_l(wchar_t c
, const wxXLocale
& loc
)
283 { return wxCRT_Isupper_lW(c
, loc
.Get()); }
284 inline int wxIsxdigit_l(wchar_t c
, const wxXLocale
& loc
)
285 { return wxCRT_Isxdigit_lW(c
, loc
.Get()); }
286 inline wchar_t wxTolower_l(wchar_t c
, const wxXLocale
& loc
)
287 { return wxCRT_Tolower_lW(c
, loc
.Get()); }
288 inline wchar_t wxToupper_l(wchar_t c
, const wxXLocale
& loc
)
289 { return wxCRT_Toupper_lW(c
, loc
.Get()); }
292 // stdlib functions for numeric <-> string conversion
293 // (see notes above about missing functions)
294 #define wxCRT_Strtod_lW wxXLOCALE_IDENT(wcstod_l)
295 #define wxCRT_Strtol_lW wxXLOCALE_IDENT(wcstol_l)
296 #define wxCRT_Strtoul_lW wxXLOCALE_IDENT(wcstoul_l)
298 inline double wxStrtod_l(const wchar_t *c
, wchar_t **endptr
, const wxXLocale
& loc
)
299 { return wxCRT_Strtod_lW(c
, endptr
, loc
.Get()); }
300 inline long wxStrtol_l(const wchar_t *c
, wchar_t **endptr
, int base
, const wxXLocale
& loc
)
301 { return wxCRT_Strtol_lW(c
, endptr
, base
, loc
.Get()); }
302 inline unsigned long wxStrtoul_l(const wchar_t *c
, wchar_t **endptr
, int base
, const wxXLocale
& loc
)
303 { return wxCRT_Strtoul_lW(c
, endptr
, base
, loc
.Get()); }
304 #else // !wxUSE_UNICODE
305 inline double wxStrtod_l(const char *c
, char **endptr
, const wxXLocale
& loc
)
306 { return wxCRT_Strtod_lA(c
, endptr
, loc
.Get()); }
307 inline long wxStrtol_l(const char *c
, char **endptr
, int base
, const wxXLocale
& loc
)
308 { return wxCRT_Strtol_lA(c
, endptr
, base
, loc
.Get()); }
309 inline unsigned long wxStrtoul_l(const char *c
, char **endptr
, int base
, const wxXLocale
& loc
)
310 { return wxCRT_Strtoul_lA(c
, endptr
, base
, loc
.Get()); }
311 #endif // wxUSE_UNICODE
312 #else // !wxHAS_XLOCALE_SUPPORT
314 int WXDLLIMPEXP_BASE
wxIsalnum_l(const wxUniChar
& c
, const wxXLocale
& loc
);
315 int WXDLLIMPEXP_BASE
wxIsalpha_l(const wxUniChar
& c
, const wxXLocale
& loc
);
316 int WXDLLIMPEXP_BASE
wxIscntrl_l(const wxUniChar
& c
, const wxXLocale
& loc
);
317 int WXDLLIMPEXP_BASE
wxIsdigit_l(const wxUniChar
& c
, const wxXLocale
& loc
);
318 int WXDLLIMPEXP_BASE
wxIsgraph_l(const wxUniChar
& c
, const wxXLocale
& loc
);
319 int WXDLLIMPEXP_BASE
wxIslower_l(const wxUniChar
& c
, const wxXLocale
& loc
);
320 int WXDLLIMPEXP_BASE
wxIsprint_l(const wxUniChar
& c
, const wxXLocale
& loc
);
321 int WXDLLIMPEXP_BASE
wxIspunct_l(const wxUniChar
& c
, const wxXLocale
& loc
);
322 int WXDLLIMPEXP_BASE
wxIsspace_l(const wxUniChar
& c
, const wxXLocale
& loc
);
323 int WXDLLIMPEXP_BASE
wxIsupper_l(const wxUniChar
& c
, const wxXLocale
& loc
);
324 int WXDLLIMPEXP_BASE
wxIsxdigit_l(const wxUniChar
& c
, const wxXLocale
& loc
);
325 int WXDLLIMPEXP_BASE
wxTolower_l(const wxUniChar
& c
, const wxXLocale
& loc
);
326 int WXDLLIMPEXP_BASE
wxToupper_l(const wxUniChar
& c
, const wxXLocale
& loc
);
329 double WXDLLIMPEXP_BASE
wxStrtod_l(const wchar_t* str
, wchar_t **endptr
, const wxXLocale
& loc
);
330 double WXDLLIMPEXP_BASE
wxStrtod_l(const char* str
, char **endptr
, const wxXLocale
& loc
);
331 long WXDLLIMPEXP_BASE
wxStrtol_l(const wchar_t* str
, wchar_t **endptr
, int base
, const wxXLocale
& loc
);
332 long WXDLLIMPEXP_BASE
wxStrtol_l(const char* str
, char **endptr
, int base
, const wxXLocale
& loc
);
333 unsigned long WXDLLIMPEXP_BASE
wxStrtoul_l(const wchar_t* str
, wchar_t **endptr
, int base
, const wxXLocale
& loc
);
334 unsigned long WXDLLIMPEXP_BASE
wxStrtoul_l(const char* str
, char **endptr
, int base
, const wxXLocale
& loc
);
336 #endif // wxHAS_XLOCALE_SUPPORT/!wxHAS_XLOCALE_SUPPORT
338 #endif // wxUSE_XLOCALE
340 #endif // _WX_XLOCALE_H_