176d0caaeSpatrick //===----------------------------------------------------------------------===//
246035553Spatrick //
346035553Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
446035553Spatrick // See https://llvm.org/LICENSE.txt for license information.
546035553Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
646035553Spatrick //
746035553Spatrick //===----------------------------------------------------------------------===//
846035553Spatrick
946035553Spatrick #include <locale>
1046035553Spatrick #include <cstdarg> // va_start, va_end
1146035553Spatrick #include <memory>
1246035553Spatrick #include <type_traits>
1346035553Spatrick
1446035553Spatrick int __libcpp_vasprintf(char **sptr, const char *__restrict fmt, va_list ap);
1546035553Spatrick
1646035553Spatrick using std::__libcpp_locale_guard;
1746035553Spatrick
1846035553Spatrick // FIXME: base currently unused. Needs manual work to construct the new locale
newlocale(int mask,const char * locale,locale_t)1946035553Spatrick locale_t newlocale( int mask, const char * locale, locale_t /*base*/ )
2046035553Spatrick {
2146035553Spatrick return {_create_locale( LC_ALL, locale ), locale};
2246035553Spatrick }
2346035553Spatrick
MB_CUR_MAX_L(locale_t __l)2446035553Spatrick decltype(MB_CUR_MAX) MB_CUR_MAX_L( locale_t __l )
2546035553Spatrick {
2646035553Spatrick #if defined(_LIBCPP_MSVCRT)
2746035553Spatrick return ___mb_cur_max_l_func(__l);
2846035553Spatrick #else
2946035553Spatrick __libcpp_locale_guard __current(__l);
3046035553Spatrick return MB_CUR_MAX;
3146035553Spatrick #endif
3246035553Spatrick }
3346035553Spatrick
localeconv_l(locale_t & loc)3446035553Spatrick lconv *localeconv_l( locale_t &loc )
3546035553Spatrick {
3646035553Spatrick __libcpp_locale_guard __current(loc);
3746035553Spatrick lconv *lc = localeconv();
3846035553Spatrick if (!lc)
3946035553Spatrick return lc;
4046035553Spatrick return loc.__store_lconv(lc);
4146035553Spatrick }
mbrlen_l(const char * __restrict s,size_t n,mbstate_t * __restrict ps,locale_t loc)4246035553Spatrick size_t mbrlen_l( const char *__restrict s, size_t n,
4346035553Spatrick mbstate_t *__restrict ps, locale_t loc )
4446035553Spatrick {
4546035553Spatrick __libcpp_locale_guard __current(loc);
4646035553Spatrick return mbrlen( s, n, ps );
4746035553Spatrick }
mbsrtowcs_l(wchar_t * __restrict dst,const char ** __restrict src,size_t len,mbstate_t * __restrict ps,locale_t loc)4846035553Spatrick size_t mbsrtowcs_l( wchar_t *__restrict dst, const char **__restrict src,
4946035553Spatrick size_t len, mbstate_t *__restrict ps, locale_t loc )
5046035553Spatrick {
5146035553Spatrick __libcpp_locale_guard __current(loc);
5246035553Spatrick return mbsrtowcs( dst, src, len, ps );
5346035553Spatrick }
wcrtomb_l(char * __restrict s,wchar_t wc,mbstate_t * __restrict ps,locale_t loc)5446035553Spatrick size_t wcrtomb_l( char *__restrict s, wchar_t wc, mbstate_t *__restrict ps,
5546035553Spatrick locale_t loc )
5646035553Spatrick {
5746035553Spatrick __libcpp_locale_guard __current(loc);
5846035553Spatrick return wcrtomb( s, wc, ps );
5946035553Spatrick }
mbrtowc_l(wchar_t * __restrict pwc,const char * __restrict s,size_t n,mbstate_t * __restrict ps,locale_t loc)6046035553Spatrick size_t mbrtowc_l( wchar_t *__restrict pwc, const char *__restrict s,
6146035553Spatrick size_t n, mbstate_t *__restrict ps, locale_t loc )
6246035553Spatrick {
6346035553Spatrick __libcpp_locale_guard __current(loc);
6446035553Spatrick return mbrtowc( pwc, s, n, ps );
6546035553Spatrick }
mbsnrtowcs_l(wchar_t * __restrict dst,const char ** __restrict src,size_t nms,size_t len,mbstate_t * __restrict ps,locale_t loc)6646035553Spatrick size_t mbsnrtowcs_l( wchar_t *__restrict dst, const char **__restrict src,
6746035553Spatrick size_t nms, size_t len, mbstate_t *__restrict ps, locale_t loc )
6846035553Spatrick {
6946035553Spatrick __libcpp_locale_guard __current(loc);
7046035553Spatrick return mbsnrtowcs( dst, src, nms, len, ps );
7146035553Spatrick }
wcsnrtombs_l(char * __restrict dst,const wchar_t ** __restrict src,size_t nwc,size_t len,mbstate_t * __restrict ps,locale_t loc)7246035553Spatrick size_t wcsnrtombs_l( char *__restrict dst, const wchar_t **__restrict src,
7346035553Spatrick size_t nwc, size_t len, mbstate_t *__restrict ps, locale_t loc )
7446035553Spatrick {
7546035553Spatrick __libcpp_locale_guard __current(loc);
7646035553Spatrick return wcsnrtombs( dst, src, nwc, len, ps );
7746035553Spatrick }
btowc_l(int c,locale_t loc)7846035553Spatrick wint_t btowc_l( int c, locale_t loc )
7946035553Spatrick {
8046035553Spatrick __libcpp_locale_guard __current(loc);
8146035553Spatrick return btowc( c );
8246035553Spatrick }
wctob_l(wint_t c,locale_t loc)8346035553Spatrick int wctob_l( wint_t c, locale_t loc )
8446035553Spatrick {
8546035553Spatrick __libcpp_locale_guard __current(loc);
8646035553Spatrick return wctob( c );
8746035553Spatrick }
8846035553Spatrick
snprintf_l(char * ret,size_t n,locale_t loc,const char * format,...)8946035553Spatrick int snprintf_l(char *ret, size_t n, locale_t loc, const char *format, ...)
9046035553Spatrick {
9146035553Spatrick va_list ap;
9246035553Spatrick va_start( ap, format );
9346035553Spatrick #if defined(_LIBCPP_MSVCRT)
9446035553Spatrick // FIXME: Remove usage of internal CRT function and globals.
9546035553Spatrick int result = __stdio_common_vsprintf(
9646035553Spatrick _CRT_INTERNAL_LOCAL_PRINTF_OPTIONS | _CRT_INTERNAL_PRINTF_STANDARD_SNPRINTF_BEHAVIOR,
9746035553Spatrick ret, n, format, loc, ap);
9846035553Spatrick #else
9946035553Spatrick __libcpp_locale_guard __current(loc);
100*4bdff4beSrobert _LIBCPP_DIAGNOSTIC_PUSH
101*4bdff4beSrobert _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wformat-nonliteral")
10246035553Spatrick int result = vsnprintf( ret, n, format, ap );
103*4bdff4beSrobert _LIBCPP_DIAGNOSTIC_POP
10446035553Spatrick #endif
10546035553Spatrick va_end(ap);
10646035553Spatrick return result;
10746035553Spatrick }
10846035553Spatrick
asprintf_l(char ** ret,locale_t loc,const char * format,...)10946035553Spatrick int asprintf_l( char **ret, locale_t loc, const char *format, ... )
11046035553Spatrick {
11146035553Spatrick va_list ap;
11246035553Spatrick va_start( ap, format );
11346035553Spatrick int result = vasprintf_l( ret, loc, format, ap );
11446035553Spatrick va_end(ap);
11546035553Spatrick return result;
11646035553Spatrick }
vasprintf_l(char ** ret,locale_t loc,const char * format,va_list ap)11746035553Spatrick int vasprintf_l( char **ret, locale_t loc, const char *format, va_list ap )
11846035553Spatrick {
11946035553Spatrick __libcpp_locale_guard __current(loc);
12046035553Spatrick return __libcpp_vasprintf( ret, format, ap );
12146035553Spatrick }
12246035553Spatrick
12346035553Spatrick #if !defined(_LIBCPP_MSVCRT)
strtof_l(const char * nptr,char ** endptr,locale_t loc)12446035553Spatrick float strtof_l(const char* nptr, char** endptr, locale_t loc) {
12546035553Spatrick __libcpp_locale_guard __current(loc);
12646035553Spatrick return strtof(nptr, endptr);
12746035553Spatrick }
12846035553Spatrick
strtold_l(const char * nptr,char ** endptr,locale_t loc)12946035553Spatrick long double strtold_l(const char* nptr, char** endptr, locale_t loc) {
13046035553Spatrick __libcpp_locale_guard __current(loc);
13146035553Spatrick return strtold(nptr, endptr);
13246035553Spatrick }
13346035553Spatrick #endif
13446035553Spatrick
13546035553Spatrick #if defined(__MINGW32__) && __MSVCRT_VERSION__ < 0x0800
strftime_l(char * ret,size_t n,const char * format,const struct tm * tm,locale_t loc)13646035553Spatrick size_t strftime_l(char *ret, size_t n, const char *format, const struct tm *tm,
13746035553Spatrick locale_t loc) {
13846035553Spatrick __libcpp_locale_guard __current(loc);
13946035553Spatrick return strftime(ret, n, format, tm);
14046035553Spatrick }
14146035553Spatrick #endif
142