1 //===-----------------------------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef _LIBCPP___LOCALE_DIR_LOCALE_BASE_API_H 10 #define _LIBCPP___LOCALE_DIR_LOCALE_BASE_API_H 11 12 #include <__config> 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: __localeconv shouldn't take a reference, but the Windows implementation doesn't allow copying __locale_t 27 // 28 // Locale management 29 // ----------------- 30 // namespace __locale { 31 // using __locale_t = implementation-defined; 32 // using __lconv_t = implementation-defined; 33 // __locale_t __newlocale(int, const char*, __locale_t); 34 // void __freelocale(__locale_t); 35 // char* __setlocale(int, const char*); 36 // __lconv_t* __localeconv(__locale_t&); 37 // } 38 // 39 // #define _LIBCPP_COLLATE_MASK /* implementation-defined */ 40 // #define _LIBCPP_CTYPE_MASK /* implementation-defined */ 41 // #define _LIBCPP_MONETARY_MASK /* implementation-defined */ 42 // #define _LIBCPP_NUMERIC_MASK /* implementation-defined */ 43 // #define _LIBCPP_TIME_MASK /* implementation-defined */ 44 // #define _LIBCPP_MESSAGES_MASK /* implementation-defined */ 45 // #define _LIBCPP_ALL_MASK /* implementation-defined */ 46 // #define _LIBCPP_LC_ALL /* implementation-defined */ 47 // 48 // Strtonum functions 49 // ------------------ 50 // namespace __locale { 51 // float __strtof(const char*, char**, __locale_t); 52 // double __strtod(const char*, char**, __locale_t); 53 // long double __strtold(const char*, char**, __locale_t); 54 // long long __strtoll(const char*, char**, __locale_t); 55 // unsigned long long __strtoull(const char*, char**, __locale_t); 56 // } 57 // 58 // Character manipulation functions 59 // -------------------------------- 60 // namespace __locale { 61 // int __islower(int, __locale_t); 62 // int __isupper(int, __locale_t); 63 // int __isdigit(int, __locale_t); 64 // int __isxdigit(int, __locale_t); 65 // int __toupper(int, __locale_t); 66 // int __tolower(int, __locale_t); 67 // int __strcoll(const char*, const char*, __locale_t); 68 // size_t __strxfrm(char*, const char*, size_t, __locale_t); 69 // 70 // int __iswctype(wint_t, wctype_t, __locale_t); 71 // int __iswspace(wint_t, __locale_t); 72 // int __iswprint(wint_t, __locale_t); 73 // int __iswcntrl(wint_t, __locale_t); 74 // int __iswupper(wint_t, __locale_t); 75 // int __iswlower(wint_t, __locale_t); 76 // int __iswalpha(wint_t, __locale_t); 77 // int __iswblank(wint_t, __locale_t); 78 // int __iswdigit(wint_t, __locale_t); 79 // int __iswpunct(wint_t, __locale_t); 80 // int __iswxdigit(wint_t, __locale_t); 81 // wint_t __towupper(wint_t, __locale_t); 82 // wint_t __towlower(wint_t, __locale_t); 83 // int __wcscoll(const wchar_t*, const wchar_t*, __locale_t); 84 // size_t __wcsxfrm(wchar_t*, const wchar_t*, size_t, __locale_t); 85 // 86 // size_t __strftime(char*, size_t, const char*, const tm*, __locale_t); 87 // } 88 // 89 // Other functions 90 // --------------- 91 // namespace __locale { 92 // implementation-defined __mb_len_max(__locale_t); 93 // wint_t __btowc(int, __locale_t); 94 // int __wctob(wint_t, __locale_t); 95 // size_t __wcsnrtombs(char*, const wchar_t**, size_t, size_t, mbstate_t*, __locale_t); 96 // size_t __wcrtomb(char*, wchar_t, mbstate_t*, __locale_t); 97 // size_t __mbsnrtowcs(wchar_t*, const char**, size_t, size_t, mbstate_t*, __locale_t); 98 // size_t __mbrtowc(wchar_t*, const char*, size_t, mbstate_t*, __locale_t); 99 // int __mbtowc(wchar_t*, const char*, size_t, __locale_t); 100 // size_t __mbrlen(const char*, size_t, mbstate_t*, __locale_t); 101 // size_t __mbsrtowcs(wchar_t*, const char**, size_t, mbstate_t*, __locale_t); 102 // int __snprintf(char*, size_t, __locale_t, const char*, ...); 103 // int __asprintf(char**, __locale_t, const char*, ...); 104 // int __sscanf(const char*, __locale_t, const char*, ...); 105 // } 106 107 #if defined(__APPLE__) 108 # include <__locale_dir/support/apple.h> 109 #elif defined(__FreeBSD__) 110 # include <__locale_dir/support/freebsd.h> 111 #elif defined(_LIBCPP_MSVCRT_LIKE) 112 # include <__locale_dir/support/windows.h> 113 #elif defined(__Fuchsia__) 114 # include <__locale_dir/support/fuchsia.h> 115 #else 116 117 // TODO: This is a temporary definition to bridge between the old way we defined the locale base API 118 // (by providing global non-reserved names) and the new API. As we move individual platforms 119 // towards the new way of defining the locale base API, this should disappear since each platform 120 // will define those directly. 121 # if defined(_AIX) || defined(__MVS__) 122 # include <__locale_dir/locale_base_api/ibm.h> 123 # elif defined(__ANDROID__) 124 # include <__locale_dir/locale_base_api/android.h> 125 # elif defined(__OpenBSD__) 126 # include <__locale_dir/locale_base_api/openbsd.h> 127 # elif defined(__wasi__) || _LIBCPP_HAS_MUSL_LIBC 128 # include <__locale_dir/locale_base_api/musl.h> 129 # endif 130 131 # include <__locale_dir/locale_base_api/bsd_locale_fallbacks.h> 132 133 # include <__cstddef/size_t.h> 134 # include <__utility/forward.h> 135 # include <ctype.h> 136 # include <string.h> 137 # include <time.h> 138 # if _LIBCPP_HAS_WIDE_CHARACTERS 139 # include <wctype.h> 140 # endif 141 _LIBCPP_BEGIN_NAMESPACE_STD 142 namespace __locale { 143 // 144 // Locale management 145 // 146 using __locale_t _LIBCPP_NODEBUG = locale_t; 147 using __lconv_t _LIBCPP_NODEBUG = lconv; 148 149 inline _LIBCPP_HIDE_FROM_ABI __locale_t __newlocale(int __category_mask, const char* __name, __locale_t __loc) { 150 return newlocale(__category_mask, __name, __loc); 151 } 152 153 inline _LIBCPP_HIDE_FROM_ABI char* __setlocale(int __category, char const* __locale) { 154 return ::setlocale(__category, __locale); 155 } 156 157 inline _LIBCPP_HIDE_FROM_ABI void __freelocale(__locale_t __loc) { freelocale(__loc); } 158 159 inline _LIBCPP_HIDE_FROM_ABI __lconv_t* __localeconv(__locale_t& __loc) { return __libcpp_localeconv_l(__loc); } 160 161 # define _LIBCPP_COLLATE_MASK LC_COLLATE_MASK 162 # define _LIBCPP_CTYPE_MASK LC_CTYPE_MASK 163 # define _LIBCPP_MONETARY_MASK LC_MONETARY_MASK 164 # define _LIBCPP_NUMERIC_MASK LC_NUMERIC_MASK 165 # define _LIBCPP_TIME_MASK LC_TIME_MASK 166 # define _LIBCPP_MESSAGES_MASK LC_MESSAGES_MASK 167 # define _LIBCPP_ALL_MASK LC_ALL_MASK 168 # define _LIBCPP_LC_ALL LC_ALL 169 170 // 171 // Strtonum functions 172 // 173 inline _LIBCPP_HIDE_FROM_ABI float __strtof(const char* __nptr, char** __endptr, __locale_t __loc) { 174 return strtof_l(__nptr, __endptr, __loc); 175 } 176 177 inline _LIBCPP_HIDE_FROM_ABI double __strtod(const char* __nptr, char** __endptr, __locale_t __loc) { 178 return strtod_l(__nptr, __endptr, __loc); 179 } 180 181 inline _LIBCPP_HIDE_FROM_ABI long double __strtold(const char* __nptr, char** __endptr, __locale_t __loc) { 182 return strtold_l(__nptr, __endptr, __loc); 183 } 184 185 inline _LIBCPP_HIDE_FROM_ABI long long __strtoll(const char* __nptr, char** __endptr, int __base, __locale_t __loc) { 186 return strtoll_l(__nptr, __endptr, __base, __loc); 187 } 188 189 inline _LIBCPP_HIDE_FROM_ABI unsigned long long 190 __strtoull(const char* __nptr, char** __endptr, int __base, __locale_t __loc) { 191 return strtoull_l(__nptr, __endptr, __base, __loc); 192 } 193 194 // 195 // Character manipulation functions 196 // 197 inline _LIBCPP_HIDE_FROM_ABI int __islower(int __ch, __locale_t __loc) { return islower_l(__ch, __loc); } 198 inline _LIBCPP_HIDE_FROM_ABI int __isupper(int __ch, __locale_t __loc) { return isupper_l(__ch, __loc); } 199 inline _LIBCPP_HIDE_FROM_ABI int __isdigit(int __ch, __locale_t __loc) { return isdigit_l(__ch, __loc); } 200 inline _LIBCPP_HIDE_FROM_ABI int __isxdigit(int __ch, __locale_t __loc) { return isxdigit_l(__ch, __loc); } 201 inline _LIBCPP_HIDE_FROM_ABI int __strcoll(const char* __s1, const char* __s2, __locale_t __loc) { 202 return strcoll_l(__s1, __s2, __loc); 203 } 204 inline _LIBCPP_HIDE_FROM_ABI size_t __strxfrm(char* __dest, const char* __src, size_t __n, __locale_t __loc) { 205 return strxfrm_l(__dest, __src, __n, __loc); 206 } 207 inline _LIBCPP_HIDE_FROM_ABI int __toupper(int __ch, __locale_t __loc) { return toupper_l(__ch, __loc); } 208 inline _LIBCPP_HIDE_FROM_ABI int __tolower(int __ch, __locale_t __loc) { return tolower_l(__ch, __loc); } 209 210 # if _LIBCPP_HAS_WIDE_CHARACTERS 211 inline _LIBCPP_HIDE_FROM_ABI int __wcscoll(const wchar_t* __s1, const wchar_t* __s2, __locale_t __loc) { 212 return wcscoll_l(__s1, __s2, __loc); 213 } 214 inline _LIBCPP_HIDE_FROM_ABI size_t __wcsxfrm(wchar_t* __dest, const wchar_t* __src, size_t __n, __locale_t __loc) { 215 return wcsxfrm_l(__dest, __src, __n, __loc); 216 } 217 inline _LIBCPP_HIDE_FROM_ABI int __iswctype(wint_t __ch, wctype_t __type, __locale_t __loc) { 218 return iswctype_l(__ch, __type, __loc); 219 } 220 inline _LIBCPP_HIDE_FROM_ABI int __iswspace(wint_t __ch, __locale_t __loc) { return iswspace_l(__ch, __loc); } 221 inline _LIBCPP_HIDE_FROM_ABI int __iswprint(wint_t __ch, __locale_t __loc) { return iswprint_l(__ch, __loc); } 222 inline _LIBCPP_HIDE_FROM_ABI int __iswcntrl(wint_t __ch, __locale_t __loc) { return iswcntrl_l(__ch, __loc); } 223 inline _LIBCPP_HIDE_FROM_ABI int __iswupper(wint_t __ch, __locale_t __loc) { return iswupper_l(__ch, __loc); } 224 inline _LIBCPP_HIDE_FROM_ABI int __iswlower(wint_t __ch, __locale_t __loc) { return iswlower_l(__ch, __loc); } 225 inline _LIBCPP_HIDE_FROM_ABI int __iswalpha(wint_t __ch, __locale_t __loc) { return iswalpha_l(__ch, __loc); } 226 inline _LIBCPP_HIDE_FROM_ABI int __iswblank(wint_t __ch, __locale_t __loc) { return iswblank_l(__ch, __loc); } 227 inline _LIBCPP_HIDE_FROM_ABI int __iswdigit(wint_t __ch, __locale_t __loc) { return iswdigit_l(__ch, __loc); } 228 inline _LIBCPP_HIDE_FROM_ABI int __iswpunct(wint_t __ch, __locale_t __loc) { return iswpunct_l(__ch, __loc); } 229 inline _LIBCPP_HIDE_FROM_ABI int __iswxdigit(wint_t __ch, __locale_t __loc) { return iswxdigit_l(__ch, __loc); } 230 inline _LIBCPP_HIDE_FROM_ABI wint_t __towupper(wint_t __ch, __locale_t __loc) { return towupper_l(__ch, __loc); } 231 inline _LIBCPP_HIDE_FROM_ABI wint_t __towlower(wint_t __ch, __locale_t __loc) { return towlower_l(__ch, __loc); } 232 # endif 233 234 inline _LIBCPP_HIDE_FROM_ABI size_t 235 __strftime(char* __s, size_t __max, const char* __format, const tm* __tm, __locale_t __loc) { 236 return strftime_l(__s, __max, __format, __tm, __loc); 237 } 238 239 // 240 // Other functions 241 // 242 inline _LIBCPP_HIDE_FROM_ABI decltype(__libcpp_mb_cur_max_l(__locale_t())) __mb_len_max(__locale_t __loc) { 243 return __libcpp_mb_cur_max_l(__loc); 244 } 245 # if _LIBCPP_HAS_WIDE_CHARACTERS 246 inline _LIBCPP_HIDE_FROM_ABI wint_t __btowc(int __ch, __locale_t __loc) { return __libcpp_btowc_l(__ch, __loc); } 247 inline _LIBCPP_HIDE_FROM_ABI int __wctob(wint_t __ch, __locale_t __loc) { return __libcpp_wctob_l(__ch, __loc); } 248 inline _LIBCPP_HIDE_FROM_ABI size_t 249 __wcsnrtombs(char* __dest, const wchar_t** __src, size_t __nwc, size_t __len, mbstate_t* __ps, __locale_t __loc) { 250 return __libcpp_wcsnrtombs_l(__dest, __src, __nwc, __len, __ps, __loc); 251 } 252 inline _LIBCPP_HIDE_FROM_ABI size_t __wcrtomb(char* __s, wchar_t __ch, mbstate_t* __ps, __locale_t __loc) { 253 return __libcpp_wcrtomb_l(__s, __ch, __ps, __loc); 254 } 255 inline _LIBCPP_HIDE_FROM_ABI size_t 256 __mbsnrtowcs(wchar_t* __dest, const char** __src, size_t __nms, size_t __len, mbstate_t* __ps, __locale_t __loc) { 257 return __libcpp_mbsnrtowcs_l(__dest, __src, __nms, __len, __ps, __loc); 258 } 259 inline _LIBCPP_HIDE_FROM_ABI size_t 260 __mbrtowc(wchar_t* __pwc, const char* __s, size_t __n, mbstate_t* __ps, __locale_t __loc) { 261 return __libcpp_mbrtowc_l(__pwc, __s, __n, __ps, __loc); 262 } 263 inline _LIBCPP_HIDE_FROM_ABI int __mbtowc(wchar_t* __pwc, const char* __pmb, size_t __max, __locale_t __loc) { 264 return __libcpp_mbtowc_l(__pwc, __pmb, __max, __loc); 265 } 266 inline _LIBCPP_HIDE_FROM_ABI size_t __mbrlen(const char* __s, size_t __n, mbstate_t* __ps, __locale_t __loc) { 267 return __libcpp_mbrlen_l(__s, __n, __ps, __loc); 268 } 269 inline _LIBCPP_HIDE_FROM_ABI size_t 270 __mbsrtowcs(wchar_t* __dest, const char** __src, size_t __len, mbstate_t* __ps, __locale_t __loc) { 271 return __libcpp_mbsrtowcs_l(__dest, __src, __len, __ps, __loc); 272 } 273 # endif 274 275 _LIBCPP_DIAGNOSTIC_PUSH 276 _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wgcc-compat") 277 _LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wformat-nonliteral") // GCC doesn't support [[gnu::format]] on variadic templates 278 # ifdef _LIBCPP_COMPILER_CLANG_BASED 279 # define _LIBCPP_VARIADIC_ATTRIBUTE_FORMAT(...) _LIBCPP_ATTRIBUTE_FORMAT(__VA_ARGS__) 280 # else 281 # define _LIBCPP_VARIADIC_ATTRIBUTE_FORMAT(...) /* nothing */ 282 # endif 283 284 template <class... _Args> 285 _LIBCPP_HIDE_FROM_ABI _LIBCPP_VARIADIC_ATTRIBUTE_FORMAT(__printf__, 4, 5) int __snprintf( 286 char* __s, size_t __n, __locale_t __loc, const char* __format, _Args&&... __args) { 287 return std::__libcpp_snprintf_l(__s, __n, __loc, __format, std::forward<_Args>(__args)...); 288 } 289 template <class... _Args> 290 _LIBCPP_HIDE_FROM_ABI _LIBCPP_VARIADIC_ATTRIBUTE_FORMAT(__printf__, 3, 4) int __asprintf( 291 char** __s, __locale_t __loc, const char* __format, _Args&&... __args) { 292 return std::__libcpp_asprintf_l(__s, __loc, __format, std::forward<_Args>(__args)...); 293 } 294 template <class... _Args> 295 _LIBCPP_HIDE_FROM_ABI _LIBCPP_VARIADIC_ATTRIBUTE_FORMAT(__scanf__, 3, 4) int __sscanf( 296 const char* __s, __locale_t __loc, const char* __format, _Args&&... __args) { 297 return std::__libcpp_sscanf_l(__s, __loc, __format, std::forward<_Args>(__args)...); 298 } 299 _LIBCPP_DIAGNOSTIC_POP 300 # undef _LIBCPP_VARIADIC_ATTRIBUTE_FORMAT 301 302 } // namespace __locale 303 _LIBCPP_END_NAMESPACE_STD 304 305 #endif // Compatibility definition of locale base APIs 306 307 #endif // _LIBCPP___LOCALE_DIR_LOCALE_BASE_API_H 308