|
11 | 11 |
|
12 | 12 | #include <__config>
|
13 | 13 |
|
| 14 | +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 15 | +# pragma GCC system_header |
| 16 | +#endif |
| 17 | + |
| 18 | +// The platform-specific headers have to provide the following interface. |
| 19 | +// |
| 20 | +// These functions are equivalent to their C counterparts, except that __locale::__locale_t |
| 21 | +// is used instead of the current global locale. |
| 22 | +// |
| 23 | +// Variadic functions may be implemented as templates with a parameter pack instead |
| 24 | +// of C-style variadic functions. |
| 25 | +// |
| 26 | +// TODO: I think __uselocale() is not necessary if we refactor a bit. |
| 27 | +// TODO: __localeconv shouldn't take a reference, but the Windows implementation doesn't allow copying __locale_t |
| 28 | +// |
| 29 | +// Locale management |
| 30 | +// ----------------- |
| 31 | +// namespace __locale { |
| 32 | +// using __locale_t = implementation-defined; |
| 33 | +// __locale_t __uselocale(__locale_t); |
| 34 | +// __locale_t __newlocale(int, const char*, __locale_t); |
| 35 | +// void __freelocale(__locale_t); |
| 36 | +// lconv* __localeconv(__locale_t&); |
| 37 | +// } |
| 38 | +// |
| 39 | +// Strtonum functions |
| 40 | +// ------------------ |
| 41 | +// namespace __locale { |
| 42 | +// float __strtof(const char*, char**, __locale_t); |
| 43 | +// double __strtod(const char*, char**, __locale_t); |
| 44 | +// long double __strtold(const char*, char**, __locale_t); |
| 45 | +// long long __strtoll(const char*, char**, __locale_t); |
| 46 | +// unsigned long long __strtoull(const char*, char**, __locale_t); |
| 47 | +// } |
| 48 | +// |
| 49 | +// Character manipulation functions |
| 50 | +// -------------------------------- |
| 51 | +// namespace __locale { |
| 52 | +// int __islower(int, __locale_t); |
| 53 | +// int __isupper(int, __locale_t); |
| 54 | +// int __isdigit(int, __locale_t); |
| 55 | +// int __isxdigit(int, __locale_t); |
| 56 | +// int __toupper(int, __locale_t); |
| 57 | +// int __tolower(int, __locale_t); |
| 58 | +// int __strcoll(const char*, const char*, __locale_t); |
| 59 | +// size_t __strxfrm(char*, const char*, size_t, __locale_t); |
| 60 | +// |
| 61 | +// int __iswspace(wint_t, __locale_t); |
| 62 | +// int __iswprint(wint_t, __locale_t); |
| 63 | +// int __iswcntrl(wint_t, __locale_t); |
| 64 | +// int __iswupper(wint_t, __locale_t); |
| 65 | +// int __iswlower(wint_t, __locale_t); |
| 66 | +// int __iswalpha(wint_t, __locale_t); |
| 67 | +// int __iswblank(wint_t, __locale_t); |
| 68 | +// int __iswdigit(wint_t, __locale_t); |
| 69 | +// int __iswpunct(wint_t, __locale_t); |
| 70 | +// int __iswxdigit(wint_t, __locale_t); |
| 71 | +// wint_t __towupper(wint_t, __locale_t); |
| 72 | +// wint_t __towlower(wint_t, __locale_t); |
| 73 | +// int __wcscoll(const wchar_t*, const wchar_t*, __locale_t); |
| 74 | +// size_t __wcsxfrm(wchar_t*, const wchar_t*, size_t, __locale_t); |
| 75 | +// |
| 76 | +// size_t __strftime(char*, size_t, const char*, const tm*, __locale_t); |
| 77 | +// } |
| 78 | +// |
| 79 | +// Other functions |
| 80 | +// --------------- |
| 81 | +// namespace __locale { |
| 82 | +// implementation-defined __mb_len_max(__locale_t); |
| 83 | +// wint_t __btowc(int, __locale_t); |
| 84 | +// int __wctob(wint_t, __locale_t); |
| 85 | +// size_t __wcsnrtombs(char*, const wchar_t**, size_t, size_t, mbstate_t*, __locale_t); |
| 86 | +// size_t __wcrtomb(char*, wchar_t, mbstate_t*, __locale_t); |
| 87 | +// size_t __mbsnrtowcs(wchar_t*, const char**, size_t, size_t, mbstate_t*, __locale_t); |
| 88 | +// size_t __mbrtowc(wchar_t*, const char*, size_t, mbstate_t*, __locale_t); |
| 89 | +// int __mbtowc(wchar_t*, const char*, size_t, __locale_t); |
| 90 | +// size_t __mbrlen(const char*, size_t, mbstate_t*, __locale_t); |
| 91 | +// size_t __mbsrtowcs(wchar_t*, const char**, size_t, mbstate_t*, __locale_t); |
| 92 | +// int __snprintf(char*, size_t, __locale_t, const char*, ...); |
| 93 | +// int __asprintf(char**, __locale_t, const char*, ...); |
| 94 | +// int __sscanf(const char*, __locale_t, const char*, ...); |
| 95 | +// } |
| 96 | + |
| 97 | +// TODO: This is a temporary definition to bridge between the old way we defined the locale base API |
| 98 | +// (by providing global non-reserved names) and the new API. As we move individual platforms |
| 99 | +// towards the new way of defining the locale base API, this should disappear since each platform |
| 100 | +// will define those directly. |
14 | 101 | #if defined(_LIBCPP_MSVCRT_LIKE)
|
15 | 102 | # include <__locale_dir/locale_base_api/win32.h>
|
16 | 103 | #elif defined(_AIX) || defined(__MVS__)
|
|
35 | 122 | # include <__locale_dir/locale_base_api/bsd_locale_fallbacks.h>
|
36 | 123 | #endif
|
37 | 124 |
|
38 |
| -#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
39 |
| -# pragma GCC system_header |
| 125 | +#include <__cstddef/size_t.h> |
| 126 | +#include <__utility/forward.h> |
| 127 | +#include <ctype.h> |
| 128 | +#include <string.h> |
| 129 | +#include <time.h> |
| 130 | +#if _LIBCPP_HAS_WIDE_CHARACTERS |
| 131 | +# include <wctype.h> |
| 132 | +#endif |
| 133 | +_LIBCPP_BEGIN_NAMESPACE_STD |
| 134 | +namespace __locale { |
| 135 | +// |
| 136 | +// Locale management |
| 137 | +// |
| 138 | +using __locale_t = locale_t; |
| 139 | + |
| 140 | +#ifndef _LIBCPP_MSVCRT_LIKE |
| 141 | +inline _LIBCPP_HIDE_FROM_ABI __locale_t __uselocale(__locale_t __loc) { return uselocale(__loc); } |
| 142 | +#endif |
| 143 | + |
| 144 | +inline _LIBCPP_HIDE_FROM_ABI __locale_t __newlocale(int __category_mask, const char* __name, __locale_t __loc) { |
| 145 | + return newlocale(__category_mask, __name, __loc); |
| 146 | +} |
| 147 | + |
| 148 | +inline _LIBCPP_HIDE_FROM_ABI void __freelocale(__locale_t __loc) { freelocale(__loc); } |
| 149 | + |
| 150 | +inline _LIBCPP_HIDE_FROM_ABI lconv* __localeconv(__locale_t& __loc) { return __libcpp_localeconv_l(__loc); } |
| 151 | + |
| 152 | +// |
| 153 | +// Strtonum functions |
| 154 | +// |
| 155 | +inline _LIBCPP_HIDE_FROM_ABI float __strtof(const char* __nptr, char** __endptr, __locale_t __loc) { |
| 156 | + return strtof_l(__nptr, __endptr, __loc); |
| 157 | +} |
| 158 | + |
| 159 | +inline _LIBCPP_HIDE_FROM_ABI double __strtod(const char* __nptr, char** __endptr, __locale_t __loc) { |
| 160 | + return strtod_l(__nptr, __endptr, __loc); |
| 161 | +} |
| 162 | + |
| 163 | +inline _LIBCPP_HIDE_FROM_ABI long double __strtold(const char* __nptr, char** __endptr, __locale_t __loc) { |
| 164 | + return strtold_l(__nptr, __endptr, __loc); |
| 165 | +} |
| 166 | + |
| 167 | +inline _LIBCPP_HIDE_FROM_ABI long long __strtoll(const char* __nptr, char** __endptr, int __base, __locale_t __loc) { |
| 168 | + return strtoll_l(__nptr, __endptr, __base, __loc); |
| 169 | +} |
| 170 | + |
| 171 | +inline _LIBCPP_HIDE_FROM_ABI unsigned long long |
| 172 | +__strtoull(const char* __nptr, char** __endptr, int __base, __locale_t __loc) { |
| 173 | + return strtoull_l(__nptr, __endptr, __base, __loc); |
| 174 | +} |
| 175 | + |
| 176 | +// |
| 177 | +// Character manipulation functions |
| 178 | +// |
| 179 | +inline _LIBCPP_HIDE_FROM_ABI int __islower(int __ch, __locale_t __loc) { return islower_l(__ch, __loc); } |
| 180 | +inline _LIBCPP_HIDE_FROM_ABI int __isupper(int __ch, __locale_t __loc) { return isupper_l(__ch, __loc); } |
| 181 | +inline _LIBCPP_HIDE_FROM_ABI int __isdigit(int __ch, __locale_t __loc) { return isdigit_l(__ch, __loc); } |
| 182 | +inline _LIBCPP_HIDE_FROM_ABI int __isxdigit(int __ch, __locale_t __loc) { return isxdigit_l(__ch, __loc); } |
| 183 | +inline _LIBCPP_HIDE_FROM_ABI int __strcoll(const char* __s1, const char* __s2, __locale_t __loc) { |
| 184 | + return strcoll_l(__s1, __s2, __loc); |
| 185 | +} |
| 186 | +inline _LIBCPP_HIDE_FROM_ABI size_t __strxfrm(char* __dest, const char* __src, size_t __n, __locale_t __loc) { |
| 187 | + return strxfrm_l(__dest, __src, __n, __loc); |
| 188 | +} |
| 189 | +inline _LIBCPP_HIDE_FROM_ABI int __toupper(int __ch, __locale_t __loc) { return toupper_l(__ch, __loc); } |
| 190 | +inline _LIBCPP_HIDE_FROM_ABI int __tolower(int __ch, __locale_t __loc) { return tolower_l(__ch, __loc); } |
| 191 | + |
| 192 | +#if _LIBCPP_HAS_WIDE_CHARACTERS |
| 193 | +inline _LIBCPP_HIDE_FROM_ABI int __wcscoll(const wchar_t* __s1, const wchar_t* __s2, __locale_t __loc) { |
| 194 | + return wcscoll_l(__s1, __s2, __loc); |
| 195 | +} |
| 196 | +inline _LIBCPP_HIDE_FROM_ABI size_t __wcsxfrm(wchar_t* __dest, const wchar_t* __src, size_t __n, __locale_t __loc) { |
| 197 | + return wcsxfrm_l(__dest, __src, __n, __loc); |
| 198 | +} |
| 199 | +inline _LIBCPP_HIDE_FROM_ABI int __iswspace(wint_t __ch, __locale_t __loc) { return iswspace_l(__ch, __loc); } |
| 200 | +inline _LIBCPP_HIDE_FROM_ABI int __iswprint(wint_t __ch, __locale_t __loc) { return iswprint_l(__ch, __loc); } |
| 201 | +inline _LIBCPP_HIDE_FROM_ABI int __iswcntrl(wint_t __ch, __locale_t __loc) { return iswcntrl_l(__ch, __loc); } |
| 202 | +inline _LIBCPP_HIDE_FROM_ABI int __iswupper(wint_t __ch, __locale_t __loc) { return iswupper_l(__ch, __loc); } |
| 203 | +inline _LIBCPP_HIDE_FROM_ABI int __iswlower(wint_t __ch, __locale_t __loc) { return iswlower_l(__ch, __loc); } |
| 204 | +inline _LIBCPP_HIDE_FROM_ABI int __iswalpha(wint_t __ch, __locale_t __loc) { return iswalpha_l(__ch, __loc); } |
| 205 | +inline _LIBCPP_HIDE_FROM_ABI int __iswblank(wint_t __ch, __locale_t __loc) { return iswblank_l(__ch, __loc); } |
| 206 | +inline _LIBCPP_HIDE_FROM_ABI int __iswdigit(wint_t __ch, __locale_t __loc) { return iswdigit_l(__ch, __loc); } |
| 207 | +inline _LIBCPP_HIDE_FROM_ABI int __iswpunct(wint_t __ch, __locale_t __loc) { return iswpunct_l(__ch, __loc); } |
| 208 | +inline _LIBCPP_HIDE_FROM_ABI int __iswxdigit(wint_t __ch, __locale_t __loc) { return iswxdigit_l(__ch, __loc); } |
| 209 | +inline _LIBCPP_HIDE_FROM_ABI wint_t __towupper(wint_t __ch, __locale_t __loc) { return towupper_l(__ch, __loc); } |
| 210 | +inline _LIBCPP_HIDE_FROM_ABI wint_t __towlower(wint_t __ch, __locale_t __loc) { return towlower_l(__ch, __loc); } |
40 | 211 | #endif
|
41 | 212 |
|
42 |
| -/* |
43 |
| -The platform-specific headers have to provide the following interface: |
44 |
| -
|
45 |
| -// TODO: rename this to __libcpp_locale_t |
46 |
| -using locale_t = implementation-defined; |
47 |
| -
|
48 |
| -implementation-defined __libcpp_mb_cur_max_l(locale_t); |
49 |
| -wint_t __libcpp_btowc_l(int, locale_t); |
50 |
| -int __libcpp_wctob_l(wint_t, locale_t); |
51 |
| -size_t __libcpp_wcsnrtombs_l(char* dest, const wchar_t** src, size_t wide_char_count, size_t len, mbstate_t, locale_t); |
52 |
| -size_t __libcpp_wcrtomb_l(char* str, wchar_t wide_char, mbstate_t*, locale_t); |
53 |
| -size_t __libcpp_mbsnrtowcs_l(wchar_t* dest, const char** src, size_t max_out, size_t len, mbstate_t*, locale_t); |
54 |
| -size_t __libcpp_mbrtowc_l(wchar_t* dest, cosnt char* src, size_t count, mbstate_t*, locale_t); |
55 |
| -int __libcpp_mbtowc_l(wchar_t* dest, const char* src, size_t count, locale_t); |
56 |
| -size_t __libcpp_mbrlen_l(const char* str, size_t count, mbstate_t*, locale_t); |
57 |
| -// TODO: __libcpp_localeconv_l shouldn't take a reference, but the Windows implementation doesn't allow copying locale_t |
58 |
| -lconv* __libcpp_localeconv_l(locale_t&); |
59 |
| -size_t __libcpp_mbsrtowcs_l(wchar_t* dest, const char** src, size_t len, mbstate_t*, locale_t); |
60 |
| -int __libcpp_snprintf_l(char* dest, size_t buff_size, locale_t, const char* format, ...); |
61 |
| -int __libcpp_asprintf_l(char** dest, locale_t, const char* format, ...); |
62 |
| -int __libcpp_sscanf_l(const char* dest, locale_t, const char* format, ...); |
63 |
| -
|
64 |
| -// TODO: change these to reserved names |
65 |
| -float strtof_l(const char* str, char** str_end, locale_t); |
66 |
| -double strtod_l(const char* str, char** str_end, locale_t); |
67 |
| -long double strtold_l(const char* str, char** str_end, locale_t); |
68 |
| -long long strtoll_l(const char* str, char** str_end, locale_t); |
69 |
| -unsigned long long strtoull_l(const char* str, char** str_end, locale_t); |
70 |
| -
|
71 |
| -locale_t newlocale(int category_mask, const char* locale, locale_t base); |
72 |
| -void freelocale(locale_t); |
73 |
| -
|
74 |
| -int islower_l(int ch, locale_t); |
75 |
| -int isupper_l(int ch, locale_t); |
76 |
| -int isdigit_l(int ch, locale_t); |
77 |
| -int isxdigit_l(int ch, locale_t); |
78 |
| -int strcoll_l(const char* lhs, const char* rhs, locale_t); |
79 |
| -size_t strxfrm_l(char* dst, const char* src, size_t n, locale_t); |
80 |
| -int wcscoll_l(const char* lhs, const char* rhs, locale_t); |
81 |
| -size_t wcsxfrm_l(wchar_t* dst, const wchar_t* src, size_t n, locale_t); |
82 |
| -int toupper_l(int ch, locale_t); |
83 |
| -int tolower_l(int ch, locale_t); |
84 |
| -int iswspace_l(wint_t ch, locale_t); |
85 |
| -int iswprint_l(wint_t ch, locale_t); |
86 |
| -int iswcntrl_l(wint_t ch, locale_t); |
87 |
| -int iswupper_l(wint_t ch, locale_t); |
88 |
| -int iswlower_l(wint_t ch, locale_t); |
89 |
| -int iswalpha_l(wint_t ch, locale_t); |
90 |
| -int iswblank_l(wint_t ch, locale_t); |
91 |
| -int iswdigit_l(wint_t ch, locale_t); |
92 |
| -int iswpunct_l(wint_t ch, locale_t); |
93 |
| -int iswxdigit_l(wint_t ch, locale_t); |
94 |
| -wint_t towupper_l(wint_t ch, locale_t); |
95 |
| -wint_t towlower_l(wint_t ch, locale_t); |
96 |
| -size_t strftime_l(char* str, size_t len, const char* format, const tm*, locale_t); |
97 |
| -
|
98 |
| -
|
99 |
| -These functions are equivalent to their C counterparts, |
100 |
| -except that locale_t is used instead of the current global locale. |
101 |
| -
|
102 |
| -The variadic functions may be implemented as templates with a parameter pack instead of variadic functions. |
103 |
| -*/ |
| 213 | +inline _LIBCPP_HIDE_FROM_ABI size_t |
| 214 | +__strftime(char* __s, size_t __max, const char* __format, const tm* __tm, __locale_t __loc) { |
| 215 | + return strftime_l(__s, __max, __format, __tm, __loc); |
| 216 | +} |
| 217 | + |
| 218 | +// |
| 219 | +// Other functions |
| 220 | +// |
| 221 | +inline _LIBCPP_HIDE_FROM_ABI decltype(__libcpp_mb_cur_max_l(__locale_t())) __mb_len_max(__locale_t __loc) { |
| 222 | + return __libcpp_mb_cur_max_l(__loc); |
| 223 | +} |
| 224 | +#if _LIBCPP_HAS_WIDE_CHARACTERS |
| 225 | +inline _LIBCPP_HIDE_FROM_ABI wint_t __btowc(int __ch, __locale_t __loc) { return __libcpp_btowc_l(__ch, __loc); } |
| 226 | +inline _LIBCPP_HIDE_FROM_ABI int __wctob(wint_t __ch, __locale_t __loc) { return __libcpp_wctob_l(__ch, __loc); } |
| 227 | +inline _LIBCPP_HIDE_FROM_ABI size_t |
| 228 | +__wcsnrtombs(char* __dest, const wchar_t** __src, size_t __nwc, size_t __len, mbstate_t* __ps, __locale_t __loc) { |
| 229 | + return __libcpp_wcsnrtombs_l(__dest, __src, __nwc, __len, __ps, __loc); |
| 230 | +} |
| 231 | +inline _LIBCPP_HIDE_FROM_ABI size_t __wcrtomb(char* __s, wchar_t __ch, mbstate_t* __ps, __locale_t __loc) { |
| 232 | + return __libcpp_wcrtomb_l(__s, __ch, __ps, __loc); |
| 233 | +} |
| 234 | +inline _LIBCPP_HIDE_FROM_ABI size_t |
| 235 | +__mbsnrtowcs(wchar_t* __dest, const char** __src, size_t __nms, size_t __len, mbstate_t* __ps, __locale_t __loc) { |
| 236 | + return __libcpp_mbsnrtowcs_l(__dest, __src, __nms, __len, __ps, __loc); |
| 237 | +} |
| 238 | +inline _LIBCPP_HIDE_FROM_ABI size_t |
| 239 | +__mbrtowc(wchar_t* __pwc, const char* __s, size_t __n, mbstate_t* __ps, __locale_t __loc) { |
| 240 | + return __libcpp_mbrtowc_l(__pwc, __s, __n, __ps, __loc); |
| 241 | +} |
| 242 | +inline _LIBCPP_HIDE_FROM_ABI int __mbtowc(wchar_t* __pwc, const char* __pmb, size_t __max, __locale_t __loc) { |
| 243 | + return __libcpp_mbtowc_l(__pwc, __pmb, __max, __loc); |
| 244 | +} |
| 245 | +inline _LIBCPP_HIDE_FROM_ABI size_t __mbrlen(const char* __s, size_t __n, mbstate_t* __ps, __locale_t __loc) { |
| 246 | + return __libcpp_mbrlen_l(__s, __n, __ps, __loc); |
| 247 | +} |
| 248 | +inline _LIBCPP_HIDE_FROM_ABI size_t |
| 249 | +__mbsrtowcs(wchar_t* __dest, const char** __src, size_t __len, mbstate_t* __ps, __locale_t __loc) { |
| 250 | + return __libcpp_mbsrtowcs_l(__dest, __src, __len, __ps, __loc); |
| 251 | +} |
| 252 | +#endif |
| 253 | + |
| 254 | +_LIBCPP_DIAGNOSTIC_PUSH |
| 255 | +_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wgcc-compat") |
| 256 | +_LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wformat-nonliteral") // GCC doesn't support [[gnu::format]] on variadic templates |
| 257 | +#ifdef _LIBCPP_COMPILER_CLANG_BASED |
| 258 | +# define _LIBCPP_VARIADIC_ATTRIBUTE_FORMAT(...) _LIBCPP_ATTRIBUTE_FORMAT(__VA_ARGS__) |
| 259 | +#else |
| 260 | +# define _LIBCPP_VARIADIC_ATTRIBUTE_FORMAT(...) /* nothing */ |
| 261 | +#endif |
| 262 | + |
| 263 | +template <class... _Args> |
| 264 | +_LIBCPP_HIDE_FROM_ABI _LIBCPP_VARIADIC_ATTRIBUTE_FORMAT(__printf__, 4, 5) int __snprintf( |
| 265 | + char* __s, size_t __n, __locale_t __loc, const char* __format, _Args&&... __args) { |
| 266 | + return __libcpp_snprintf_l(__s, __n, __loc, __format, std::forward<_Args>(__args)...); |
| 267 | +} |
| 268 | +template <class... _Args> |
| 269 | +_LIBCPP_HIDE_FROM_ABI _LIBCPP_VARIADIC_ATTRIBUTE_FORMAT(__printf__, 3, 4) int __asprintf( |
| 270 | + char** __s, __locale_t __loc, const char* __format, _Args&&... __args) { |
| 271 | + return __libcpp_asprintf_l(__s, __loc, __format, std::forward<_Args>(__args)...); |
| 272 | +} |
| 273 | +template <class... _Args> |
| 274 | +_LIBCPP_HIDE_FROM_ABI _LIBCPP_VARIADIC_ATTRIBUTE_FORMAT(__scanf__, 3, 4) int __sscanf( |
| 275 | + const char* __s, __locale_t __loc, const char* __format, _Args&&... __args) { |
| 276 | + return __libcpp_sscanf_l(__s, __loc, __format, std::forward<_Args>(__args)...); |
| 277 | +} |
| 278 | +_LIBCPP_DIAGNOSTIC_POP |
| 279 | +#undef _LIBCPP_VARIADIC_ATTRIBUTE_FORMAT |
| 280 | + |
| 281 | +} // namespace __locale |
| 282 | +_LIBCPP_END_NAMESPACE_STD |
104 | 283 |
|
105 | 284 | #endif // _LIBCPP___LOCALE_DIR_LOCALE_BASE_API_H
|
0 commit comments