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 wxXLocale()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 wxXLocale(const char * loc)83 wxXLocale(const char *loc) { Init(loc); } 84 85 // Destroy the locale ~wxXLocale()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) IsOk()94 bool IsOk() const { return m_locale != NULL; } 95 96 // Get the type Get()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() wxXLocale(struct wxXLocaleCTag * WXUNUSED (dummy))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 wxXLocale()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 wxXLocale(wxLanguage lang)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 wxXLocale(const char * loc)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) IsOk()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() wxXLocale(struct wxXLocaleCTag * WXUNUSED (dummy))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 wxIsalnum_l(char c,const wxXLocale & loc)203 inline int wxIsalnum_l(char c, const wxXLocale& loc) 204 { return wxCRT_Isalnum_lA(static_cast<unsigned char>(c), loc.Get()); } wxIsalpha_l(char c,const wxXLocale & loc)205 inline int wxIsalpha_l(char c, const wxXLocale& loc) 206 { return wxCRT_Isalpha_lA(static_cast<unsigned char>(c), loc.Get()); } wxIscntrl_l(char c,const wxXLocale & loc)207 inline int wxIscntrl_l(char c, const wxXLocale& loc) 208 { return wxCRT_Iscntrl_lA(static_cast<unsigned char>(c), loc.Get()); } wxIsdigit_l(char c,const wxXLocale & loc)209 inline int wxIsdigit_l(char c, const wxXLocale& loc) 210 { return wxCRT_Isdigit_lA(static_cast<unsigned char>(c), loc.Get()); } wxIsgraph_l(char c,const wxXLocale & loc)211 inline int wxIsgraph_l(char c, const wxXLocale& loc) 212 { return wxCRT_Isgraph_lA(static_cast<unsigned char>(c), loc.Get()); } wxIslower_l(char c,const wxXLocale & loc)213 inline int wxIslower_l(char c, const wxXLocale& loc) 214 { return wxCRT_Islower_lA(static_cast<unsigned char>(c), loc.Get()); } wxIsprint_l(char c,const wxXLocale & loc)215 inline int wxIsprint_l(char c, const wxXLocale& loc) 216 { return wxCRT_Isprint_lA(static_cast<unsigned char>(c), loc.Get()); } wxIspunct_l(char c,const wxXLocale & loc)217 inline int wxIspunct_l(char c, const wxXLocale& loc) 218 { return wxCRT_Ispunct_lA(static_cast<unsigned char>(c), loc.Get()); } wxIsspace_l(char c,const wxXLocale & loc)219 inline int wxIsspace_l(char c, const wxXLocale& loc) 220 { return wxCRT_Isspace_lA(static_cast<unsigned char>(c), loc.Get()); } wxIsupper_l(char c,const wxXLocale & loc)221 inline int wxIsupper_l(char c, const wxXLocale& loc) 222 { return wxCRT_Isupper_lA(static_cast<unsigned char>(c), loc.Get()); } wxIsxdigit_l(char c,const wxXLocale & loc)223 inline int wxIsxdigit_l(char c, const wxXLocale& loc) 224 { return wxCRT_Isxdigit_lA(static_cast<unsigned char>(c), loc.Get()); } wxTolower_l(char c,const wxXLocale & loc)225 inline int wxTolower_l(char c, const wxXLocale& loc) 226 { return wxCRT_Tolower_lA(static_cast<unsigned char>(c), loc.Get()); } wxToupper_l(char c,const wxXLocale & loc)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 wxStrtod_lA(const char * c,char ** endptr,const wxXLocale & loc)240 inline double wxStrtod_lA(const char *c, char **endptr, const wxXLocale& loc) 241 { return wxCRT_Strtod_lA(c, endptr, loc.Get()); } wxStrtol_lA(const char * c,char ** endptr,int base,const wxXLocale & loc)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()); } wxStrtoul_lA(const char * c,char ** endptr,int base,const wxXLocale & loc)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 wxIsalnum_l(wchar_t c,const wxXLocale & loc)264 inline int wxIsalnum_l(wchar_t c, const wxXLocale& loc) 265 { return wxCRT_Isalnum_lW(c, loc.Get()); } wxIsalpha_l(wchar_t c,const wxXLocale & loc)266 inline int wxIsalpha_l(wchar_t c, const wxXLocale& loc) 267 { return wxCRT_Isalpha_lW(c, loc.Get()); } wxIscntrl_l(wchar_t c,const wxXLocale & loc)268 inline int wxIscntrl_l(wchar_t c, const wxXLocale& loc) 269 { return wxCRT_Iscntrl_lW(c, loc.Get()); } wxIsdigit_l(wchar_t c,const wxXLocale & loc)270 inline int wxIsdigit_l(wchar_t c, const wxXLocale& loc) 271 { return wxCRT_Isdigit_lW(c, loc.Get()); } wxIsgraph_l(wchar_t c,const wxXLocale & loc)272 inline int wxIsgraph_l(wchar_t c, const wxXLocale& loc) 273 { return wxCRT_Isgraph_lW(c, loc.Get()); } wxIslower_l(wchar_t c,const wxXLocale & loc)274 inline int wxIslower_l(wchar_t c, const wxXLocale& loc) 275 { return wxCRT_Islower_lW(c, loc.Get()); } wxIsprint_l(wchar_t c,const wxXLocale & loc)276 inline int wxIsprint_l(wchar_t c, const wxXLocale& loc) 277 { return wxCRT_Isprint_lW(c, loc.Get()); } wxIspunct_l(wchar_t c,const wxXLocale & loc)278 inline int wxIspunct_l(wchar_t c, const wxXLocale& loc) 279 { return wxCRT_Ispunct_lW(c, loc.Get()); } wxIsspace_l(wchar_t c,const wxXLocale & loc)280 inline int wxIsspace_l(wchar_t c, const wxXLocale& loc) 281 { return wxCRT_Isspace_lW(c, loc.Get()); } wxIsupper_l(wchar_t c,const wxXLocale & loc)282 inline int wxIsupper_l(wchar_t c, const wxXLocale& loc) 283 { return wxCRT_Isupper_lW(c, loc.Get()); } wxIsxdigit_l(wchar_t c,const wxXLocale & loc)284 inline int wxIsxdigit_l(wchar_t c, const wxXLocale& loc) 285 { return wxCRT_Isxdigit_lW(c, loc.Get()); } wxTolower_l(wchar_t c,const wxXLocale & loc)286 inline wchar_t wxTolower_l(wchar_t c, const wxXLocale& loc) 287 { return wxCRT_Tolower_lW(c, loc.Get()); } wxToupper_l(wchar_t c,const wxXLocale & loc)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 wxStrtod_l(const wchar_t * c,wchar_t ** endptr,const wxXLocale & loc)298 inline double wxStrtod_l(const wchar_t *c, wchar_t **endptr, const wxXLocale& loc) 299 { return wxCRT_Strtod_lW(c, endptr, loc.Get()); } wxStrtol_l(const wchar_t * c,wchar_t ** endptr,int base,const wxXLocale & loc)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()); } wxStrtoul_l(const wchar_t * c,wchar_t ** endptr,int base,const wxXLocale & loc)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 wxStrtod_l(const char * c,char ** endptr,const wxXLocale & loc)305 inline double wxStrtod_l(const char *c, char **endptr, const wxXLocale& loc) 306 { return wxCRT_Strtod_lA(c, endptr, loc.Get()); } wxStrtol_l(const char * c,char ** endptr,int base,const wxXLocale & loc)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()); } wxStrtoul_l(const char * c,char ** endptr,int base,const wxXLocale & loc)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_ 341