/src/wxwidgets/include/wx/xlocale.h
Line | Count | Source |
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 defined(__VISUALC__) |
40 | | typedef _locale_t wxXLocale_t; |
41 | | #define wxXLOCALE_IDENT(name) _ ## name |
42 | | #elif defined(HAVE_LOCALE_T) |
43 | | // Some systems (notably macOS) require including a separate header for |
44 | | // locale_t and related functions. |
45 | | #ifdef HAVE_XLOCALE_H |
46 | | #include <xlocale.h> |
47 | | #endif |
48 | | #include <locale.h> |
49 | | #include <ctype.h> |
50 | | #include <stdlib.h> |
51 | | #include <wctype.h> |
52 | | |
53 | | // Locale type and identifier name |
54 | | typedef locale_t wxXLocale_t; |
55 | | |
56 | 0 | #define wxXLOCALE_IDENT(name) name |
57 | | #else |
58 | | #error "Unknown xlocale support" |
59 | | #endif |
60 | | #endif // wxHAS_XLOCALE_SUPPORT |
61 | | |
62 | | |
63 | | // wxXLocale is a wrapper around the native type representing a locale. |
64 | | // |
65 | | // It is not to be confused with wxLocale, which handles actually changing the |
66 | | // locale, loading message catalogs, etc. This just stores a locale value. |
67 | | // The similarity of names is unfortunate, but there doesn't seem to be any |
68 | | // better alternative right now. Perhaps by wxWidgets 4.0 better naming could |
69 | | // be used, or this class could become wxLocale (a wrapper for the value), and |
70 | | // some other class could be used to load the language catalogs or something |
71 | | // that would be clearer |
72 | | #ifdef wxHAS_XLOCALE_SUPPORT |
73 | | |
74 | | class WXDLLIMPEXP_BASE wxXLocale |
75 | | { |
76 | | public: |
77 | | // Construct an uninitialized locale |
78 | 2 | wxXLocale() { m_locale = nullptr; } |
79 | | |
80 | | #if wxUSE_INTL |
81 | | // Construct from a symbolic language constant |
82 | | wxXLocale(wxLanguage lang); |
83 | | #endif |
84 | | |
85 | | // Construct from the given language string |
86 | 0 | wxXLocale(const char *loc) { Init(loc); } |
87 | | |
88 | | // Destroy the locale |
89 | 0 | ~wxXLocale() { Free(); } |
90 | | |
91 | | |
92 | | // Get the global "C" locale object |
93 | | static wxXLocale& GetCLocale(); |
94 | | |
95 | | // Check if the object represents a valid locale (notice that without |
96 | | // wxHAS_XLOCALE_SUPPORT the only valid locale is the "C" one) |
97 | 0 | bool IsOk() const { return m_locale != nullptr; } |
98 | | |
99 | | // Get the type |
100 | 0 | wxXLocale_t Get() const { return m_locale; } |
101 | | |
102 | | bool operator== (const wxXLocale& loc) const |
103 | 0 | { return m_locale == loc.m_locale; } |
104 | | |
105 | | private: |
106 | | // Special ctor for the "C" locale, it's only used internally as the user |
107 | | // code is supposed to use GetCLocale() |
108 | 0 | wxXLocale(struct wxXLocaleCTag * WXUNUSED(dummy)) { Init("C"); } |
109 | | |
110 | | // Create from the given language string (called from ctors) |
111 | | void Init(const char *loc); |
112 | | |
113 | | // Free the locale if it's non-null |
114 | | void Free(); |
115 | | |
116 | | |
117 | | // The corresponding locale handle, nullptr if invalid |
118 | | wxXLocale_t m_locale; |
119 | | |
120 | | |
121 | | // POSIX xlocale API provides a duplocale() function but MSVC locale API |
122 | | // doesn't give us any means to copy a _locale_t object so we reduce the |
123 | | // functionality to least common denominator here -- it shouldn't be a |
124 | | // problem as copying the locale objects shouldn't be often needed |
125 | | wxDECLARE_NO_COPY_CLASS(wxXLocale); |
126 | | }; |
127 | | |
128 | | #else // !wxHAS_XLOCALE_SUPPORT |
129 | | |
130 | | // Skeleton version supporting only the "C" locale for the systems without |
131 | | // xlocale support |
132 | | class WXDLLIMPEXP_BASE wxXLocale |
133 | | { |
134 | | public: |
135 | | // Construct an uninitialized locale |
136 | | wxXLocale() { m_isC = false; } |
137 | | |
138 | | // Construct from a symbolic language constant: unless the language is |
139 | | // wxLANGUAGE_ENGLISH_US (which we assume to be the same as "C" locale) |
140 | | // the object will be invalid |
141 | | wxXLocale(wxLanguage lang) |
142 | | { |
143 | | m_isC = lang == wxLANGUAGE_ENGLISH_US; |
144 | | } |
145 | | |
146 | | // Construct from the given language string: unless the string is "C" or |
147 | | // "POSIX" the object will be invalid |
148 | | wxXLocale(const char *loc) |
149 | | { |
150 | | m_isC = loc && (strcmp(loc, "C") == 0 || strcmp(loc, "POSIX") == 0); |
151 | | } |
152 | | |
153 | | // Default copy ctor, assignment operator and dtor are ok (or would be if |
154 | | // we didn't use wxDECLARE_NO_COPY_CLASS() for consistency with the |
155 | | // xlocale version) |
156 | | |
157 | | |
158 | | // Get the global "C" locale object |
159 | | static wxXLocale& GetCLocale(); |
160 | | |
161 | | // Check if the object represents a valid locale (notice that without |
162 | | // wxHAS_XLOCALE_SUPPORT the only valid locale is the "C" one) |
163 | | bool IsOk() const { return m_isC; } |
164 | | |
165 | | private: |
166 | | // Special ctor for the "C" locale, it's only used internally as the user |
167 | | // code is supposed to use GetCLocale() |
168 | | wxXLocale(struct wxXLocaleCTag * WXUNUSED(dummy)) { m_isC = true; } |
169 | | |
170 | | // Without xlocale support this class can only represent "C" locale, if |
171 | | // this is false the object is invalid |
172 | | bool m_isC; |
173 | | |
174 | | |
175 | | // although it's not a problem to copy the objects of this class, we use |
176 | | // this macro in this implementation for consistency with the xlocale-based |
177 | | // one which can't be copied when using MSVC locale API |
178 | | wxDECLARE_NO_COPY_CLASS(wxXLocale); |
179 | | }; |
180 | | |
181 | | #endif // wxHAS_XLOCALE_SUPPORT/!wxHAS_XLOCALE_SUPPORT |
182 | | |
183 | | |
184 | | // A shorter synonym for the most commonly used locale object |
185 | 0 | #define wxCLocale (wxXLocale::GetCLocale()) |
186 | | extern WXDLLIMPEXP_DATA_BASE(wxXLocale) wxNullXLocale; |
187 | | |
188 | | // Wrappers for various functions: |
189 | | #ifdef wxHAS_XLOCALE_SUPPORT |
190 | | |
191 | | // ctype functions |
192 | | #define wxCRT_Isalnum_lA wxXLOCALE_IDENT(isalnum_l) |
193 | | #define wxCRT_Isalpha_lA wxXLOCALE_IDENT(isalpha_l) |
194 | | #define wxCRT_Iscntrl_lA wxXLOCALE_IDENT(iscntrl_l) |
195 | | #define wxCRT_Isdigit_lA wxXLOCALE_IDENT(isdigit_l) |
196 | | #define wxCRT_Isgraph_lA wxXLOCALE_IDENT(isgraph_l) |
197 | | #define wxCRT_Islower_lA wxXLOCALE_IDENT(islower_l) |
198 | | #define wxCRT_Isprint_lA wxXLOCALE_IDENT(isprint_l) |
199 | | #define wxCRT_Ispunct_lA wxXLOCALE_IDENT(ispunct_l) |
200 | | #define wxCRT_Isspace_lA wxXLOCALE_IDENT(isspace_l) |
201 | | #define wxCRT_Isupper_lA wxXLOCALE_IDENT(isupper_l) |
202 | | #define wxCRT_Isxdigit_lA wxXLOCALE_IDENT(isxdigit_l) |
203 | | #define wxCRT_Tolower_lA wxXLOCALE_IDENT(tolower_l) |
204 | | #define wxCRT_Toupper_lA wxXLOCALE_IDENT(toupper_l) |
205 | | |
206 | | inline int wxIsalnum_l(char c, const wxXLocale& loc) |
207 | 0 | { return wxCRT_Isalnum_lA(static_cast<unsigned char>(c), loc.Get()); } |
208 | | inline int wxIsalpha_l(char c, const wxXLocale& loc) |
209 | 0 | { return wxCRT_Isalpha_lA(static_cast<unsigned char>(c), loc.Get()); } |
210 | | inline int wxIscntrl_l(char c, const wxXLocale& loc) |
211 | 0 | { return wxCRT_Iscntrl_lA(static_cast<unsigned char>(c), loc.Get()); } |
212 | | inline int wxIsdigit_l(char c, const wxXLocale& loc) |
213 | 0 | { return wxCRT_Isdigit_lA(static_cast<unsigned char>(c), loc.Get()); } |
214 | | inline int wxIsgraph_l(char c, const wxXLocale& loc) |
215 | 0 | { return wxCRT_Isgraph_lA(static_cast<unsigned char>(c), loc.Get()); } |
216 | | inline int wxIslower_l(char c, const wxXLocale& loc) |
217 | 0 | { return wxCRT_Islower_lA(static_cast<unsigned char>(c), loc.Get()); } |
218 | | inline int wxIsprint_l(char c, const wxXLocale& loc) |
219 | 0 | { return wxCRT_Isprint_lA(static_cast<unsigned char>(c), loc.Get()); } |
220 | | inline int wxIspunct_l(char c, const wxXLocale& loc) |
221 | 0 | { return wxCRT_Ispunct_lA(static_cast<unsigned char>(c), loc.Get()); } |
222 | | inline int wxIsspace_l(char c, const wxXLocale& loc) |
223 | 0 | { return wxCRT_Isspace_lA(static_cast<unsigned char>(c), loc.Get()); } |
224 | | inline int wxIsupper_l(char c, const wxXLocale& loc) |
225 | 0 | { return wxCRT_Isupper_lA(static_cast<unsigned char>(c), loc.Get()); } |
226 | | inline int wxIsxdigit_l(char c, const wxXLocale& loc) |
227 | 0 | { return wxCRT_Isxdigit_lA(static_cast<unsigned char>(c), loc.Get()); } |
228 | | inline int wxTolower_l(char c, const wxXLocale& loc) |
229 | 0 | { return wxCRT_Tolower_lA(static_cast<unsigned char>(c), loc.Get()); } |
230 | | inline int wxToupper_l(char c, const wxXLocale& loc) |
231 | 0 | { return wxCRT_Toupper_lA(static_cast<unsigned char>(c), loc.Get()); } |
232 | | |
233 | | |
234 | | // stdlib functions for numeric <-> string conversion |
235 | | // NOTE: GNU libc does not have ato[fil]_l functions; |
236 | | // MSVC++8 does not have _strto[u]ll_l functions; |
237 | | // thus we take the minimal set of functions provided in both environments: |
238 | | |
239 | | #define wxCRT_Strtod_lA wxXLOCALE_IDENT(strtod_l) |
240 | | #define wxCRT_Strtol_lA wxXLOCALE_IDENT(strtol_l) |
241 | | #define wxCRT_Strtoul_lA wxXLOCALE_IDENT(strtoul_l) |
242 | | |
243 | | inline double wxStrtod_lA(const char *c, char **endptr, const wxXLocale& loc) |
244 | 0 | { return wxCRT_Strtod_lA(c, endptr, loc.Get()); } |
245 | | inline long wxStrtol_lA(const char *c, char **endptr, int base, const wxXLocale& loc) |
246 | 0 | { return wxCRT_Strtol_lA(c, endptr, base, loc.Get()); } |
247 | | inline unsigned long wxStrtoul_lA(const char *c, char **endptr, int base, const wxXLocale& loc) |
248 | 0 | { return wxCRT_Strtoul_lA(c, endptr, base, loc.Get()); } |
249 | | |
250 | | // ctype functions |
251 | | #define wxCRT_Isalnum_lW wxXLOCALE_IDENT(iswalnum_l) |
252 | | #define wxCRT_Isalpha_lW wxXLOCALE_IDENT(iswalpha_l) |
253 | | #define wxCRT_Iscntrl_lW wxXLOCALE_IDENT(iswcntrl_l) |
254 | | #define wxCRT_Isdigit_lW wxXLOCALE_IDENT(iswdigit_l) |
255 | | #define wxCRT_Isgraph_lW wxXLOCALE_IDENT(iswgraph_l) |
256 | | #define wxCRT_Islower_lW wxXLOCALE_IDENT(iswlower_l) |
257 | | #define wxCRT_Isprint_lW wxXLOCALE_IDENT(iswprint_l) |
258 | | #define wxCRT_Ispunct_lW wxXLOCALE_IDENT(iswpunct_l) |
259 | | #define wxCRT_Isspace_lW wxXLOCALE_IDENT(iswspace_l) |
260 | | #define wxCRT_Isupper_lW wxXLOCALE_IDENT(iswupper_l) |
261 | | #define wxCRT_Isxdigit_lW wxXLOCALE_IDENT(iswxdigit_l) |
262 | | #define wxCRT_Tolower_lW wxXLOCALE_IDENT(towlower_l) |
263 | | #define wxCRT_Toupper_lW wxXLOCALE_IDENT(towupper_l) |
264 | | |
265 | | inline int wxIsalnum_l(wchar_t c, const wxXLocale& loc) |
266 | 0 | { return wxCRT_Isalnum_lW(c, loc.Get()); } |
267 | | inline int wxIsalpha_l(wchar_t c, const wxXLocale& loc) |
268 | 0 | { return wxCRT_Isalpha_lW(c, loc.Get()); } |
269 | | inline int wxIscntrl_l(wchar_t c, const wxXLocale& loc) |
270 | 0 | { return wxCRT_Iscntrl_lW(c, loc.Get()); } |
271 | | inline int wxIsdigit_l(wchar_t c, const wxXLocale& loc) |
272 | 0 | { return wxCRT_Isdigit_lW(c, loc.Get()); } |
273 | | inline int wxIsgraph_l(wchar_t c, const wxXLocale& loc) |
274 | 0 | { return wxCRT_Isgraph_lW(c, loc.Get()); } |
275 | | inline int wxIslower_l(wchar_t c, const wxXLocale& loc) |
276 | 0 | { return wxCRT_Islower_lW(c, loc.Get()); } |
277 | | inline int wxIsprint_l(wchar_t c, const wxXLocale& loc) |
278 | 0 | { return wxCRT_Isprint_lW(c, loc.Get()); } |
279 | | inline int wxIspunct_l(wchar_t c, const wxXLocale& loc) |
280 | 0 | { return wxCRT_Ispunct_lW(c, loc.Get()); } |
281 | | inline int wxIsspace_l(wchar_t c, const wxXLocale& loc) |
282 | 0 | { return wxCRT_Isspace_lW(c, loc.Get()); } |
283 | | inline int wxIsupper_l(wchar_t c, const wxXLocale& loc) |
284 | 0 | { return wxCRT_Isupper_lW(c, loc.Get()); } |
285 | | inline int wxIsxdigit_l(wchar_t c, const wxXLocale& loc) |
286 | 0 | { return wxCRT_Isxdigit_lW(c, loc.Get()); } |
287 | | inline wchar_t wxTolower_l(wchar_t c, const wxXLocale& loc) |
288 | 0 | { return wxCRT_Tolower_lW(c, loc.Get()); } |
289 | | inline wchar_t wxToupper_l(wchar_t c, const wxXLocale& loc) |
290 | 0 | { return wxCRT_Toupper_lW(c, loc.Get()); } |
291 | | |
292 | | |
293 | | // stdlib functions for numeric <-> string conversion |
294 | | // (see notes above about missing functions) |
295 | 0 | #define wxCRT_Strtod_lW wxXLOCALE_IDENT(wcstod_l) |
296 | 0 | #define wxCRT_Strtol_lW wxXLOCALE_IDENT(wcstol_l) |
297 | 0 | #define wxCRT_Strtoul_lW wxXLOCALE_IDENT(wcstoul_l) |
298 | | |
299 | | inline double wxStrtod_l(const wchar_t *c, wchar_t **endptr, const wxXLocale& loc) |
300 | 0 | { return wxCRT_Strtod_lW(c, endptr, loc.Get()); } |
301 | | inline long wxStrtol_l(const wchar_t *c, wchar_t **endptr, int base, const wxXLocale& loc) |
302 | 0 | { return wxCRT_Strtol_lW(c, endptr, base, loc.Get()); } |
303 | | inline unsigned long wxStrtoul_l(const wchar_t *c, wchar_t **endptr, int base, const wxXLocale& loc) |
304 | 0 | { return wxCRT_Strtoul_lW(c, endptr, base, loc.Get()); } |
305 | | #else // !wxHAS_XLOCALE_SUPPORT |
306 | | // ctype functions |
307 | | int WXDLLIMPEXP_BASE wxIsalnum_l(const wxUniChar& c, const wxXLocale& loc); |
308 | | int WXDLLIMPEXP_BASE wxIsalpha_l(const wxUniChar& c, const wxXLocale& loc); |
309 | | int WXDLLIMPEXP_BASE wxIscntrl_l(const wxUniChar& c, const wxXLocale& loc); |
310 | | int WXDLLIMPEXP_BASE wxIsdigit_l(const wxUniChar& c, const wxXLocale& loc); |
311 | | int WXDLLIMPEXP_BASE wxIsgraph_l(const wxUniChar& c, const wxXLocale& loc); |
312 | | int WXDLLIMPEXP_BASE wxIslower_l(const wxUniChar& c, const wxXLocale& loc); |
313 | | int WXDLLIMPEXP_BASE wxIsprint_l(const wxUniChar& c, const wxXLocale& loc); |
314 | | int WXDLLIMPEXP_BASE wxIspunct_l(const wxUniChar& c, const wxXLocale& loc); |
315 | | int WXDLLIMPEXP_BASE wxIsspace_l(const wxUniChar& c, const wxXLocale& loc); |
316 | | int WXDLLIMPEXP_BASE wxIsupper_l(const wxUniChar& c, const wxXLocale& loc); |
317 | | int WXDLLIMPEXP_BASE wxIsxdigit_l(const wxUniChar& c, const wxXLocale& loc); |
318 | | int WXDLLIMPEXP_BASE wxTolower_l(const wxUniChar& c, const wxXLocale& loc); |
319 | | int WXDLLIMPEXP_BASE wxToupper_l(const wxUniChar& c, const wxXLocale& loc); |
320 | | |
321 | | // stdlib functions |
322 | | double WXDLLIMPEXP_BASE wxStrtod_l(const wchar_t* str, wchar_t **endptr, const wxXLocale& loc); |
323 | | double WXDLLIMPEXP_BASE wxStrtod_l(const char* str, char **endptr, const wxXLocale& loc); |
324 | | long WXDLLIMPEXP_BASE wxStrtol_l(const wchar_t* str, wchar_t **endptr, int base, const wxXLocale& loc); |
325 | | long WXDLLIMPEXP_BASE wxStrtol_l(const char* str, char **endptr, int base, const wxXLocale& loc); |
326 | | unsigned long WXDLLIMPEXP_BASE wxStrtoul_l(const wchar_t* str, wchar_t **endptr, int base, const wxXLocale& loc); |
327 | | unsigned long WXDLLIMPEXP_BASE wxStrtoul_l(const char* str, char **endptr, int base, const wxXLocale& loc); |
328 | | |
329 | | #endif // wxHAS_XLOCALE_SUPPORT/!wxHAS_XLOCALE_SUPPORT |
330 | | |
331 | | #endif // wxUSE_XLOCALE |
332 | | |
333 | | #endif // _WX_XLOCALE_H_ |