xlocale.h 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340
  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. This header defines portable wrappers around xlocale foo_l() functions or
  12. their MSVC proprietary _foo_l() equivalents when they are available and
  13. implements these functions for the "C" locale [only] if they are not. This
  14. allows the program running under the default user locale to still use "C"
  15. locale for operations such as reading data from files where they are stored
  16. using decimal point &c.
  17. TODO: Currently only the character classification and transformation
  18. functions and number <-> string functions, are implemented,
  19. we also need at least
  20. - formatted IO: scanf_l(), printf_l() &c
  21. - time: strftime_l(), strptime_l()
  22. */
  23. #ifndef _WX_XLOCALE_H_
  24. #define _WX_XLOCALE_H_
  25. #include "wx/defs.h" // wxUSE_XLOCALE
  26. #if wxUSE_XLOCALE
  27. #include "wx/crt.h" // Includes wx/chartype.h, wx/wxcrt.h(wx/string.h)
  28. #include "wx/intl.h" // wxLanguage
  29. // The platform-specific locale type
  30. // If wxXLocale_t is not defined, then only "C" locale support is provided
  31. #ifdef wxHAS_XLOCALE_SUPPORT
  32. #if wxCHECK_VISUALC_VERSION(8) && !defined(__WXWINCE__)
  33. typedef _locale_t wxXLocale_t;
  34. #define wxXLOCALE_IDENT(name) _ ## name
  35. #elif defined(HAVE_LOCALE_T)
  36. #include <locale.h>
  37. #include <xlocale.h>
  38. #include <ctype.h>
  39. #include <stdlib.h>
  40. #if wxUSE_UNICODE
  41. #include <wctype.h>
  42. #endif
  43. // Locale type and identifier name
  44. typedef locale_t wxXLocale_t;
  45. #define wxXLOCALE_IDENT(name) name
  46. #else
  47. #error "Unknown xlocale support"
  48. #endif
  49. #endif // wxHAS_XLOCALE_SUPPORT
  50. // wxXLocale is a wrapper around the native type representing a locale.
  51. //
  52. // It is not to be confused with wxLocale, which handles actually changing the
  53. // locale, loading message catalogs, etc. This just stores a locale value.
  54. // The similarity of names is unfortunate, but there doesn't seem to be any
  55. // better alternative right now. Perhaps by wxWidgets 4.0 better naming could
  56. // be used, or this class could become wxLocale (a wrapper for the value), and
  57. // some other class could be used to load the language catalogs or something
  58. // that would be clearer
  59. #ifdef wxHAS_XLOCALE_SUPPORT
  60. class WXDLLIMPEXP_BASE wxXLocale
  61. {
  62. public:
  63. // Construct an uninitialized locale
  64. wxXLocale() { m_locale = NULL; }
  65. // Construct from a symbolic language constant
  66. wxXLocale(wxLanguage lang);
  67. // Construct from the given language string
  68. wxXLocale(const char *loc) { Init(loc); }
  69. // Destroy the locale
  70. ~wxXLocale() { Free(); }
  71. // Get the global "C" locale object
  72. static wxXLocale& GetCLocale();
  73. // Check if the object represents a valid locale (notice that without
  74. // wxHAS_XLOCALE_SUPPORT the only valid locale is the "C" one)
  75. bool IsOk() const { return m_locale != NULL; }
  76. // Get the type
  77. wxXLocale_t Get() const { return m_locale; }
  78. bool operator== (const wxXLocale& loc) const
  79. { return m_locale == loc.m_locale; }
  80. private:
  81. // Special ctor for the "C" locale, it's only used internally as the user
  82. // code is supposed to use GetCLocale()
  83. wxXLocale(struct wxXLocaleCTag * WXUNUSED(dummy)) { Init("C"); }
  84. // Create from the given language string (called from ctors)
  85. void Init(const char *loc);
  86. // Free the locale if it's non-NULL
  87. void Free();
  88. // The corresponding locale handle, NULL if invalid
  89. wxXLocale_t m_locale;
  90. // POSIX xlocale API provides a duplocale() function but MSVC locale API
  91. // doesn't give us any means to copy a _locale_t object so we reduce the
  92. // functionality to least common denominator here -- it shouldn't be a
  93. // problem as copying the locale objects shouldn't be often needed
  94. wxDECLARE_NO_COPY_CLASS(wxXLocale);
  95. };
  96. #else // !wxHAS_XLOCALE_SUPPORT
  97. // Skeleton version supporting only the "C" locale for the systems without
  98. // xlocale support
  99. class WXDLLIMPEXP_BASE wxXLocale
  100. {
  101. public:
  102. // Construct an uninitialized locale
  103. wxXLocale() { m_isC = false; }
  104. // Construct from a symbolic language constant: unless the language is
  105. // wxLANGUAGE_ENGLISH_US (which we suppose to be the same as "C" locale)
  106. // the object will be invalid
  107. wxXLocale(wxLanguage lang)
  108. {
  109. m_isC = lang == wxLANGUAGE_ENGLISH_US;
  110. }
  111. // Construct from the given language string: unless the string is "C" or
  112. // "POSIX" the object will be invalid
  113. wxXLocale(const char *loc)
  114. {
  115. m_isC = loc && (strcmp(loc, "C") == 0 || strcmp(loc, "POSIX") == 0);
  116. }
  117. // Default copy ctor, assignment operator and dtor are ok (or would be if
  118. // we didn't use DECLARE_NO_COPY_CLASS() for consistency with the xlocale
  119. // version)
  120. // Get the global "C" locale object
  121. static wxXLocale& GetCLocale();
  122. // Check if the object represents a valid locale (notice that without
  123. // wxHAS_XLOCALE_SUPPORT the only valid locale is the "C" one)
  124. bool IsOk() const { return m_isC; }
  125. private:
  126. // Special ctor for the "C" locale, it's only used internally as the user
  127. // code is supposed to use GetCLocale()
  128. wxXLocale(struct wxXLocaleCTag * WXUNUSED(dummy)) { m_isC = true; }
  129. // Without xlocale support this class can only represent "C" locale, if
  130. // this is false the object is invalid
  131. bool m_isC;
  132. // although it's not a problem to copy the objects of this class, we use
  133. // this macro in this implementation for consistency with the xlocale-based
  134. // one which can't be copied when using MSVC locale API
  135. wxDECLARE_NO_COPY_CLASS(wxXLocale);
  136. };
  137. #endif // wxHAS_XLOCALE_SUPPORT/!wxHAS_XLOCALE_SUPPORT
  138. // A shorter synonym for the most commonly used locale object
  139. #define wxCLocale (wxXLocale::GetCLocale())
  140. extern WXDLLIMPEXP_DATA_BASE(wxXLocale) wxNullXLocale;
  141. // Wrappers for various functions:
  142. #ifdef wxHAS_XLOCALE_SUPPORT
  143. // ctype functions
  144. #define wxCRT_Isalnum_lA wxXLOCALE_IDENT(isalnum_l)
  145. #define wxCRT_Isalpha_lA wxXLOCALE_IDENT(isalpha_l)
  146. #define wxCRT_Iscntrl_lA wxXLOCALE_IDENT(iscntrl_l)
  147. #define wxCRT_Isdigit_lA wxXLOCALE_IDENT(isdigit_l)
  148. #define wxCRT_Isgraph_lA wxXLOCALE_IDENT(isgraph_l)
  149. #define wxCRT_Islower_lA wxXLOCALE_IDENT(islower_l)
  150. #define wxCRT_Isprint_lA wxXLOCALE_IDENT(isprint_l)
  151. #define wxCRT_Ispunct_lA wxXLOCALE_IDENT(ispunct_l)
  152. #define wxCRT_Isspace_lA wxXLOCALE_IDENT(isspace_l)
  153. #define wxCRT_Isupper_lA wxXLOCALE_IDENT(isupper_l)
  154. #define wxCRT_Isxdigit_lA wxXLOCALE_IDENT(isxdigit_l)
  155. #define wxCRT_Tolower_lA wxXLOCALE_IDENT(tolower_l)
  156. #define wxCRT_Toupper_lA wxXLOCALE_IDENT(toupper_l)
  157. inline int wxIsalnum_l(char c, const wxXLocale& loc)
  158. { return wxCRT_Isalnum_lA(static_cast<unsigned char>(c), loc.Get()); }
  159. inline int wxIsalpha_l(char c, const wxXLocale& loc)
  160. { return wxCRT_Isalpha_lA(static_cast<unsigned char>(c), loc.Get()); }
  161. inline int wxIscntrl_l(char c, const wxXLocale& loc)
  162. { return wxCRT_Iscntrl_lA(static_cast<unsigned char>(c), loc.Get()); }
  163. inline int wxIsdigit_l(char c, const wxXLocale& loc)
  164. { return wxCRT_Isdigit_lA(static_cast<unsigned char>(c), loc.Get()); }
  165. inline int wxIsgraph_l(char c, const wxXLocale& loc)
  166. { return wxCRT_Isgraph_lA(static_cast<unsigned char>(c), loc.Get()); }
  167. inline int wxIslower_l(char c, const wxXLocale& loc)
  168. { return wxCRT_Islower_lA(static_cast<unsigned char>(c), loc.Get()); }
  169. inline int wxIsprint_l(char c, const wxXLocale& loc)
  170. { return wxCRT_Isprint_lA(static_cast<unsigned char>(c), loc.Get()); }
  171. inline int wxIspunct_l(char c, const wxXLocale& loc)
  172. { return wxCRT_Ispunct_lA(static_cast<unsigned char>(c), loc.Get()); }
  173. inline int wxIsspace_l(char c, const wxXLocale& loc)
  174. { return wxCRT_Isspace_lA(static_cast<unsigned char>(c), loc.Get()); }
  175. inline int wxIsupper_l(char c, const wxXLocale& loc)
  176. { return wxCRT_Isupper_lA(static_cast<unsigned char>(c), loc.Get()); }
  177. inline int wxIsxdigit_l(char c, const wxXLocale& loc)
  178. { return wxCRT_Isxdigit_lA(static_cast<unsigned char>(c), loc.Get()); }
  179. inline int wxTolower_l(char c, const wxXLocale& loc)
  180. { return wxCRT_Tolower_lA(static_cast<unsigned char>(c), loc.Get()); }
  181. inline int wxToupper_l(char c, const wxXLocale& loc)
  182. { return wxCRT_Toupper_lA(static_cast<unsigned char>(c), loc.Get()); }
  183. // stdlib functions for numeric <-> string conversion
  184. // NOTE: GNU libc does not have ato[fil]_l functions;
  185. // MSVC++8 does not have _strto[u]ll_l functions;
  186. // thus we take the minimal set of functions provided in both environments:
  187. #define wxCRT_Strtod_lA wxXLOCALE_IDENT(strtod_l)
  188. #define wxCRT_Strtol_lA wxXLOCALE_IDENT(strtol_l)
  189. #define wxCRT_Strtoul_lA wxXLOCALE_IDENT(strtoul_l)
  190. inline double wxStrtod_lA(const char *c, char **endptr, const wxXLocale& loc)
  191. { return wxCRT_Strtod_lA(c, endptr, loc.Get()); }
  192. inline long wxStrtol_lA(const char *c, char **endptr, int base, const wxXLocale& loc)
  193. { return wxCRT_Strtol_lA(c, endptr, base, loc.Get()); }
  194. inline unsigned long wxStrtoul_lA(const char *c, char **endptr, int base, const wxXLocale& loc)
  195. { return wxCRT_Strtoul_lA(c, endptr, base, loc.Get()); }
  196. #if wxUSE_UNICODE
  197. // ctype functions
  198. #define wxCRT_Isalnum_lW wxXLOCALE_IDENT(iswalnum_l)
  199. #define wxCRT_Isalpha_lW wxXLOCALE_IDENT(iswalpha_l)
  200. #define wxCRT_Iscntrl_lW wxXLOCALE_IDENT(iswcntrl_l)
  201. #define wxCRT_Isdigit_lW wxXLOCALE_IDENT(iswdigit_l)
  202. #define wxCRT_Isgraph_lW wxXLOCALE_IDENT(iswgraph_l)
  203. #define wxCRT_Islower_lW wxXLOCALE_IDENT(iswlower_l)
  204. #define wxCRT_Isprint_lW wxXLOCALE_IDENT(iswprint_l)
  205. #define wxCRT_Ispunct_lW wxXLOCALE_IDENT(iswpunct_l)
  206. #define wxCRT_Isspace_lW wxXLOCALE_IDENT(iswspace_l)
  207. #define wxCRT_Isupper_lW wxXLOCALE_IDENT(iswupper_l)
  208. #define wxCRT_Isxdigit_lW wxXLOCALE_IDENT(iswxdigit_l)
  209. #define wxCRT_Tolower_lW wxXLOCALE_IDENT(towlower_l)
  210. #define wxCRT_Toupper_lW wxXLOCALE_IDENT(towupper_l)
  211. inline int wxIsalnum_l(wchar_t c, const wxXLocale& loc)
  212. { return wxCRT_Isalnum_lW(c, loc.Get()); }
  213. inline int wxIsalpha_l(wchar_t c, const wxXLocale& loc)
  214. { return wxCRT_Isalpha_lW(c, loc.Get()); }
  215. inline int wxIscntrl_l(wchar_t c, const wxXLocale& loc)
  216. { return wxCRT_Iscntrl_lW(c, loc.Get()); }
  217. inline int wxIsdigit_l(wchar_t c, const wxXLocale& loc)
  218. { return wxCRT_Isdigit_lW(c, loc.Get()); }
  219. inline int wxIsgraph_l(wchar_t c, const wxXLocale& loc)
  220. { return wxCRT_Isgraph_lW(c, loc.Get()); }
  221. inline int wxIslower_l(wchar_t c, const wxXLocale& loc)
  222. { return wxCRT_Islower_lW(c, loc.Get()); }
  223. inline int wxIsprint_l(wchar_t c, const wxXLocale& loc)
  224. { return wxCRT_Isprint_lW(c, loc.Get()); }
  225. inline int wxIspunct_l(wchar_t c, const wxXLocale& loc)
  226. { return wxCRT_Ispunct_lW(c, loc.Get()); }
  227. inline int wxIsspace_l(wchar_t c, const wxXLocale& loc)
  228. { return wxCRT_Isspace_lW(c, loc.Get()); }
  229. inline int wxIsupper_l(wchar_t c, const wxXLocale& loc)
  230. { return wxCRT_Isupper_lW(c, loc.Get()); }
  231. inline int wxIsxdigit_l(wchar_t c, const wxXLocale& loc)
  232. { return wxCRT_Isxdigit_lW(c, loc.Get()); }
  233. inline wchar_t wxTolower_l(wchar_t c, const wxXLocale& loc)
  234. { return wxCRT_Tolower_lW(c, loc.Get()); }
  235. inline wchar_t wxToupper_l(wchar_t c, const wxXLocale& loc)
  236. { return wxCRT_Toupper_lW(c, loc.Get()); }
  237. // stdlib functions for numeric <-> string conversion
  238. // (see notes above about missing functions)
  239. #define wxCRT_Strtod_lW wxXLOCALE_IDENT(wcstod_l)
  240. #define wxCRT_Strtol_lW wxXLOCALE_IDENT(wcstol_l)
  241. #define wxCRT_Strtoul_lW wxXLOCALE_IDENT(wcstoul_l)
  242. inline double wxStrtod_l(const wchar_t *c, wchar_t **endptr, const wxXLocale& loc)
  243. { return wxCRT_Strtod_lW(c, endptr, loc.Get()); }
  244. inline long wxStrtol_l(const wchar_t *c, wchar_t **endptr, int base, const wxXLocale& loc)
  245. { return wxCRT_Strtol_lW(c, endptr, base, loc.Get()); }
  246. inline unsigned long wxStrtoul_l(const wchar_t *c, wchar_t **endptr, int base, const wxXLocale& loc)
  247. { return wxCRT_Strtoul_lW(c, endptr, base, loc.Get()); }
  248. #else // !wxUSE_UNICODE
  249. inline double wxStrtod_l(const char *c, char **endptr, const wxXLocale& loc)
  250. { return wxCRT_Strtod_lA(c, endptr, loc.Get()); }
  251. inline long wxStrtol_l(const char *c, char **endptr, int base, const wxXLocale& loc)
  252. { return wxCRT_Strtol_lA(c, endptr, base, loc.Get()); }
  253. inline unsigned long wxStrtoul_l(const char *c, char **endptr, int base, const wxXLocale& loc)
  254. { return wxCRT_Strtoul_lA(c, endptr, base, loc.Get()); }
  255. #endif // wxUSE_UNICODE
  256. #else // !wxHAS_XLOCALE_SUPPORT
  257. // ctype functions
  258. int WXDLLIMPEXP_BASE wxIsalnum_l(const wxUniChar& c, const wxXLocale& loc);
  259. int WXDLLIMPEXP_BASE wxIsalpha_l(const wxUniChar& c, const wxXLocale& loc);
  260. int WXDLLIMPEXP_BASE wxIscntrl_l(const wxUniChar& c, const wxXLocale& loc);
  261. int WXDLLIMPEXP_BASE wxIsdigit_l(const wxUniChar& c, const wxXLocale& loc);
  262. int WXDLLIMPEXP_BASE wxIsgraph_l(const wxUniChar& c, const wxXLocale& loc);
  263. int WXDLLIMPEXP_BASE wxIslower_l(const wxUniChar& c, const wxXLocale& loc);
  264. int WXDLLIMPEXP_BASE wxIsprint_l(const wxUniChar& c, const wxXLocale& loc);
  265. int WXDLLIMPEXP_BASE wxIspunct_l(const wxUniChar& c, const wxXLocale& loc);
  266. int WXDLLIMPEXP_BASE wxIsspace_l(const wxUniChar& c, const wxXLocale& loc);
  267. int WXDLLIMPEXP_BASE wxIsupper_l(const wxUniChar& c, const wxXLocale& loc);
  268. int WXDLLIMPEXP_BASE wxIsxdigit_l(const wxUniChar& c, const wxXLocale& loc);
  269. int WXDLLIMPEXP_BASE wxTolower_l(const wxUniChar& c, const wxXLocale& loc);
  270. int WXDLLIMPEXP_BASE wxToupper_l(const wxUniChar& c, const wxXLocale& loc);
  271. // stdlib functions
  272. double WXDLLIMPEXP_BASE wxStrtod_l(const wchar_t* str, wchar_t **endptr, const wxXLocale& loc);
  273. double WXDLLIMPEXP_BASE wxStrtod_l(const char* str, char **endptr, const wxXLocale& loc);
  274. long WXDLLIMPEXP_BASE wxStrtol_l(const wchar_t* str, wchar_t **endptr, int base, const wxXLocale& loc);
  275. long WXDLLIMPEXP_BASE wxStrtol_l(const char* str, char **endptr, int base, const wxXLocale& loc);
  276. unsigned long WXDLLIMPEXP_BASE wxStrtoul_l(const wchar_t* str, wchar_t **endptr, int base, const wxXLocale& loc);
  277. unsigned long WXDLLIMPEXP_BASE wxStrtoul_l(const char* str, char **endptr, int base, const wxXLocale& loc);
  278. #endif // wxHAS_XLOCALE_SUPPORT/!wxHAS_XLOCALE_SUPPORT
  279. #endif // wxUSE_XLOCALE
  280. #endif // _WX_XLOCALE_H_