Remove all lines containing cvs/svn "$Id$" keyword.
[wxWidgets.git] / include / wx / xlocale.h
1 //////////////////////////////////////////////////////////////////////////////
2 // Name: wx/xlocale.h
3 // Purpose: Header to provide some xlocale wrappers
4 // Author: Brian Vanderburg II, Vadim Zeitlin
5 // Created: 2008-01-07
6 // Copyright: (c) 2008 Brian Vanderburg II
7 // 2008 Vadim Zeitlin <vadim@wxwidgets.org>
8 // Licence: wxWindows licence
9 ///////////////////////////////////////////////////////////////////////////////
10
11 /*
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.
18
19 TODO: Currently only the character classification and transformation
20 functions and number <-> string functions, are implemented,
21 we also need at least
22 - formatted IO: scanf_l(), printf_l() &c
23 - time: strftime_l(), strptime_l()
24 */
25
26 #ifndef _WX_XLOCALE_H_
27 #define _WX_XLOCALE_H_
28
29 #include "wx/defs.h" // wxUSE_XLOCALE
30
31 #if wxUSE_XLOCALE
32
33 #include "wx/crt.h" // Includes wx/chartype.h, wx/wxcrt.h(wx/string.h)
34 #include "wx/intl.h" // wxLanguage
35
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)
43 #include <locale.h>
44 #include <xlocale.h>
45 #include <ctype.h>
46 #include <stdlib.h>
47
48 #if wxUSE_UNICODE
49 #include <wctype.h>
50 #endif
51
52 // Locale type and identifier name
53 typedef locale_t wxXLocale_t;
54
55 #define wxXLOCALE_IDENT(name) name
56 #else
57 #error "Unknown xlocale support"
58 #endif
59 #endif // wxHAS_XLOCALE_SUPPORT
60
61
62 // wxXLocale is a wrapper around the native type representing a locale.
63 //
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
72
73 class WXDLLIMPEXP_BASE wxXLocale
74 {
75 public:
76 // Construct an uninitialized locale
77 wxXLocale() { m_locale = NULL; }
78
79 // Construct from a symbolic language constant
80 wxXLocale(wxLanguage lang);
81
82 // Construct from the given language string
83 wxXLocale(const char *loc) { Init(loc); }
84
85 // Destroy the locale
86 ~wxXLocale() { Free(); }
87
88
89 // Get the global "C" locale object
90 static wxXLocale& GetCLocale();
91
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; }
95
96 // Get the type
97 wxXLocale_t Get() const { return m_locale; }
98
99 bool operator== (const wxXLocale& loc) const
100 { return m_locale == loc.m_locale; }
101
102 private:
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"); }
106
107 // Create from the given language string (called from ctors)
108 void Init(const char *loc);
109
110 // Free the locale if it's non-NULL
111 void Free();
112
113
114 // The corresponding locale handle, NULL if invalid
115 wxXLocale_t m_locale;
116
117
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);
123 };
124
125 #else // !wxHAS_XLOCALE_SUPPORT
126
127 // Skeleton version supporting only the "C" locale for the systems without
128 // xlocale support
129 class WXDLLIMPEXP_BASE wxXLocale
130 {
131 public:
132 // Construct an uninitialized locale
133 wxXLocale() { m_isC = false; }
134
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)
139 {
140 m_isC = lang == wxLANGUAGE_ENGLISH_US;
141 }
142
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)
146 {
147 m_isC = loc && (strcmp(loc, "C") == 0 || strcmp(loc, "POSIX") == 0);
148 }
149
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
152 // version)
153
154
155 // Get the global "C" locale object
156 static wxXLocale& GetCLocale();
157
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; }
161
162 private:
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; }
166
167 // Without xlocale support this class can only represent "C" locale, if
168 // this is false the object is invalid
169 bool m_isC;
170
171
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);
176 };
177
178 #endif // wxHAS_XLOCALE_SUPPORT/!wxHAS_XLOCALE_SUPPORT
179
180
181 // A shorter synonym for the most commonly used locale object
182 #define wxCLocale (wxXLocale::GetCLocale())
183 extern WXDLLIMPEXP_DATA_BASE(wxXLocale) wxNullXLocale;
184
185 // Wrappers for various functions:
186 #ifdef wxHAS_XLOCALE_SUPPORT
187
188 // ctype functions
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)
202
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()); }
229
230
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:
235
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)
239
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()); }
246
247 #if wxUSE_UNICODE
248
249 // ctype functions
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)
263
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()); }
290
291
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)
297
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
313 // ctype functions
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);
327
328 // stdlib functions
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);
335
336 #endif // wxHAS_XLOCALE_SUPPORT/!wxHAS_XLOCALE_SUPPORT
337
338 #endif // wxUSE_XLOCALE
339
340 #endif // _WX_XLOCALE_H_