Index: CMakeLists.txt =================================================================== --- CMakeLists.txt +++ CMakeLists.txt @@ -124,6 +124,7 @@ "Build libc++ with support for a monotonic clock. This option may only be set to OFF when LIBCXX_ENABLE_THREADS=OFF." ON) option(LIBCXX_HAS_MUSL_LIBC "Build libc++ with support for the Musl C library" OFF) +option(LIBCXX_ENABLE_LOCALE_EXTENSIONS "Build libc++ with POSIX and/or BSD locale extensions" ON) # Misc options ---------------------------------------------------------------- # FIXME: Turn -pedantic back ON. It is currently off because it warns @@ -378,6 +379,7 @@ config_define_if_not(LIBCXX_ENABLE_THREADS _LIBCPP_HAS_NO_THREADS) config_define_if_not(LIBCXX_ENABLE_MONOTONIC_CLOCK _LIBCPP_HAS_NO_MONOTONIC_CLOCK) config_define_if_not(LIBCXX_ENABLE_THREAD_UNSAFE_C_FUNCTIONS _LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS) +config_define_if_not(LIBCXX_ENABLE_LOCALE_EXTENSIONS _LIBCPP_HAS_NO_LOCALE_EXTENSIONS) config_define_if(LIBCXX_HAS_MUSL_LIBC _LIBCPP_HAS_MUSL_LIBC) Index: include/__config =================================================================== --- include/__config +++ include/__config @@ -721,11 +721,6 @@ #define _LIBCPP_NONUNIQUE_RTTI_BIT (1ULL << 63) #endif -#if defined(__APPLE__) || defined(__FreeBSD__) || defined(_WIN32) || \ - defined(__sun__) || defined(__NetBSD__) || defined(__CloudABI__) -#define _LIBCPP_LOCALE__L_EXTENSIONS 1 -#endif - #if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) // Most unix variants have catopen. These are the specific ones that don't. #if !defined(_WIN32) && !defined(__ANDROID__) && !defined(_NEWLIB_VERSION) Index: include/__config_site.in =================================================================== --- include/__config_site.in +++ include/__config_site.in @@ -19,5 +19,6 @@ #cmakedefine _LIBCPP_HAS_NO_MONOTONIC_CLOCK #cmakedefine _LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS #cmakedefine _LIBCPP_HAS_MUSL_LIBC +#cmakedefine _LIBCPP_HAS_NO_LOCALE_EXTENSIONS #endif // _LIBCPP_CONFIG_SITE Index: include/__locale =================================================================== --- include/__locale +++ include/__locale @@ -19,7 +19,14 @@ #include #include #include -#if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__) + +#include + +#include +#if defined(_LIBCPP_HAS_NO_LOCALE_EXTENSIONS) +# include +# include +#elif defined(_LIBCPP_MSVCRT) || defined(__MINGW32__) # include #elif defined(_AIX) # include @@ -30,16 +37,14 @@ # include # endif #elif defined(__sun__) -# include # include #elif defined(_NEWLIB_VERSION) # include -#elif (defined(__GLIBC__) || defined(__APPLE__) || defined(__FreeBSD__) \ - || defined(__EMSCRIPTEN__) || defined(__IBMCPP__)) -# include #elif defined(_LIBCPP_HAS_MUSL_LIBC) # include -#endif // __GLIBC__ || __APPLE__ || __FreeBSD__ || __sun__ || __EMSCRIPTEN__ || __IBMCPP__ +#elif defined(__GLIBC__) +# include +#endif #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header @@ -281,7 +286,7 @@ class _LIBCPP_TYPE_VIS collate_byname : public collate { - locale_t __l; + _CXX_locale_t __l; public: typedef char char_type; typedef basic_string string_type; @@ -300,7 +305,7 @@ class _LIBCPP_TYPE_VIS collate_byname : public collate { - locale_t __l; + _CXX_locale_t __l; public: typedef wchar_t char_type; typedef basic_string string_type; @@ -659,7 +664,7 @@ class _LIBCPP_TYPE_VIS ctype_byname : public ctype { - locale_t __l; + _CXX_locale_t __l; public: explicit ctype_byname(const char*, size_t = 0); @@ -677,7 +682,7 @@ class _LIBCPP_TYPE_VIS ctype_byname : public ctype { - locale_t __l; + _CXX_locale_t __l; public: explicit ctype_byname(const char*, size_t = 0); @@ -909,7 +914,7 @@ : public locale::facet, public codecvt_base { - locale_t __l; + _CXX_locale_t __l; public: typedef wchar_t intern_type; typedef char extern_type; Index: include/algorithm =================================================================== --- include/algorithm +++ include/algorithm @@ -629,12 +629,7 @@ #include #include -#if defined(__IBMCPP__) -#include "support/ibm/support.h" -#endif -#if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__) -#include "support/win32/support.h" -#endif +#include "support/__builtin_support.h" #include <__undef_min_max> Index: include/ctype.h =================================================================== --- include/ctype.h +++ include/ctype.h @@ -45,7 +45,6 @@ // back to C++ linkage before including these C++ headers. extern "C++" { #include "support/win32/support.h" - #include "support/win32/locale_win32.h" } #endif // _LIBCPP_MSVCRT Index: include/locale =================================================================== --- include/locale +++ include/locale @@ -191,14 +191,6 @@ #endif #include #include -#if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__) -#include -#elif defined(_NEWLIB_VERSION) -// FIXME: replace all the uses of _NEWLIB_VERSION with __NEWLIB__ preceded by an -// include of once https://sourceware.org/ml/newlib-cvs/2014-q3/msg00038.html -// has had a chance to bake for a bit -#include -#endif #ifdef _LIBCPP_HAS_CATOPEN #include #endif @@ -222,195 +214,12 @@ #else # define _LIBCPP_GET_C_LOCALE __cloc() // Get the C locale object - _LIBCPP_FUNC_VIS locale_t __cloc(); + _LIBCPP_FUNC_VIS _CXX_locale_t __cloc(); #define __cloc_defined #endif -typedef _VSTD::remove_pointer::type __locale_struct; -typedef _VSTD::unique_ptr<__locale_struct, decltype(&freelocale)> __locale_unique_ptr; -#ifndef _LIBCPP_LOCALE__L_EXTENSIONS -typedef _VSTD::unique_ptr<__locale_struct, decltype(&uselocale)> __locale_raii; -#endif - -// OSX has nice foo_l() functions that let you turn off use of the global -// locale. Linux, not so much. The following functions avoid the locale when -// that's possible and otherwise do the wrong thing. FIXME. -#if defined(__linux__) || defined(__EMSCRIPTEN__) || defined(_AIX) || \ - defined(_NEWLIB_VERSION) || defined(__GLIBC__) - -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS -decltype(MB_CUR_MAX_L(_VSTD::declval())) -inline _LIBCPP_INLINE_VISIBILITY -__mb_cur_max_l(locale_t __l) -{ - return MB_CUR_MAX_L(__l); -} -#else // _LIBCPP_LOCALE__L_EXTENSIONS -inline _LIBCPP_ALWAYS_INLINE -decltype(MB_CUR_MAX) __mb_cur_max_l(locale_t __l) -{ - __locale_raii __current(uselocale(__l), uselocale); - return MB_CUR_MAX; -} -#endif // _LIBCPP_LOCALE__L_EXTENSIONS - -inline _LIBCPP_ALWAYS_INLINE -wint_t __btowc_l(int __c, locale_t __l) -{ -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - return btowc_l(__c, __l); -#else - __locale_raii __current(uselocale(__l), uselocale); - return btowc(__c); -#endif -} - -inline _LIBCPP_ALWAYS_INLINE -int __wctob_l(wint_t __c, locale_t __l) -{ -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - return wctob_l(__c, __l); -#else - __locale_raii __current(uselocale(__l), uselocale); - return wctob(__c); -#endif -} - -inline _LIBCPP_ALWAYS_INLINE -size_t __wcsnrtombs_l(char *__dest, const wchar_t **__src, size_t __nwc, - size_t __len, mbstate_t *__ps, locale_t __l) -{ -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - return wcsnrtombs_l(__dest, __src, __nwc, __len, __ps, __l); -#else - __locale_raii __current(uselocale(__l), uselocale); - return wcsnrtombs(__dest, __src, __nwc, __len, __ps); -#endif -} - -inline _LIBCPP_ALWAYS_INLINE -size_t __wcrtomb_l(char *__s, wchar_t __wc, mbstate_t *__ps, locale_t __l) -{ -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - return wcrtomb_l(__s, __wc, __ps, __l); -#else - __locale_raii __current(uselocale(__l), uselocale); - return wcrtomb(__s, __wc, __ps); -#endif -} - -inline _LIBCPP_ALWAYS_INLINE -size_t __mbsnrtowcs_l(wchar_t * __dest, const char **__src, size_t __nms, - size_t __len, mbstate_t *__ps, locale_t __l) -{ -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - return mbsnrtowcs_l(__dest, __src, __nms, __len, __ps, __l); -#else - __locale_raii __current(uselocale(__l), uselocale); - return mbsnrtowcs(__dest, __src, __nms, __len, __ps); -#endif -} - -inline _LIBCPP_ALWAYS_INLINE -size_t __mbrtowc_l(wchar_t *__pwc, const char *__s, size_t __n, - mbstate_t *__ps, locale_t __l) -{ -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - return mbrtowc_l(__pwc, __s, __n, __ps, __l); -#else - __locale_raii __current(uselocale(__l), uselocale); - return mbrtowc(__pwc, __s, __n, __ps); -#endif -} - -inline _LIBCPP_ALWAYS_INLINE -int __mbtowc_l(wchar_t *__pwc, const char *__pmb, size_t __max, locale_t __l) -{ -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - return mbtowc_l(__pwc, __pmb, __max, __l); -#else - __locale_raii __current(uselocale(__l), uselocale); - return mbtowc(__pwc, __pmb, __max); -#endif -} - -inline _LIBCPP_ALWAYS_INLINE -size_t __mbrlen_l(const char *__s, size_t __n, mbstate_t *__ps, locale_t __l) -{ -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - return mbrlen_l(__s, __n, __ps, __l); -#else - __locale_raii __current(uselocale(__l), uselocale); - return mbrlen(__s, __n, __ps); -#endif -} - -inline _LIBCPP_ALWAYS_INLINE -lconv *__localeconv_l(locale_t __l) -{ -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - return localeconv_l(__l); -#else - __locale_raii __current(uselocale(__l), uselocale); - return localeconv(); -#endif -} - -inline _LIBCPP_ALWAYS_INLINE -size_t __mbsrtowcs_l(wchar_t *__dest, const char **__src, size_t __len, - mbstate_t *__ps, locale_t __l) -{ -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - return mbsrtowcs_l(__dest, __src, __len, __ps, __l); -#else - __locale_raii __current(uselocale(__l), uselocale); - return mbsrtowcs(__dest, __src, __len, __ps); -#endif -} - -inline -int __snprintf_l(char *__s, size_t __n, locale_t __l, const char *__format, ...) { - va_list __va; - va_start(__va, __format); -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - int __res = vsnprintf_l(__s, __n, __l, __format, __va); -#else - __locale_raii __current(uselocale(__l), uselocale); - int __res = vsnprintf(__s, __n, __format, __va); -#endif - va_end(__va); - return __res; -} - -inline -int __asprintf_l(char **__s, locale_t __l, const char *__format, ...) { - va_list __va; - va_start(__va, __format); -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - int __res = vasprintf_l(__s, __l, __format, __va); -#else - __locale_raii __current(uselocale(__l), uselocale); - int __res = vasprintf(__s, __format, __va); -#endif - va_end(__va); - return __res; -} - -inline -int __sscanf_l(const char *__s, locale_t __l, const char *__format, ...) { - va_list __va; - va_start(__va, __format); -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - int __res = vsscanf_l(__s, __l, __format, __va); -#else - __locale_raii __current(uselocale(__l), uselocale); - int __res = vsscanf(__s, __format, __va); -#endif - va_end(__va); - return __res; -} - -#endif // __linux__ +typedef _VSTD::remove_pointer<_CXX_locale_t>::type __locale_struct; +typedef _VSTD::unique_ptr<__locale_struct, decltype(&_CXX_freelocale)> __locale_unique_ptr; // __scan_keyword // Scans [__b, __e) until a match is found in the basic_strings range @@ -871,7 +680,7 @@ typename remove_reference::type __save_errno = errno; errno = 0; char *__p2; - long long __ll = strtoll_l(__a, &__p2, __base, _LIBCPP_GET_C_LOCALE); + long long __ll = _CXX_strtoll_l(__a, &__p2, __base, _LIBCPP_GET_C_LOCALE); typename remove_reference::type __current_errno = errno; if (__current_errno == 0) errno = __save_errno; @@ -911,7 +720,7 @@ typename remove_reference::type __save_errno = errno; errno = 0; char *__p2; - unsigned long long __ll = strtoull_l(__a, &__p2, __base, _LIBCPP_GET_C_LOCALE); + unsigned long long __ll = _CXX_strtoull_l(__a, &__p2, __base, _LIBCPP_GET_C_LOCALE); typename remove_reference::type __current_errno = errno; if (__current_errno == 0) errno = __save_errno; @@ -941,7 +750,7 @@ typename remove_reference::type __save_errno = errno; errno = 0; char *__p2; - long double __ld = strtold_l(__a, &__p2, _LIBCPP_GET_C_LOCALE); + long double __ld = _CXX_strtold_l(__a, &__p2, _LIBCPP_GET_C_LOCALE); typename remove_reference::type __current_errno = errno; if (__current_errno == 0) errno = __save_errno; @@ -1188,11 +997,7 @@ } // Stage 3 __buf.resize(__a_end - __a); -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - if (sscanf_l(__buf.c_str(), _LIBCPP_GET_C_LOCALE, "%p", &__v) != 1) -#else - if (__sscanf_l(__buf.c_str(), _LIBCPP_GET_C_LOCALE, "%p", &__v) != 1) -#endif + if (_CXX_sscanf_l(__buf.c_str(), _LIBCPP_GET_C_LOCALE, "%p", &__v) != 1) __err = ios_base::failbit; // EOF checked if (__b == __e) @@ -1297,13 +1102,13 @@ *__oe++ = __ct.widen(*__nf++); *__oe++ = __ct.widen(*__nf++); for (__ns = __nf; __ns < __ne; ++__ns) - if (!isxdigit_l(*__ns, _LIBCPP_GET_C_LOCALE)) + if (!_CXX_isxdigit_l(*__ns, _LIBCPP_GET_C_LOCALE)) break; } else { for (__ns = __nf; __ns < __ne; ++__ns) - if (!isdigit_l(*__ns, _LIBCPP_GET_C_LOCALE)) + if (!_CXX_isdigit_l(*__ns, _LIBCPP_GET_C_LOCALE)) break; } if (__grouping.empty()) @@ -1558,11 +1363,7 @@ + ((numeric_limits::digits % 3) != 0) + 1; char __nar[__nbuf]; -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - int __nc = snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v); -#else - int __nc = __snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v); -#endif + int __nc = _CXX_snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v); char* __ne = __nar + __nc; char* __np = this->__identify_padding(__nar, __ne, __iob); // Stage 2 - Widen __nar while adding thousands separators @@ -1588,11 +1389,7 @@ + ((numeric_limits::digits % 3) != 0) + 2; char __nar[__nbuf]; -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - int __nc = snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v); -#else - int __nc = __snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v); -#endif + int __nc = _CXX_snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v); char* __ne = __nar + __nc; char* __np = this->__identify_padding(__nar, __ne, __iob); // Stage 2 - Widen __nar while adding thousands separators @@ -1618,11 +1415,7 @@ + ((numeric_limits::digits % 3) != 0) + 1; char __nar[__nbuf]; -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - int __nc = snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v); -#else - int __nc = __snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v); -#endif + int __nc = _CXX_snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v); char* __ne = __nar + __nc; char* __np = this->__identify_padding(__nar, __ne, __iob); // Stage 2 - Widen __nar while adding thousands separators @@ -1648,11 +1441,7 @@ + ((numeric_limits::digits % 3) != 0) + 1; char __nar[__nbuf]; -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - int __nc = snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v); -#else - int __nc = __snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v); -#endif + int __nc = _CXX_snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v); char* __ne = __nar + __nc; char* __np = this->__identify_padding(__nar, __ne, __iob); // Stage 2 - Widen __nar while adding thousands separators @@ -1679,34 +1468,17 @@ char* __nb = __nar; int __nc; if (__specify_precision) -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - __nc = snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, + __nc = _CXX_snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, (int)__iob.precision(), __v); -#else - __nc = __snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, - (int)__iob.precision(), __v); -#endif else -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - __nc = snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, __v); -#else - __nc = __snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, __v); -#endif + __nc = _CXX_snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, __v); unique_ptr __nbh(0, free); if (__nc > static_cast(__nbuf-1)) { if (__specify_precision) -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - __nc = asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, (int)__iob.precision(), __v); -#else - __nc = __asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, (int)__iob.precision(), __v); -#endif + __nc = _CXX_asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, (int)__iob.precision(), __v); else -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - __nc = asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, __v); -#else - __nc = __asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, (int)__iob.precision(), __v); -#endif + __nc = _CXX_asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, (int)__iob.precision(), __v); if (__nb == 0) __throw_bad_alloc(); __nbh.reset(__nb); @@ -1747,34 +1519,17 @@ char* __nb = __nar; int __nc; if (__specify_precision) -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - __nc = snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, + __nc = _CXX_snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, (int)__iob.precision(), __v); -#else - __nc = __snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, - (int)__iob.precision(), __v); -#endif else -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - __nc = snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, __v); -#else - __nc = __snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, __v); -#endif + __nc = _CXX_snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, __v); unique_ptr __nbh(0, free); if (__nc > static_cast(__nbuf-1)) { if (__specify_precision) -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - __nc = asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, (int)__iob.precision(), __v); -#else - __nc = __asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, (int)__iob.precision(), __v); -#endif + __nc = _CXX_asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, (int)__iob.precision(), __v); else -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - __nc = asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, __v); -#else - __nc = __asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, __v); -#endif + __nc = _CXX_asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, __v); if (__nb == 0) __throw_bad_alloc(); __nbh.reset(__nb); @@ -1810,11 +1565,7 @@ char __fmt[6] = "%p"; const unsigned __nbuf = 20; char __nar[__nbuf]; -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - int __nc = snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v); -#else - int __nc = __snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v); -#endif + int __nc = _CXX_snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v); char* __ne = __nar + __nc; char* __np = this->__identify_padding(__nar, __ne, __iob); // Stage 2 - Widen __nar @@ -2509,7 +2260,7 @@ class _LIBCPP_TYPE_VIS __time_get { protected: - locale_t __loc_; + _CXX_locale_t __loc_; __time_get(const char* __nm); __time_get(const string& __nm); @@ -2591,7 +2342,7 @@ class _LIBCPP_TYPE_VIS __time_put { - locale_t __loc_; + _CXX_locale_t __loc_; protected: _LIBCPP_ALWAYS_INLINE __time_put() : __loc_(_LIBCPP_GET_C_LOCALE) {} __time_put(const char* __nm); @@ -3526,11 +3277,7 @@ // secure memory for digit storage if (__n > __bs-1) { -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - __n = static_cast(asprintf_l(&__bb, _LIBCPP_GET_C_LOCALE, "%.0Lf", __units)); -#else - __n = __asprintf_l(&__bb, _LIBCPP_GET_C_LOCALE, "%.0Lf", __units); -#endif + __n = _CXX_asprintf_l(&__bb, _LIBCPP_GET_C_LOCALE, "%.0Lf", __units); if (__bb == 0) __throw_bad_alloc(); __hn.reset(__bb); Index: include/stdlib.h =================================================================== --- include/stdlib.h +++ include/stdlib.h @@ -98,7 +98,7 @@ extern "C++" { #ifdef _LIBCPP_MSVCRT -#include "support/win32/locale_win32.h" +#include "support/win32/support.h" #endif // _LIBCPP_MSVCRT #undef abs Index: include/support/__builtin_support.h =================================================================== --- /dev/null +++ include/support/__builtin_support.h @@ -0,0 +1,23 @@ +// -*- C++ -*- +//===-------------------- support/__builtin_support.h ---------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_SUPPORT_BUILTIN_SUPPORT_H +#define _LIBCPP_SUPPORT_BUILTIN_SUPPORT_H + +#include <__config> +#if defined(__IBMCPP__) +#include "support/ibm/support.h" +#endif // defined(__IBMCPP__) + +#if defined(_LIBCPP_MSVC) +#include +#endif // defined(_LIBCPP_MSVC) + +#endif // _LIBCPP_SUPPORT_BUILTIN_SUPPORT_H Index: include/support/android/locale_bionic.h =================================================================== --- include/support/android/locale_bionic.h +++ include/support/android/locale_bionic.h @@ -24,8 +24,8 @@ } #endif -// Share implementation with Newlib -#include +#include +#include #endif // defined(__ANDROID__) #endif // _LIBCPP_SUPPORT_ANDROID_LOCALE_BIONIC_H Index: include/support/ibm/locale_mgmt_aix.h =================================================================== --- /dev/null +++ include/support/ibm/locale_mgmt_aix.h @@ -0,0 +1,100 @@ +// -*- C++ -*- +//===------------------- support/ibm/locale_mgmt_aix.h --------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_SUPPORT_IBM_LOCALE_MGMT_AIX_H +#define _LIBCPP_SUPPORT_IBM_LOCALE_MGMT_AIX_H + +#if !defined(_LIBCPP_SUPPORT_XLOCALE_LOCALE_MANAGEMENT_H) +#error "This must be included inside support/xlocale/__locale_management.h" +#endif + +#if defined(_AIX) +#include "cstdlib" + +#ifdef __cplusplus +extern "C" { +#endif + +#if !defined(_AIX71) + +#undef _CXX_LC_COLLATE_MASK +#undef _CXX_LC_CTYPE_MASK +#undef _CXX_LC_MESSAGES_MASK +#undef _CXX_LC_MONETARY_MASK +#undef _CXX_LC_NUMERIC_MASK +#undef _CXX_LC_TIME_MASK +#undef _CXX_LC_ALL_MASK +// AIX 7.1 and higher has these definitions. Definitions and stubs +// are provied here as a temporary workaround on AIX 6.1. + +#define _CXX_LC_COLLATE_MASK 1 +#define _CXX_LC_CTYPE_MASK 2 +#define _CXX_LC_MESSAGES_MASK 4 +#define _CXX_LC_MONETARY_MASK 8 +#define _CXX_LC_NUMERIC_MASK 16 +#define _CXX_LC_TIME_MASK 32 +#define _CXX_LC_ALL_MASK (_CXX_LC_COLLATE_MASK | _CXX_LC_CTYPE_MASK | \ + _CXX_LC_MESSAGES_MASK | _CXX_LC_MONETARY_MASK |\ + _CXX_LC_NUMERIC_MASK | _CXX_LC_TIME_MASK) + +#undef _CXX_locale_t +typedef void* _CXX_locale_t; + +// The following are stubs. They are not supported on AIX 6.1. +#undef _CXX_newlocale +static inline +_CXX_locale_t _CXX_newlocale(int category_mask, const char *locale, _CXX_locale_t base) +{ + _LC_locale_t *newloc, *loc; + if ((loc = (_LC_locale_t *)__xopen_locale(locale)) == NULL) + { + errno = EINVAL; + return (_CXX_locale_t)0; + } + if ((newloc = (_LC_locale_t *)calloc(1, sizeof(_LC_locale_t))) == NULL) + { + errno = ENOMEM; + return (_CXX_locale_t)0; + } + if (!base) + base = (_LC_locale_t *)__xopen_locale("C"); + memcpy(newloc, base, sizeof (_LC_locale_t)); + if (category_mask & _CXX_LC_COLLATE_MASK) + newloc->lc_collate = loc->lc_collate; + if (category_mask & _CXX_LC_CTYPE_MASK) + newloc->lc_ctype = loc->lc_ctype; + //if (category_mask & _CXX_LC_MESSAGES_MASK) + // newloc->lc_messages = loc->lc_messages; + if (category_mask & _CXX_LC_MONETARY_MASK) + newloc->lc_monetary = loc->lc_monetary; + if (category_mask & _CXX_LC_TIME_MASK) + newloc->lc_time = loc->lc_time; + if (category_mask & _CXX_LC_NUMERIC_MASK) + newloc->lc_numeric = loc->lc_numeric; + return (_CXX_locale_t)newloc; +} +#undef _CXX_freelocale +static inline +void _CXX_freelocale(_CXX_locale_t locobj) +{ + free(locobj); +} +#undef _CXX_uselocale +static inline +_CXX_locale_t _CXX_uselocale(_CXX_locale_t newloc) +{ + return (_CXX_locale_t)0; +} + +#ifdef __cplusplus +} +#endif +#endif // defined(_AIX) +#endif // _LIBCPP_SUPPORT_IBM_LOCALE_MGMT_AIX_H Index: include/support/ibm/xlocale.h =================================================================== --- include/support/ibm/xlocale.h +++ include/support/ibm/xlocale.h @@ -11,6 +11,10 @@ #ifndef _LIBCPP_SUPPORT_IBM_XLOCALE_H #define _LIBCPP_SUPPORT_IBM_XLOCALE_H +#if !defined(_LIBCPP_SUPPORT_XLOCALE_DEFAULTS_H) +#error "This support header must be included after support/xlocale/__defaults.h" +#endif + #if defined(_AIX) #include "cstdlib" @@ -19,245 +23,164 @@ #endif #if !defined(_AIX71) -// AIX 7.1 and higher has these definitions. Definitions and stubs -// are provied here as a temporary workaround on AIX 6.1. - -#define LC_COLLATE_MASK 1 -#define LC_CTYPE_MASK 2 -#define LC_MESSAGES_MASK 4 -#define LC_MONETARY_MASK 8 -#define LC_NUMERIC_MASK 16 -#define LC_TIME_MASK 32 -#define LC_ALL_MASK (LC_COLLATE_MASK | LC_CTYPE_MASK | \ - LC_MESSAGES_MASK | LC_MONETARY_MASK |\ - LC_NUMERIC_MASK | LC_TIME_MASK) - -typedef void* locale_t; - -// The following are stubs. They are not supported on AIX 6.1. -static inline -locale_t newlocale(int category_mask, const char *locale, locale_t base) -{ - _LC_locale_t *newloc, *loc; - if ((loc = (_LC_locale_t *)__xopen_locale(locale)) == NULL) - { - errno = EINVAL; - return (locale_t)0; - } - if ((newloc = (_LC_locale_t *)calloc(1, sizeof(_LC_locale_t))) == NULL) - { - errno = ENOMEM; - return (locale_t)0; - } - if (!base) - base = (_LC_locale_t *)__xopen_locale("C"); - memcpy(newloc, base, sizeof (_LC_locale_t)); - if (category_mask & LC_COLLATE_MASK) - newloc->lc_collate = loc->lc_collate; - if (category_mask & LC_CTYPE_MASK) - newloc->lc_ctype = loc->lc_ctype; - //if (category_mask & LC_MESSAGES_MASK) - // newloc->lc_messages = loc->lc_messages; - if (category_mask & LC_MONETARY_MASK) - newloc->lc_monetary = loc->lc_monetary; - if (category_mask & LC_TIME_MASK) - newloc->lc_time = loc->lc_time; - if (category_mask & LC_NUMERIC_MASK) - newloc->lc_numeric = loc->lc_numeric; - return (locale_t)newloc; -} -static inline -void freelocale(locale_t locobj) -{ - free(locobj); -} -static inline -locale_t uselocale(locale_t newloc) -{ - return (locale_t)0; -} +#undef _CXX_isblank_l static inline -int isalnum_l(int c, locale_t locale) -{ - return __xisalnum(locale, c); -} -static inline -int isalpha_l(int c, locale_t locale) -{ - return __xisalpha(locale, c); -} -static inline -int isblank_l(int c, locale_t locale) +int _CXX_isblank_l(int c, _CXX_locale_t locale) { return __xisblank(locale, c); } +#undef _CXX_isdigit_l static inline -int iscntrl_l(int c, locale_t locale) -{ - return __xiscntrl(locale, c); -} -static inline -int isdigit_l(int c, locale_t locale) +int _CXX_isdigit_l(int c, _CXX_locale_t locale) { return __xisdigit(locale, c); } +#undef _CXX_islower_l static inline -int isgraph_l(int c, locale_t locale) -{ - return __xisgraph(locale, c); -} -static inline -int islower_l(int c, locale_t locale) +int _CXX_islower_l(int c, _CXX_locale_t locale) { return __xislower(locale, c); } +#undef _CXX_isupper_l static inline -int isprint_l(int c, locale_t locale) -{ - return __xisprint(locale, c); -} - -static inline -int ispunct_l(int c, locale_t locale) -{ - return __xispunct(locale, c); -} -static inline -int isspace_l(int c, locale_t locale) -{ - return __xisspace(locale, c); -} -static inline -int isupper_l(int c, locale_t locale) +int _CXX_isupper_l(int c, _CXX_locale_t locale) { return __xisupper(locale, c); } +#undef _CXX_isxdigit_l static inline -int isxdigit_l(int c, locale_t locale) +int _CXX_isxdigit_l(int c, _CXX_locale_t locale) { return __xisxdigit(locale, c); } +#undef _CXX_iswalpha_l static inline -int iswalnum_l(wchar_t wc, locale_t locale) -{ - return __xiswalnum(locale, wc); -} - -static inline -int iswalpha_l(wchar_t wc, locale_t locale) +int _CXX_iswalpha_l(wchar_t wc, _CXX_locale_t locale) { return __xiswalpha(locale, wc); } +#undef _CXX_iswblank_l static inline -int iswblank_l(wchar_t wc, locale_t locale) +int _CXX_iswblank_l(wchar_t wc, _CXX_locale_t locale) { return __xiswblank(locale, wc); } +#undef _CXX_iswcntrl_l static inline -int iswcntrl_l(wchar_t wc, locale_t locale) +int _CXX_iswcntrl_l(wchar_t wc, _CXX_locale_t locale) { return __xiswcntrl(locale, wc); } +#undef _CXX_iswdigit_l static inline -int iswdigit_l(wchar_t wc, locale_t locale) +int _CXX_iswdigit_l(wchar_t wc, _CXX_locale_t locale) { return __xiswdigit(locale, wc); } +#undef _CXX_iswlower_l static inline -int iswgraph_l(wchar_t wc, locale_t locale) -{ - return __xiswgraph(locale, wc); -} - -static inline -int iswlower_l(wchar_t wc, locale_t locale) +int _CXX_iswlower_l(wchar_t wc, _CXX_locale_t locale) { return __xiswlower(locale, wc); } +#undef _CXX_iswprint_l static inline -int iswprint_l(wchar_t wc, locale_t locale) +int _CXX_iswprint_l(wchar_t wc, _CXX_locale_t locale) { return __xiswprint(locale, wc); } +#undef _CXX_iswpunct_l static inline -int iswpunct_l(wchar_t wc, locale_t locale) +int _CXX_iswpunct_l(wchar_t wc, _CXX_locale_t locale) { return __xiswpunct(locale, wc); } +#undef _CXX_iswspace_l static inline -int iswspace_l(wchar_t wc, locale_t locale) +int _CXX_iswspace_l(wchar_t wc, _CXX_locale_t locale) { return __xiswspace(locale, wc); } +#undef _CXX_iswupper_l static inline -int iswupper_l(wchar_t wc, locale_t locale) +int _CXX_iswupper_l(wchar_t wc, _CXX_locale_t locale) { return __xiswupper(locale, wc); } +#undef _CXX_iswxdigit_l static inline -int iswxdigit_l(wchar_t wc, locale_t locale) +int _CXX_iswxdigit_l(wchar_t wc, _CXX_locale_t locale) { return __xiswxdigit(locale, wc); } +#undef _CXX_iswctype_l static inline -int iswctype_l(wint_t wc, wctype_t desc, locale_t locale) +int _CXX_iswctype_l(wint_t wc, wctype_t desc, _CXX_locale_t locale) { return __xiswctype(locale, wc, desc); } +#undef _CXX_toupper_l static inline -int toupper_l(int c, locale_t locale) +int _CXX_toupper_l(int c, _CXX_locale_t locale) { return __xtoupper(locale, c); } +#undef _CXX_tolower_l static inline -int tolower_l(int c, locale_t locale) +int _CXX_tolower_l(int c, _CXX_locale_t locale) { return __xtolower(locale, c); } +#undef _CXX_towupper_l static inline -wint_t towupper_l(wint_t wc, locale_t locale) +wint_t _CXX_towupper_l(wint_t wc, _CXX_locale_t locale) { return __xtowupper(locale, wc); } +#undef _CXX_towlower_l static inline -wint_t towlower_l(wint_t wc, locale_t locale) +wint_t _CXX_towlower_l(wint_t wc, _CXX_locale_t locale) { return __xtowlower(locale, wc); } +#undef _CXX_strcoll_l static inline -int strcoll_l(const char *__s1, const char *__s2, locale_t locale) +int _CXX_strcoll_l(const char *__s1, const char *__s2, _CXX_locale_t locale) { return __xstrcoll(locale, __s1, __s2); } +#undef _CXX_wcscoll_l static inline -int wcscoll_l(const wchar_t *__s1, const wchar_t *__s2, locale_t locale) +int _CXX_wcscoll_l(const wchar_t *__s1, const wchar_t *__s2, _CXX_locale_t locale) { return __xwcscoll(locale, __s1, __s2); } +#undef _CXX_strxfrm_l static inline -size_t strxfrm_l(char *__s1, const char *__s2, size_t __n, locale_t locale) +size_t _CXX_strxfrm_l(char *__s1, const char *__s2, size_t __n, _CXX_locale_t locale) { return __xstrxfrm(locale, __s1, __s2, __n); } +#undef _CXX_wcsxfrm_l static inline -size_t wcsxfrm_l(wchar_t *__ws1, const wchar_t *__ws2, size_t __n, - locale_t locale) +size_t _CXX_wcsxfrm_l(wchar_t *__ws1, const wchar_t *__ws2, size_t __n, + _CXX_locale_t locale) { return __xwcsxfrm(locale, __ws1, __ws2, __n); } @@ -265,42 +188,49 @@ // strftime_l() is defined by POSIX. However, AIX 7.1 does not have it // implemented yet. +#undef _CXX_strftime_l static inline -size_t strftime_l(char *__s, size_t __size, const char *__fmt, - const struct tm *__tm, locale_t locale) { +size_t _CXX_strftime_l(char *__s, size_t __size, const char *__fmt, + const struct tm *__tm, _CXX_locale_t locale) { return __xstrftime(locale, __s, __size, __fmt, __tm); } // The following are not POSIX routines. These are quick-and-dirty hacks // to make things pretend to work +#undef _CXX_strtoll_l static inline -long long strtoll_l(const char *__nptr, char **__endptr, - int __base, locale_t locale) { +long long _CXX_strtoll_l(const char *__nptr, char **__endptr, + int __base, _CXX_locale_t locale) { return strtoll(__nptr, __endptr, __base); } +#undef _CXX_strtol_l static inline -long strtol_l(const char *__nptr, char **__endptr, - int __base, locale_t locale) { +long _CXX_strtol_l(const char *__nptr, char **__endptr, + int __base, _CXX_locale_t locale) { return strtol(__nptr, __endptr, __base); } +#undef _CXX_strtold_l static inline -long double strtold_l(const char *__nptr, char **__endptr, - locale_t locale) { +long double _CXX_strtold_l(const char *__nptr, char **__endptr, + _CXX_locale_t locale) { return strtold(__nptr, __endptr); } +#undef _CXX_strtoull_l static inline -unsigned long long strtoull_l(const char *__nptr, char **__endptr, - int __base, locale_t locale) { +unsigned long long _CXX_strtoull_l(const char *__nptr, char **__endptr, + int __base, _CXX_locale_t locale) { return strtoull(__nptr, __endptr, __base); } +#undef _CXX_strtoul_l static inline -unsigned long strtoul_l(const char *__nptr, char **__endptr, - int __base, locale_t locale) { +unsigned long _CXX_strtoul_l(const char *__nptr, char **__endptr, + int __base, _CXX_locale_t locale) { return strtoul(__nptr, __endptr, __base); } +#undef __vasprintf static inline -int vasprintf(char **strp, const char *fmt, va_list ap) +int __vasprintf(char **strp, const char *fmt, va_list ap) { const size_t buff_size = 256; int str_size; Index: include/support/musl/xlocale.h =================================================================== --- include/support/musl/xlocale.h +++ include/support/musl/xlocale.h @@ -18,6 +18,10 @@ #ifndef _LIBCPP_SUPPORT_MUSL_XLOCALE_H #define _LIBCPP_SUPPORT_MUSL_XLOCALE_H +#if !defined(_LIBCPP_SUPPORT_XLOCALE_DEFAULTS_H) +#error "This support header must be included after support/xlocale/__defaults.h" +#endif + #include #include @@ -25,32 +29,20 @@ extern "C" { #endif -static inline long long strtoll_l(const char *nptr, char **endptr, int base, - locale_t) { +#undef _CXX_strtoll_l +static inline long long _CXX_strtoll_l(const char *nptr, char **endptr, int base, + _CXX_locale_t __loc) { + __locale_sentry __current(__loc); return strtoll(nptr, endptr, base); } -static inline unsigned long long strtoull_l(const char *nptr, char **endptr, - int base, locale_t) { +#undef _CXX_strtoull_l +static inline unsigned long long _CXX_strtoull_l(const char *nptr, char **endptr, + int base, _CXX_locale_t __loc) { + __locale_sentry __current(__loc); return strtoull(nptr, endptr, base); } -static inline long long wcstoll_l(const wchar_t *nptr, wchar_t **endptr, - int base, locale_t) { - return wcstoll(nptr, endptr, base); -} - -static inline unsigned long long wcstoull_l(const wchar_t *nptr, - wchar_t **endptr, int base, - locale_t) { - return wcstoull(nptr, endptr, base); -} - -static inline long double wcstold_l(const wchar_t *nptr, wchar_t **endptr, - locale_t) { - return wcstold(nptr, endptr); -} - #ifdef __cplusplus } #endif Index: include/support/newlib/xlocale.h =================================================================== --- include/support/newlib/xlocale.h +++ include/support/newlib/xlocale.h @@ -17,46 +17,8 @@ #include #include -#ifdef __cplusplus -extern "C" { -#endif - -// Patch over newlib's lack of extended locale support -typedef void *locale_t; -static inline locale_t duplocale(locale_t) { - return NULL; -} - -static inline void freelocale(locale_t) { -} - -static inline locale_t newlocale(int, const char *, locale_t) { - return NULL; -} - -static inline locale_t uselocale(locale_t) { - return NULL; -} - -#define LC_COLLATE_MASK (1 << LC_COLLATE) -#define LC_CTYPE_MASK (1 << LC_CTYPE) -#define LC_MESSAGES_MASK (1 << LC_MESSAGES) -#define LC_MONETARY_MASK (1 << LC_MONETARY) -#define LC_NUMERIC_MASK (1 << LC_NUMERIC) -#define LC_TIME_MASK (1 << LC_TIME) -#define LC_ALL_MASK (LC_COLLATE_MASK|\ - LC_CTYPE_MASK|\ - LC_MONETARY_MASK|\ - LC_NUMERIC_MASK|\ - LC_TIME_MASK|\ - LC_MESSAGES_MASK) - -// Share implementation with Android's Bionic -#include - -#ifdef __cplusplus -} // extern "C" -#endif +#include +#include #endif // _NEWLIB_VERSION Index: include/support/solaris/xlocale.h =================================================================== --- include/support/solaris/xlocale.h +++ include/support/solaris/xlocale.h @@ -14,52 +14,69 @@ #ifndef __XLOCALE_H_INCLUDED #define __XLOCALE_H_INCLUDED -#include +#if !defined(_LIBCPP_SUPPORT_XLOCALE_DEFAULTS_H) +#error "This support header must be included after support/xlocale/__defaults.h" +#endif +#include #ifdef __cplusplus extern "C" { #endif +#undef _CXX_snprintf_l +#undef _CXX_asprintf_l +int _CXX_snprintf_l(char *__s, size_t __n, _CXX_locale_t __l, const char *__format, ...); +int _CXX_asprintf_l(char **__s, _CXX_locale_t __l, const char *__format, ...); -int snprintf_l(char *__s, size_t __n, locale_t __l, const char *__format, ...); -int asprintf_l(char **__s, locale_t __l, const char *__format, ...); +#undef _CXX_sscanf_l +int _CXX_sscanf_l(const char *__s, _CXX_locale_t __l, const char *__format, ...); -int sscanf_l(const char *__s, locale_t __l, const char *__format, ...); - -int toupper_l(int __c, locale_t __l); -int tolower_l(int __c, locale_t __l); +#undef _CXX_toupper_l +#undef _CXX_tolower_l +int _CXX_toupper_l(int __c, _CXX_locale_t __l); +int _CXX_tolower_l(int __c, _CXX_locale_t __l); struct lconv *localeconv(void); -struct lconv *localeconv_l(locale_t __l); +#undef _CXX_localeconv_l +struct lconv *_CXX_localeconv_l(_CXX_locale_t __l); // FIXME: These are quick-and-dirty hacks to make things pretend to work +#undef _CXX_strtoll_l static inline -long long strtoll_l(const char *__nptr, char **__endptr, - int __base, locale_t __loc) { +long long _CXX_strtoll_l(const char *__nptr, char **__endptr, + int __base, _CXX_locale_t __loc) { + __locale_sentry __current(__loc); return strtoll(__nptr, __endptr, __base); } +#undef _CXX_strtol_l static inline -long strtol_l(const char *__nptr, char **__endptr, - int __base, locale_t __loc) { +long _CXX_strtol_l(const char *__nptr, char **__endptr, + int __base, _CXX_locale_t __loc) { + __locale_sentry __current(__loc); return strtol(__nptr, __endptr, __base); } +#undef _CXX_strtold_l static inline -long double strtold_l(const char *__nptr, char **__endptr, - locale_t __loc) { +long double _CXX_strtold_l(const char *__nptr, char **__endptr, + _CXX_locale_t __loc) { + __locale_sentry __current(__loc); return strtold(__nptr, __endptr); } +#undef _CXX_strtoull_l static inline -unsigned long long strtoull_l(const char *__nptr, char **__endptr, - int __base, locale_t __loc) { +unsigned long long _CXX_strtoull_l(const char *__nptr, char **__endptr, + int __base, _CXX_locale_t __loc) { + __locale_sentry __current(__loc); return strtoull(__nptr, __endptr, __base); } +#undef _CXX_strtoul_l static inline -unsigned long strtoul_l(const char *__nptr, char **__endptr, - int __base, locale_t __loc) { +unsigned long _CXX_strtoul_l(const char *__nptr, char **__endptr, + int __base, _CXX_locale_t __loc) { + __locale_sentry __current(__loc); return strtoul(__nptr, __endptr, __base); } - #ifdef __cplusplus } #endif Index: include/support/win32/builtin_support.h =================================================================== --- /dev/null +++ include/support/win32/builtin_support.h @@ -0,0 +1,149 @@ +// -*- C++ -*- +//===------------------ support/win32/builtin_support.h -------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_SUPPORT_WIN32_BUILTIN_SUPPORT_H +#define _LIBCPP_SUPPORT_WIN32_BUILTIN_SUPPORT_H + +#include + +// Bit builtin's make these assumptions when calling _BitScanForward/Reverse +// etc. These assumptions are expected to be true for Win32/Win64 which this +// file supports. +static_assert(sizeof(unsigned long long) == 8, ""); +static_assert(sizeof(unsigned long) == 4, ""); +static_assert(sizeof(unsigned int) == 4, ""); + +_LIBCPP_ALWAYS_INLINE int __builtin_popcount(unsigned int x) +{ + // Binary: 0101... + static const unsigned int m1 = 0x55555555; + // Binary: 00110011.. + static const unsigned int m2 = 0x33333333; + // Binary: 4 zeros, 4 ones ... + static const unsigned int m4 = 0x0f0f0f0f; + // The sum of 256 to the power of 0,1,2,3... + static const unsigned int h01 = 0x01010101; + // Put count of each 2 bits into those 2 bits. + x -= (x >> 1) & m1; + // Put count of each 4 bits into those 4 bits. + x = (x & m2) + ((x >> 2) & m2); + // Put count of each 8 bits into those 8 bits. + x = (x + (x >> 4)) & m4; + // Returns left 8 bits of x + (x<<8) + (x<<16) + (x<<24). + return (x * h01) >> 24; +} + +_LIBCPP_ALWAYS_INLINE int __builtin_popcountl(unsigned long x) +{ + return __builtin_popcount(static_cast(x)); +} + +_LIBCPP_ALWAYS_INLINE int __builtin_popcountll(unsigned long long x) +{ + // Binary: 0101... + static const unsigned long long m1 = 0x5555555555555555; + // Binary: 00110011.. + static const unsigned long long m2 = 0x3333333333333333; + // Binary: 4 zeros, 4 ones ... + static const unsigned long long m4 = 0x0f0f0f0f0f0f0f0f; + // The sum of 256 to the power of 0,1,2,3... + static const unsigned long long h01 = 0x0101010101010101; + // Put count of each 2 bits into those 2 bits. + x -= (x >> 1) & m1; + // Put count of each 4 bits into those 4 bits. + x = (x & m2) + ((x >> 2) & m2); + // Put count of each 8 bits into those 8 bits. + x = (x + (x >> 4)) & m4; + // Returns left 8 bits of x + (x<<8) + (x<<16) + (x<<24) + ... + return static_cast((x * h01) >> 56); +} + +// Returns the number of trailing 0-bits in x, starting at the least significant +// bit position. If x is 0, the result is undefined. +_LIBCPP_ALWAYS_INLINE int __builtin_ctzll(unsigned long long mask) +{ + unsigned long where; +// Search from LSB to MSB for first set bit. +// Returns zero if no set bit is found. +#if defined(_WIN64) + if (_BitScanForward64(&where, mask)) + return static_cast(where); +#elif defined(_WIN32) + // Win32 doesn't have _BitScanForward64 so emulate it with two 32 bit calls. + // Scan the Low Word. + if (_BitScanForward(&where, static_cast(mask))) + return static_cast(where); + // Scan the High Word. + if (_BitScanForward(&where, static_cast(mask >> 32))) + return static_cast(where + 32); // Create a bit offset from the LSB. +#else +#error "Implementation of __builtin_ctzll required" +#endif + return 64; +} + +_LIBCPP_ALWAYS_INLINE int __builtin_ctzl(unsigned long mask) +{ + unsigned long where; + // Search from LSB to MSB for first set bit. + // Returns zero if no set bit is found. + if (_BitScanForward(&where, mask)) + return static_cast(where); + return 32; +} + +_LIBCPP_ALWAYS_INLINE int __builtin_ctz(unsigned int mask) +{ + // Win32 and Win64 expectations. + static_assert(sizeof(mask) == 4, ""); + static_assert(sizeof(unsigned long) == 4, ""); + return __builtin_ctzl(static_cast(mask)); +} + +// Returns the number of leading 0-bits in x, starting at the most significant +// bit position. If x is 0, the result is undefined. +_LIBCPP_ALWAYS_INLINE int __builtin_clzll(unsigned long long mask) +{ + unsigned long where; +// BitScanReverse scans from MSB to LSB for first set bit. +// Returns 0 if no set bit is found. +#if defined(_WIN64) + if (_BitScanReverse64(&where, mask)) + return static_cast(63 - where); +#elif defined(_WIN32) + // Scan the high 32 bits. + if (_BitScanReverse(&where, static_cast(mask >> 32))) + return static_cast(63 - + (where + 32)); // Create a bit offset from the MSB. + // Scan the low 32 bits. + if (_BitScanReverse(&where, static_cast(mask))) + return static_cast(63 - where); +#else +#error "Implementation of __builtin_clzll required" +#endif + return 64; // Undefined Behavior. +} + +_LIBCPP_ALWAYS_INLINE int __builtin_clzl(unsigned long mask) +{ + unsigned long where; + // Search from LSB to MSB for first set bit. + // Returns zero if no set bit is found. + if (_BitScanReverse(&where, mask)) + return static_cast(31 - where); + return 32; // Undefined Behavior. +} + +_LIBCPP_ALWAYS_INLINE int __builtin_clz(unsigned int x) +{ + return __builtin_clzl(x); +} + +#endif // _LIBCPP_SUPPORT_WIN32_BUILTIN_SUPPORT_H Index: include/support/win32/locale_mgmt_win32.h =================================================================== --- /dev/null +++ include/support/win32/locale_mgmt_win32.h @@ -0,0 +1,50 @@ +// -*- C++ -*- +//===----------------- support/win32/locale_mgmt_win32.h ------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_SUPPORT_WIN32_LOCALE_MGMT_WIN32_H +#define _LIBCPP_SUPPORT_WIN32_LOCALE_MGMT_WIN32_H + +#if !defined(_LIBCPP_SUPPORT_XLOCALE_LOCALE_MANAGEMENT_H) +#error "This must be included inside support/xlocale/__locale_management.h" +#endif + +#include + +#undef _CXX_locale_t +#undef _CXX_freelocale +#undef _CXX_newlocale +#undef _CXX_uselocale +#undef _CXX_LC_COLLATE_MASK +#undef _CXX_LC_CTYPE_MASK +#undef _CXX_LC_MESSAGES_MASK +#undef _CXX_LC_MONETARY_MASK +#undef _CXX_LC_NUMERIC_MASK +#undef _CXX_LC_TIME_MASK +#undef _CXX_LC_ALL_MASK + +#define _CXX_locale_t _locale_t +#define _CXX_LC_COLLATE_MASK _M_COLLATE +#define _CXX_LC_CTYPE_MASK _M_CTYPE +#define _CXX_LC_MONETARY_MASK _M_MONETARY +#define _CXX_LC_NUMERIC_MASK _M_NUMERIC +#define _CXX_LC_TIME_MASK _M_TIME +#define _CXX_LC_MESSAGES_MASK _M_MESSAGES +#define _CXX_LC_ALL_MASK ( _CXX_LC_COLLATE_MASK \ + | _CXX_LC_CTYPE_MASK \ + | _CXX_LC_MESSAGES_MASK \ + | _CXX_LC_MONETARY_MASK \ + | _CXX_LC_NUMERIC_MASK \ + | _CXX_LC_TIME_MASK ) +#define _CXX_freelocale _free_locale +// FIXME: base currently unused. Needs manual work to construct the new locale +_CXX_locale_t _CXX_newlocale( int mask, const char * locale, _CXX_locale_t base ); +_CXX_locale_t _CXX_uselocale( _CXX_locale_t newloc ); + +#endif // _LIBCPP_SUPPORT_WIN32_LOCALE_MGMT_WIN32_H Index: include/support/win32/locale_win32.h =================================================================== --- include/support/win32/locale_win32.h +++ include/support/win32/locale_win32.h @@ -11,119 +11,129 @@ #ifndef _LIBCPP_SUPPORT_WIN32_LOCALE_WIN32_H #define _LIBCPP_SUPPORT_WIN32_LOCALE_WIN32_H -// ctype mask table defined in msvcrt.dll -extern "C" unsigned short __declspec(dllimport) _ctype[]; +#if !defined(_LIBCPP_SUPPORT_XLOCALE_DEFAULTS_H) +#error "This support header must be included after support/xlocale/__defaults.h" +#endif #include "support/win32/support.h" #include #include -#include // _locale_t -#define locale_t _locale_t -#define LC_COLLATE_MASK _M_COLLATE -#define LC_CTYPE_MASK _M_CTYPE -#define LC_MONETARY_MASK _M_MONETARY -#define LC_NUMERIC_MASK _M_NUMERIC -#define LC_TIME_MASK _M_TIME -#define LC_MESSAGES_MASK _M_MESSAGES -#define LC_ALL_MASK ( LC_COLLATE_MASK \ - | LC_CTYPE_MASK \ - | LC_MESSAGES_MASK \ - | LC_MONETARY_MASK \ - | LC_NUMERIC_MASK \ - | LC_TIME_MASK ) -#define freelocale _free_locale -// FIXME: base currently unused. Needs manual work to construct the new locale -locale_t newlocale( int mask, const char * locale, locale_t base ); -locale_t uselocale( locale_t newloc ); -lconv *localeconv_l( locale_t loc ); -size_t mbrlen_l( const char *__restrict s, size_t n, - mbstate_t *__restrict ps, locale_t loc); -size_t mbsrtowcs_l( wchar_t *__restrict dst, const char **__restrict src, - size_t len, mbstate_t *__restrict ps, locale_t loc ); -size_t wcrtomb_l( char *__restrict s, wchar_t wc, mbstate_t *__restrict ps, - locale_t loc); -size_t mbrtowc_l( wchar_t *__restrict pwc, const char *__restrict s, - size_t n, mbstate_t *__restrict ps, locale_t loc); -size_t mbsnrtowcs_l( wchar_t *__restrict dst, const char **__restrict src, - size_t nms, size_t len, mbstate_t *__restrict ps, locale_t loc); -size_t wcsnrtombs_l( char *__restrict dst, const wchar_t **__restrict src, - size_t nwc, size_t len, mbstate_t *__restrict ps, locale_t loc); -wint_t btowc_l( int c, locale_t loc ); -int wctob_l( wint_t c, locale_t loc ); -typedef _VSTD::remove_pointer::type __locale_struct; -typedef _VSTD::unique_ptr<__locale_struct, decltype(&uselocale)> __locale_raii; +#include + +#undef _CXX_mb_cur_max_l +#undef _CXX_btowc_l +#undef _CXX_wctob_l +#undef _CXX_wcsnrtombs_l +#undef _CXX_wcrtomb_l +#undef _CXX_mbsnrtowcs_l +#undef _CXX_mbrtowc_l +#undef _CXX_mbtowc_l +#undef _CXX_mbrlen_l +#undef _CXX_localeconv_l +#undef _CXX_mbsrtowcs_l +#undef _CXX_snprintf_l +#undef _CXX_asprintf_l +#undef _CXX_sscanf_l +#undef _CXX_isblank_l +#undef _CXX_isdigit_l +#undef _CXX_islower_l +#undef _CXX_isupper_l +#undef _CXX_isxdigit_l +#undef _CXX_iswalpha_l +#undef _CXX_iswblank_l +#undef _CXX_iswcntrl_l +#undef _CXX_iswdigit_l +#undef _CXX_iswlower_l +#undef _CXX_iswprint_l +#undef _CXX_iswpunct_l +#undef _CXX_iswspace_l +#undef _CXX_iswupper_l +#undef _CXX_iswxdigit_l +#undef _CXX_toupper_l +#undef _CXX_tolower_l +#undef _CXX_towupper_l +#undef _CXX_towlower_l +#undef _CXX_strcoll_l +#undef _CXX_strxfrm_l +#undef _CXX_strftime_l +#undef _CXX_wcscoll_l +#undef _CXX_wcsxfrm_l +#undef _CXX_strtold_l +#undef _CXX_strtoll_l +#undef _CXX_strtoull_l + +lconv *_CXX_localeconv_l( _CXX_locale_t loc ); +size_t _CXX_mbrlen_l( const char *__restrict s, size_t n, + mbstate_t *__restrict ps, _CXX_locale_t loc); +size_t _CXX_mbsrtowcs_l( wchar_t *__restrict dst, const char **__restrict src, + size_t len, mbstate_t *__restrict ps, _CXX_locale_t loc ); +size_t _CXX_wcrtomb_l( char *__restrict s, wchar_t wc, mbstate_t *__restrict ps, + _CXX_locale_t loc); +size_t _CXX_mbrtowc_l( wchar_t *__restrict pwc, const char *__restrict s, + size_t n, mbstate_t *__restrict ps, _CXX_locale_t loc); +size_t _CXX_mbsnrtowcs_l( wchar_t *__restrict dst, const char **__restrict src, + size_t nms, size_t len, mbstate_t *__restrict ps, _CXX_locale_t loc); +size_t _CXX_wcsnrtombs_l( char *__restrict dst, const wchar_t **__restrict src, + size_t nwc, size_t len, mbstate_t *__restrict ps, _CXX_locale_t loc); +wint_t _CXX_btowc_l( int c, _CXX_locale_t loc ); +int _CXX_wctob_l( wint_t c, _CXX_locale_t loc ); inline _LIBCPP_ALWAYS_INLINE -decltype(MB_CUR_MAX) MB_CUR_MAX_L( locale_t __l ) +decltype(MB_CUR_MAX) _CXX_mb_cur_max_l( _CXX_locale_t __l ) { - __locale_raii __current( uselocale(__l), uselocale ); + __locale_sentry __current(__l); return MB_CUR_MAX; } // the *_l functions are prefixed on Windows, only available for msvcr80+, VS2005+ -#define mbtowc_l _mbtowc_l -#define strtoll_l _strtoi64_l -#define strtoull_l _strtoui64_l +#define _CXX_mbtowc_l _mbtowc_l +#define _CXX_strtoll_l _strtoi64_l +#define _CXX_strtoull_l _strtoui64_l // FIXME: current msvcrt does not know about long double -#define strtold_l _strtod_l +#define _CXX_strtold_l _strtod_l inline _LIBCPP_INLINE_VISIBILITY int -islower_l(int c, _locale_t loc) +_CXX_islower_l(int c, _locale_t loc) { return _islower_l((int)c, loc); } inline _LIBCPP_INLINE_VISIBILITY int -isupper_l(int c, _locale_t loc) +_CXX_isupper_l(int c, _locale_t loc) { return _isupper_l((int)c, loc); } -#define isdigit_l _isdigit_l -#define isxdigit_l _isxdigit_l -#define strcoll_l _strcoll_l -#define strxfrm_l _strxfrm_l -#define wcscoll_l _wcscoll_l -#define wcsxfrm_l _wcsxfrm_l -#define toupper_l _toupper_l -#define tolower_l _tolower_l -#define iswspace_l _iswspace_l -#define iswprint_l _iswprint_l -#define iswcntrl_l _iswcntrl_l -#define iswupper_l _iswupper_l -#define iswlower_l _iswlower_l -#define iswalpha_l _iswalpha_l -#define iswdigit_l _iswdigit_l -#define iswpunct_l _iswpunct_l -#define iswxdigit_l _iswxdigit_l -#define towupper_l _towupper_l -#define towlower_l _towlower_l -#define strftime_l _strftime_l -#define sscanf_l( __s, __l, __f, ...) _sscanf_l( __s, __f, __l, __VA_ARGS__ ) -#define vsscanf_l( __s, __l, __f, ...) _sscanf_l( __s, __f, __l, __VA_ARGS__ ) -#define sprintf_l( __s, __l, __f, ... ) _sprintf_l( __s, __f, __l, __VA_ARGS__ ) -#define vsprintf_l( __s, __l, __f, ... ) _vsprintf_l( __s, __f, __l, __VA_ARGS__ ) -#define vsnprintf_l( __s, __n, __l, __f, ... ) _vsnprintf_l( __s, __n, __f, __l, __VA_ARGS__ ) -int snprintf_l(char *ret, size_t n, locale_t loc, const char *format, ...); -int asprintf_l( char **ret, locale_t loc, const char *format, ... ); -int vasprintf_l( char **ret, locale_t loc, const char *format, va_list ap ); - - -// not-so-pressing FIXME: use locale to determine blank characters -inline int isblank_l( int c, locale_t /*loc*/ ) -{ - return ( c == ' ' || c == '\t' ); -} -inline int iswblank_l( wint_t c, locale_t /*loc*/ ) -{ - return ( c == L' ' || c == L'\t' ); -} +#define _CXX_isblank_l _isblank_l +#define _CXX_isdigit_l _isdigit_l +#define _CXX_isxdigit_l _isxdigit_l +#define _CXX_strcoll_l _strcoll_l +#define _CXX_strxfrm_l _strxfrm_l +#define _CXX_wcscoll_l _wcscoll_l +#define _CXX_wcsxfrm_l _wcsxfrm_l +#define _CXX_toupper_l _toupper_l +#define _CXX_tolower_l _tolower_l +#define _CXX_iswblank_l _iswblank_l +#define _CXX_iswspace_l _iswspace_l +#define _CXX_iswprint_l _iswprint_l +#define _CXX_iswcntrl_l _iswcntrl_l +#define _CXX_iswupper_l _iswupper_l +#define _CXX_iswlower_l _iswlower_l +#define _CXX_iswalpha_l _iswalpha_l +#define _CXX_iswdigit_l _iswdigit_l +#define _CXX_iswpunct_l _iswpunct_l +#define _CXX_iswxdigit_l _iswxdigit_l +#define _CXX_towupper_l _towupper_l +#define _CXX_towlower_l _towlower_l +#define _CXX_strftime_l _strftime_l +#define _CXX_sscanf_l( __s, __l, __f, ...) _sscanf_l( __s, __f, __l, __VA_ARGS__ ) +#define _CXX_vsscanf_l( __s, __l, __f, ...) _sscanf_l( __s, __f, __l, __VA_ARGS__ ) +#define _CXX_sprintf_l( __s, __l, __f, ... ) _sprintf_l( __s, __f, __l, __VA_ARGS__ ) +#define _CXX_vsprintf_l( __s, __l, __f, ... ) _vsprintf_l( __s, __f, __l, __VA_ARGS__ ) +#define _CXX_vsnprintf_l( __s, __n, __l, __f, ... ) _vsnprintf_l( __s, __n, __f, __l, __VA_ARGS__ ) +int _CXX_snprintf_l(char *ret, size_t n, _CXX_locale_t loc, const char *format, ...); +int _CXX_asprintf_l( char **ret, _CXX_locale_t loc, const char *format, ... ); +int _CXX_vasprintf_l( char **ret, _CXX_locale_t loc, const char *format, va_list ap ); -#if defined(_LIBCPP_MSVCRT) -inline int isblank( int c, locale_t /*loc*/ ) -{ return ( c == ' ' || c == '\t' ); } -inline int iswblank( wint_t c, locale_t /*loc*/ ) -{ return ( c == L' ' || c == L'\t' ); } -#endif // _LIBCPP_MSVCRT #endif // _LIBCPP_SUPPORT_WIN32_LOCALE_WIN32_H Index: include/support/win32/support.h =================================================================== --- include/support/win32/support.h +++ include/support/win32/support.h @@ -1,5 +1,5 @@ // -*- C++ -*- -//===----------------------- support/win32/support.h ----------------------===// +//===--------------------- support/win32/support.h ------------------------===// // // The LLVM Compiler Infrastructure // @@ -16,14 +16,10 @@ #include // mbstate_t #include // va_ macros -// "builtins" not implemented here for Clang or GCC as they provide -// implementations. Assuming required for elsewhere else, certainly MSVC. -#if defined(_LIBCPP_MSVC) -#include -#endif #if defined(_LIBCPP_MSVCRT) #include #endif + #define swprintf _snwprintf #define vswprintf _vsnwprintf @@ -31,19 +27,6 @@ #define NOMINMAX #endif -// The mingw headers already define these as static. -#ifndef __MINGW32__ -extern "C" { - -int vasprintf(char **sptr, const char *__restrict fmt, va_list ap); -int asprintf(char **sptr, const char *__restrict fmt, ...); -size_t mbsnrtowcs(wchar_t *__restrict dst, const char **__restrict src, - size_t nmc, size_t len, mbstate_t *__restrict ps); -size_t wcsnrtombs(char *__restrict dst, const wchar_t **__restrict src, - size_t nwc, size_t len, mbstate_t *__restrict ps); -} -#endif // __MINGW32__ - #if defined(_LIBCPP_MSVCRT) #define snprintf _snprintf #define atoll _atoi64 @@ -67,140 +50,4 @@ #define _Exit _exit #endif -#if defined(_LIBCPP_MSVC) - -// Bit builtin's make these assumptions when calling _BitScanForward/Reverse -// etc. These assumptions are expected to be true for Win32/Win64 which this -// file supports. -static_assert(sizeof(unsigned long long) == 8, ""); -static_assert(sizeof(unsigned long) == 4, ""); -static_assert(sizeof(unsigned int) == 4, ""); - -_LIBCPP_ALWAYS_INLINE int __builtin_popcount(unsigned int x) -{ - // Binary: 0101... - static const unsigned int m1 = 0x55555555; - // Binary: 00110011.. - static const unsigned int m2 = 0x33333333; - // Binary: 4 zeros, 4 ones ... - static const unsigned int m4 = 0x0f0f0f0f; - // The sum of 256 to the power of 0,1,2,3... - static const unsigned int h01 = 0x01010101; - // Put count of each 2 bits into those 2 bits. - x -= (x >> 1) & m1; - // Put count of each 4 bits into those 4 bits. - x = (x & m2) + ((x >> 2) & m2); - // Put count of each 8 bits into those 8 bits. - x = (x + (x >> 4)) & m4; - // Returns left 8 bits of x + (x<<8) + (x<<16) + (x<<24). - return (x * h01) >> 24; -} - -_LIBCPP_ALWAYS_INLINE int __builtin_popcountl(unsigned long x) -{ - return __builtin_popcount(static_cast(x)); -} - -_LIBCPP_ALWAYS_INLINE int __builtin_popcountll(unsigned long long x) -{ - // Binary: 0101... - static const unsigned long long m1 = 0x5555555555555555; - // Binary: 00110011.. - static const unsigned long long m2 = 0x3333333333333333; - // Binary: 4 zeros, 4 ones ... - static const unsigned long long m4 = 0x0f0f0f0f0f0f0f0f; - // The sum of 256 to the power of 0,1,2,3... - static const unsigned long long h01 = 0x0101010101010101; - // Put count of each 2 bits into those 2 bits. - x -= (x >> 1) & m1; - // Put count of each 4 bits into those 4 bits. - x = (x & m2) + ((x >> 2) & m2); - // Put count of each 8 bits into those 8 bits. - x = (x + (x >> 4)) & m4; - // Returns left 8 bits of x + (x<<8) + (x<<16) + (x<<24) + ... - return static_cast((x * h01) >> 56); -} - -// Returns the number of trailing 0-bits in x, starting at the least significant -// bit position. If x is 0, the result is undefined. -_LIBCPP_ALWAYS_INLINE int __builtin_ctzll(unsigned long long mask) -{ - unsigned long where; -// Search from LSB to MSB for first set bit. -// Returns zero if no set bit is found. -#if defined(_WIN64) - if (_BitScanForward64(&where, mask)) - return static_cast(where); -#elif defined(_WIN32) - // Win32 doesn't have _BitScanForward64 so emulate it with two 32 bit calls. - // Scan the Low Word. - if (_BitScanForward(&where, static_cast(mask))) - return static_cast(where); - // Scan the High Word. - if (_BitScanForward(&where, static_cast(mask >> 32))) - return static_cast(where + 32); // Create a bit offset from the LSB. -#else -#error "Implementation of __builtin_ctzll required" -#endif - return 64; -} - -_LIBCPP_ALWAYS_INLINE int __builtin_ctzl(unsigned long mask) -{ - unsigned long where; - // Search from LSB to MSB for first set bit. - // Returns zero if no set bit is found. - if (_BitScanForward(&where, mask)) - return static_cast(where); - return 32; -} - -_LIBCPP_ALWAYS_INLINE int __builtin_ctz(unsigned int mask) -{ - // Win32 and Win64 expectations. - static_assert(sizeof(mask) == 4, ""); - static_assert(sizeof(unsigned long) == 4, ""); - return __builtin_ctzl(static_cast(mask)); -} - -// Returns the number of leading 0-bits in x, starting at the most significant -// bit position. If x is 0, the result is undefined. -_LIBCPP_ALWAYS_INLINE int __builtin_clzll(unsigned long long mask) -{ - unsigned long where; -// BitScanReverse scans from MSB to LSB for first set bit. -// Returns 0 if no set bit is found. -#if defined(_WIN64) - if (_BitScanReverse64(&where, mask)) - return static_cast(63 - where); -#elif defined(_WIN32) - // Scan the high 32 bits. - if (_BitScanReverse(&where, static_cast(mask >> 32))) - return static_cast(63 - - (where + 32)); // Create a bit offset from the MSB. - // Scan the low 32 bits. - if (_BitScanReverse(&where, static_cast(mask))) - return static_cast(63 - where); -#else -#error "Implementation of __builtin_clzll required" -#endif - return 64; // Undefined Behavior. -} - -_LIBCPP_ALWAYS_INLINE int __builtin_clzl(unsigned long mask) -{ - unsigned long where; - // Search from LSB to MSB for first set bit. - // Returns zero if no set bit is found. - if (_BitScanReverse(&where, mask)) - return static_cast(31 - where); - return 32; // Undefined Behavior. -} - -_LIBCPP_ALWAYS_INLINE int __builtin_clz(unsigned int x) -{ - return __builtin_clzl(x); -} -#endif // _LIBCPP_MSVC - #endif // _LIBCPP_SUPPORT_WIN32_SUPPORT_H Index: include/support/xlocale/__defaults.h =================================================================== --- /dev/null +++ include/support/xlocale/__defaults.h @@ -0,0 +1,59 @@ +// -*- C++ -*- +//===----------------- support/xlocale/__defaults.h -------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_SUPPORT_XLOCALE_DEFAULTS_H +#define _LIBCPP_SUPPORT_XLOCALE_DEFAULTS_H + +// BSD-only *_l functions and macros +#define _CXX_mb_cur_max_l MB_CUR_MAX_L +#define _CXX_btowc_l btowc_l +#define _CXX_wctob_l wctob_l +#define _CXX_wcsnrtombs_l wcsnrtombs_l +#define _CXX_wcrtomb_l wcrtomb_l +#define _CXX_mbsnrtowcs_l mbsnrtowcs_l +#define _CXX_mbrtowc_l mbrtowc_l +#define _CXX_mbtowc_l mbtowc_l +#define _CXX_mbrlen_l mbrlen_l +#define _CXX_localeconv_l localeconv_l +#define _CXX_mbsrtowcs_l mbsrtowcs_l +#define _CXX_snprintf_l snprintf_l +#define _CXX_asprintf_l asprintf_l +#define _CXX_sscanf_l sscanf_l +#define _CXX_strcoll_l strcoll_l +#define _CXX_strxfrm_l strxfrm_l +#define _CXX_strftime_l strftime_l +#define _CXX_strtold_l strtold_l +#define _CXX_strtoll_l strtoll_l +#define _CXX_strtoull_l strtoull_l + +// POSIX-only *_l functions and macros +#define _CXX_isblank_l isblank_l +#define _CXX_isdigit_l isdigit_l +#define _CXX_islower_l islower_l +#define _CXX_isupper_l isupper_l +#define _CXX_isxdigit_l isxdigit_l +#define _CXX_iswalpha_l iswalpha_l +#define _CXX_iswblank_l iswblank_l +#define _CXX_iswcntrl_l iswcntrl_l +#define _CXX_iswdigit_l iswdigit_l +#define _CXX_iswlower_l iswlower_l +#define _CXX_iswprint_l iswprint_l +#define _CXX_iswpunct_l iswpunct_l +#define _CXX_iswspace_l iswspace_l +#define _CXX_iswupper_l iswupper_l +#define _CXX_iswxdigit_l iswxdigit_l +#define _CXX_toupper_l toupper_l +#define _CXX_tolower_l tolower_l +#define _CXX_towupper_l towupper_l +#define _CXX_towlower_l towlower_l +#define _CXX_wcscoll_l wcscoll_l +#define _CXX_wcsxfrm_l wcsxfrm_l + +#endif // _LIBCPP_SUPPORT_XLOCALE_DEFAULTS_H Index: include/support/xlocale/__locale_management.h =================================================================== --- /dev/null +++ include/support/xlocale/__locale_management.h @@ -0,0 +1,58 @@ +// -*- C++ -*- +//===---------------- support/xlocale/__locale_management.h -------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_SUPPORT_XLOCALE_LOCALE_MANAGEMENT_H +#define _LIBCPP_SUPPORT_XLOCALE_LOCALE_MANAGEMENT_H + +// POSIX-only locale management functions and macros +#define _CXX_locale_t locale_t +#define _CXX_freelocale freelocale +#define _CXX_newlocale newlocale +#define _CXX_uselocale uselocale +#define _CXX_LC_COLLATE_MASK LC_COLLATE_MASK +#define _CXX_LC_CTYPE_MASK LC_CTYPE_MASK +#define _CXX_LC_MESSAGES_MASK LC_MESSAGES_MASK +#define _CXX_LC_MONETARY_MASK LC_MONETARY_MASK +#define _CXX_LC_NUMERIC_MASK LC_NUMERIC_MASK +#define _CXX_LC_TIME_MASK LC_TIME_MASK +#define _CXX_LC_ALL_MASK LC_ALL_MASK + +#if defined(__sun__) || defined(__GLIBC__) || defined(__APPLE__) \ + || defined(__FreeBSD__) || defined(__EMSCRIPTEN__) || defined(__IBMCPP__) +# include +#endif + +#if defined(_LIBCPP_HAS_NO_LOCALE_EXTENSIONS) || defined(_NEWLIB_VERSION) +# include +#elif defined(__ANDROID__) +// Android gained the locale aware functions in L (API level 21) +# include +# if __ANDROID_API__ <= 20 +# include +# endif +#elif defined(_LIBCPP_MSVCRT) || defined(__MINGW32__) +# include +#elif defined(_AIX) +# include +#endif + +class __locale_sentry +{ +public: + explicit __locale_sentry(_CXX_locale_t __l_arg) : __l(_CXX_uselocale(__l_arg)) {} + ~__locale_sentry() {_CXX_uselocale(__l);} + + __locale_sentry(const __locale_sentry &) = delete; + __locale_sentry &operator=(const __locale_sentry &) = delete; +private: + _CXX_locale_t __l; +}; + +#endif // _LIBCPP_SUPPORT_XLOCALE_LOCALE_MANAGEMENT_H Index: include/support/xlocale/__non_bsd_defaults.h =================================================================== --- /dev/null +++ include/support/xlocale/__non_bsd_defaults.h @@ -0,0 +1,186 @@ +// -*- C++ -*- +//===--------------- support/xlocale/__non_bsd_defaults.h -----------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// This is a shared implementation of a shim to provide extended locale support +// on top of libc's that don't support it (like Android's bionic, and Newlib). +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_SUPPORT_XLOCALE_NON_BSD_DEFAULTS_H +#define _LIBCPP_SUPPORT_XLOCALE_NON_BSD_DEFAULTS_H + +#include + +#undef _CXX_mb_cur_max_l +#undef _CXX_btowc_l +#undef _CXX_wctob_l +#undef _CXX_wcsnrtombs_l +#undef _CXX_wcrtomb_l +#undef _CXX_mbsnrtowcs_l +#undef _CXX_mbrtowc_l +#undef _CXX_mbtowc_l +#undef _CXX_mbrlen_l +#undef _CXX_localeconv_l +#undef _CXX_mbsrtowcs_l +#undef _CXX_snprintf_l +#undef _CXX_asprintf_l +#undef _CXX_sscanf_l +#undef _CXX_strcoll_l +#undef _CXX_strxfrm_l +#undef _CXX_strftime_l +#undef _CXX_strtold_l +#undef _CXX_strtoll_l +#undef _CXX_strtoull_l + +inline _LIBCPP_ALWAYS_INLINE +decltype(MB_CUR_MAX) _CXX_mb_cur_max_l(_CXX_locale_t __l) +{ + __locale_sentry __current(__l); + return MB_CUR_MAX; +} + +inline _LIBCPP_ALWAYS_INLINE +wint_t _CXX_btowc_l(int __c, _CXX_locale_t __l) +{ + __locale_sentry __current(__l); + return btowc(__c); +} + +inline _LIBCPP_ALWAYS_INLINE +int _CXX_wctob_l(wint_t __c, _CXX_locale_t __l) +{ + __locale_sentry __current(__l); + return wctob(__c); +} + +inline _LIBCPP_ALWAYS_INLINE +size_t _CXX_wcsnrtombs_l(char *__dest, const wchar_t **__src, size_t __nwc, + size_t __len, mbstate_t *__ps, _CXX_locale_t __l) +{ + __locale_sentry __current(__l); + return wcsnrtombs(__dest, __src, __nwc, __len, __ps); +} + +inline _LIBCPP_ALWAYS_INLINE +size_t _CXX_wcrtomb_l(char *__s, wchar_t __wc, mbstate_t *__ps, _CXX_locale_t __l) +{ + __locale_sentry __current(__l); + return wcrtomb(__s, __wc, __ps); +} + +inline _LIBCPP_ALWAYS_INLINE +size_t _CXX_mbsnrtowcs_l(wchar_t * __dest, const char **__src, size_t __nms, + size_t __len, mbstate_t *__ps, _CXX_locale_t __l) +{ + __locale_sentry __current(__l); + return mbsnrtowcs(__dest, __src, __nms, __len, __ps); +} + +inline _LIBCPP_ALWAYS_INLINE +size_t _CXX_mbrtowc_l(wchar_t *__pwc, const char *__s, size_t __n, + mbstate_t *__ps, _CXX_locale_t __l) +{ + __locale_sentry __current(__l); + return mbrtowc(__pwc, __s, __n, __ps); +} + +inline _LIBCPP_ALWAYS_INLINE +int _CXX_mbtowc_l(wchar_t *__pwc, const char *__pmb, size_t __max, _CXX_locale_t __l) +{ + __locale_sentry __current(__l); + return mbtowc(__pwc, __pmb, __max); +} + +inline _LIBCPP_ALWAYS_INLINE +size_t _CXX_mbrlen_l(const char *__s, size_t __n, mbstate_t *__ps, _CXX_locale_t __l) +{ + __locale_sentry __current(__l); + return mbrlen(__s, __n, __ps); +} + +inline _LIBCPP_ALWAYS_INLINE +lconv *_CXX_localeconv_l(_CXX_locale_t __l) +{ + __locale_sentry __current(__l); + return localeconv(); +} + +inline _LIBCPP_ALWAYS_INLINE +size_t _CXX_mbsrtowcs_l(wchar_t *__dest, const char **__src, size_t __len, + mbstate_t *__ps, _CXX_locale_t __l) +{ + __locale_sentry __current(__l); + return mbsrtowcs(__dest, __src, __len, __ps); +} + +inline +int _CXX_snprintf_l(char *__s, size_t __n, _CXX_locale_t __l, const char *__format, ...) { + va_list __va; + va_start(__va, __format); + __locale_sentry __current(__l); + int __res = vsnprintf(__s, __n, __format, __va); + va_end(__va); + return __res; +} + +inline +int _CXX_asprintf_l(char **__s, _CXX_locale_t __l, const char *__format, ...) { + va_list __va; + va_start(__va, __format); + __locale_sentry __current(__l); + int __res = vasprintf(__s, __format, __va); + va_end(__va); + return __res; +} + +inline +int _CXX_sscanf_l(const char *__s, _CXX_locale_t __l, const char *__format, ...) { + va_list __va; + va_start(__va, __format); + __locale_sentry __current(__l); + int __res = vsscanf(__s, __format, __va); + va_end(__va); + return __res; +} + +static inline int _CXX_strcoll_l(const char *s1, const char *s2, _CXX_locale_t __l) { + __locale_sentry __current(__l); + return strcoll(s1, s2); +} + +static inline size_t _CXX_strxfrm_l(char *dest, const char *src, size_t n, + _CXX_locale_t __l) { + __locale_sentry __current(__l); + return strxfrm(dest, src, n); +} + +static inline size_t _CXX_strftime_l(char *s, size_t max, const char *format, + const struct tm *tm, _CXX_locale_t __l) { + __locale_sentry __current(__l); + return strftime(s, max, format, tm); +} + +static inline long double _CXX_strtold_l(const char *nptr, char **endptr, + _CXX_locale_t __l) { + __locale_sentry __current(__l); + return strtold(nptr, endptr); +} + +static inline long long _CXX_strtoll_l(const char *nptr, char **endptr, int base, + _CXX_locale_t __l) { + __locale_sentry __current(__l); + return strtoll(nptr, endptr, base); +} + +static inline unsigned long long _CXX_strtoull_l(const char *nptr, char **endptr, + int base, _CXX_locale_t __l) { + __locale_sentry __current(__l); + return strtoull(nptr, endptr, base); +} + +#endif // _LIBCPP_SUPPORT_XLOCALE_NON_BSD_DEFAULTS_H Index: include/support/xlocale/__non_posix_ctype_defaults.h =================================================================== --- /dev/null +++ include/support/xlocale/__non_posix_ctype_defaults.h @@ -0,0 +1,146 @@ +// -*- C++ -*- +//===------------ support/xlocale/__non_posix_ctype_defaults.h ------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// This is a shared implementation of a shim to provide extended locale support +// on top of libc's that don't support it (like Android's bionic, and Newlib). +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_SUPPORT_XLOCALE_NON_POSIX_CTYPE_DEFAULTS_H +#define _LIBCPP_SUPPORT_XLOCALE_NON_POSIX_CTYPE_DEFAULTS_H + +#undef _CXX_isblank_l +#undef _CXX_isdigit_l +#undef _CXX_islower_l +#undef _CXX_isupper_l +#undef _CXX_isxdigit_l +#undef _CXX_iswalpha_l +#undef _CXX_iswblank_l +#undef _CXX_iswcntrl_l +#undef _CXX_iswdigit_l +#undef _CXX_iswlower_l +#undef _CXX_iswprint_l +#undef _CXX_iswpunct_l +#undef _CXX_iswspace_l +#undef _CXX_iswupper_l +#undef _CXX_iswxdigit_l +#undef _CXX_toupper_l +#undef _CXX_tolower_l +#undef _CXX_towupper_l +#undef _CXX_towlower_l +#undef _CXX_wcscoll_l +#undef _CXX_wcsxfrm_l + +static inline int _CXX_isblank_l(int c, _CXX_locale_t __l) { + __locale_sentry __current(__l); + return isblank(c); +} + +static inline int _CXX_isdigit_l(int c, _CXX_locale_t __l) { + __locale_sentry __current(__l); + return isdigit(c); +} + +static inline int _CXX_islower_l(int c, _CXX_locale_t __l) { + __locale_sentry __current(__l); + return islower(c); +} + +static inline int _CXX_isupper_l(int c, _CXX_locale_t __l) { + __locale_sentry __current(__l); + return isupper(c); +} + +static inline int _CXX_isxdigit_l(int c, _CXX_locale_t __l) { + __locale_sentry __current(__l); + return isxdigit(c); +} + +static inline int _CXX_iswalpha_l(wint_t c, _CXX_locale_t __l) { + __locale_sentry __current(__l); + return iswalpha(c); +} + +static inline int _CXX_iswblank_l(wint_t c, _CXX_locale_t __l) { + __locale_sentry __current(__l); + return iswblank(c); +} + +static inline int _CXX_iswcntrl_l(wint_t c, _CXX_locale_t __l) { + __locale_sentry __current(__l); + return iswcntrl(c); +} + +static inline int _CXX_iswdigit_l(wint_t c, _CXX_locale_t __l) { + __locale_sentry __current(__l); + return iswdigit(c); +} + +static inline int _CXX_iswlower_l(wint_t c, _CXX_locale_t __l) { + __locale_sentry __current(__l); + return iswlower(c); +} + +static inline int _CXX_iswprint_l(wint_t c, _CXX_locale_t __l) { + __locale_sentry __current(__l); + return iswprint(c); +} + +static inline int _CXX_iswpunct_l(wint_t c, _CXX_locale_t __l) { + __locale_sentry __current(__l); + return iswpunct(c); +} + +static inline int _CXX_iswspace_l(wint_t c, _CXX_locale_t __l) { + __locale_sentry __current(__l); + return iswspace(c); +} + +static inline int _CXX_iswupper_l(wint_t c, _CXX_locale_t __l) { + __locale_sentry __current(__l); + return iswupper(c); +} + +static inline int _CXX_iswxdigit_l(wint_t c, _CXX_locale_t __l) { + __locale_sentry __current(__l); + return iswxdigit(c); +} + +static inline int _CXX_toupper_l(int c, _CXX_locale_t __l) { + __locale_sentry __current(__l); + return toupper(c); +} + +static inline int _CXX_tolower_l(int c, _CXX_locale_t __l) { + __locale_sentry __current(__l); + return tolower(c); +} + +static inline int _CXX_towupper_l(int c, _CXX_locale_t __l) { + __locale_sentry __current(__l); + return towupper(c); +} + +static inline int _CXX_towlower_l(int c, _CXX_locale_t __l) { + __locale_sentry __current(__l); + return towlower(c); +} + +static inline int _CXX_wcscoll_l(const wchar_t *ws1, const wchar_t *ws2, + _CXX_locale_t __l) { + __locale_sentry __current(__l); + return wcscoll(ws1, ws2); +} + +static inline size_t _CXX_wcsxfrm_l(wchar_t *dest, const wchar_t *src, size_t n, + _CXX_locale_t __l) { + __locale_sentry __current(__l); + return wcsxfrm(dest, src, n); +} + +#endif // _LIBCPP_SUPPORT_XLOCALE_NON_POSIX_CTYPE_DEFAULTS_H Index: include/support/xlocale/__nop_locale_mgmt.h =================================================================== --- /dev/null +++ include/support/xlocale/__nop_locale_mgmt.h @@ -0,0 +1,42 @@ +// -*- C++ -*- +//===------------ support/xlocale/__nop_locale_mgmt.h -----------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_SUPPORT_XLOCALE_NOP_LOCALE_MGMT_H +#define _LIBCPP_SUPPORT_XLOCALE_NOP_LOCALE_MGMT_H + +#if !defined(_LIBCPP_SUPPORT_XLOCALE_LOCALE_MANAGEMENT_H) +#error "This must be included inside support/xlocale/__locale_management.h" +#endif + +#undef _CXX_locale_t +#undef _CXX_freelocale +#undef _CXX_newlocale +#undef _CXX_uselocale +#undef _CXX_LC_ALL_MASK + +// Patch over lack of extended locale support +typedef void *_CXX_locale_t; + +static inline void _CXX_freelocale(_CXX_locale_t) { +} + +static inline _CXX_locale_t _CXX_newlocale(int, const char *, _CXX_locale_t) { + return NULL; +} + +static inline _CXX_locale_t _CXX_uselocale(_CXX_locale_t) { + return NULL; +} + +// The specific value here don't matter much, because the only thing that +// normally uses LC_ALL_MASK is newlocale... and our version ignores everything. +#define _CXX_LC_ALL_MASK (0) + +#endif // _LIBCPP_SUPPORT_XLOCALE_NOP_LOCALE_MGMT_H Index: include/support/xlocale/xlocale.h =================================================================== --- include/support/xlocale/xlocale.h +++ /dev/null @@ -1,194 +0,0 @@ -// -*- C++ -*- -//===------------------- support/xlocale/xlocale.h ------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is dual licensed under the MIT and the University of Illinois Open -// Source Licenses. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// This is a shared implementation of a shim to provide extended locale support -// on top of libc's that don't support it (like Android's bionic, and Newlib). -// -// The 'illusion' only works when the specified locale is "C" or "POSIX", but -// that's about as good as we can do without implementing full xlocale support -// in the underlying libc. -//===----------------------------------------------------------------------===// - -#ifndef _LIBCPP_SUPPORT_XLOCALE_XLOCALE_H -#define _LIBCPP_SUPPORT_XLOCALE_XLOCALE_H - -#ifdef __cplusplus -extern "C" { -#endif - -static inline int isalnum_l(int c, locale_t) { - return isalnum(c); -} - -static inline int isalpha_l(int c, locale_t) { - return isalpha(c); -} - -static inline int isblank_l(int c, locale_t) { - return isblank(c); -} - -static inline int iscntrl_l(int c, locale_t) { - return iscntrl(c); -} - -static inline int isdigit_l(int c, locale_t) { - return isdigit(c); -} - -static inline int isgraph_l(int c, locale_t) { - return isgraph(c); -} - -static inline int islower_l(int c, locale_t) { - return islower(c); -} - -static inline int isprint_l(int c, locale_t) { - return isprint(c); -} - -static inline int ispunct_l(int c, locale_t) { - return ispunct(c); -} - -static inline int isspace_l(int c, locale_t) { - return isspace(c); -} - -static inline int isupper_l(int c, locale_t) { - return isupper(c); -} - -static inline int isxdigit_l(int c, locale_t) { - return isxdigit(c); -} - -static inline int iswalnum_l(wint_t c, locale_t) { - return iswalnum(c); -} - -static inline int iswalpha_l(wint_t c, locale_t) { - return iswalpha(c); -} - -static inline int iswblank_l(wint_t c, locale_t) { - return iswblank(c); -} - -static inline int iswcntrl_l(wint_t c, locale_t) { - return iswcntrl(c); -} - -static inline int iswdigit_l(wint_t c, locale_t) { - return iswdigit(c); -} - -static inline int iswgraph_l(wint_t c, locale_t) { - return iswgraph(c); -} - -static inline int iswlower_l(wint_t c, locale_t) { - return iswlower(c); -} - -static inline int iswprint_l(wint_t c, locale_t) { - return iswprint(c); -} - -static inline int iswpunct_l(wint_t c, locale_t) { - return iswpunct(c); -} - -static inline int iswspace_l(wint_t c, locale_t) { - return iswspace(c); -} - -static inline int iswupper_l(wint_t c, locale_t) { - return iswupper(c); -} - -static inline int iswxdigit_l(wint_t c, locale_t) { - return iswxdigit(c); -} - -static inline int toupper_l(int c, locale_t) { - return toupper(c); -} - -static inline int tolower_l(int c, locale_t) { - return tolower(c); -} - -static inline int towupper_l(int c, locale_t) { - return towupper(c); -} - -static inline int towlower_l(int c, locale_t) { - return towlower(c); -} - -static inline int strcoll_l(const char *s1, const char *s2, locale_t) { - return strcoll(s1, s2); -} - -static inline size_t strxfrm_l(char *dest, const char *src, size_t n, - locale_t) { - return strxfrm(dest, src, n); -} - -static inline size_t strftime_l(char *s, size_t max, const char *format, - const struct tm *tm, locale_t) { - return strftime(s, max, format, tm); -} - -static inline int wcscoll_l(const wchar_t *ws1, const wchar_t *ws2, locale_t) { - return wcscoll(ws1, ws2); -} - -static inline size_t wcsxfrm_l(wchar_t *dest, const wchar_t *src, size_t n, - locale_t) { - return wcsxfrm(dest, src, n); -} - -static inline long double strtold_l(const char *nptr, char **endptr, locale_t) { - return strtold(nptr, endptr); -} - -static inline long long strtoll_l(const char *nptr, char **endptr, int base, - locale_t) { - return strtoll(nptr, endptr, base); -} - -static inline unsigned long long strtoull_l(const char *nptr, char **endptr, - int base, locale_t) { - return strtoull(nptr, endptr, base); -} - -static inline long long wcstoll_l(const wchar_t *nptr, wchar_t **endptr, - int base, locale_t) { - return wcstoll(nptr, endptr, base); -} - -static inline unsigned long long wcstoull_l(const wchar_t *nptr, - wchar_t **endptr, int base, - locale_t) { - return wcstoull(nptr, endptr, base); -} - -static inline long double wcstold_l(const wchar_t *nptr, wchar_t **endptr, - locale_t) { - return wcstold(nptr, endptr); -} - -#ifdef __cplusplus -} -#endif - -#endif // _LIBCPP_SUPPORT_XLOCALE_XLOCALE_H Index: src/locale.cpp =================================================================== --- src/locale.cpp +++ src/locale.cpp @@ -26,11 +26,6 @@ #include "cstring" #include "cwctype" #include "__sso_allocator" -#if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__) -#include "support/win32/locale_win32.h" -#elif !defined(__ANDROID__) -#include -#endif #include #include @@ -40,14 +35,19 @@ #pragma clang diagnostic ignored "-Wsign-conversion" #endif +#if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__) +// ctype mask table defined in msvcrt.dll +extern "C" unsigned short __declspec(dllimport) _ctype[]; +#endif + _LIBCPP_BEGIN_NAMESPACE_STD #ifdef __cloc_defined -locale_t __cloc() { +_CXX_locale_t __cloc() { // In theory this could create a race condition. In practice // the race condition is non-fatal since it will just create // a little resource leak. Better approach would be appreciated. - static locale_t result = newlocale(LC_ALL_MASK, "C", 0); + static _CXX_locale_t result = _CXX_newlocale(_CXX_LC_ALL_MASK, "C", 0); return result; } #endif // __cloc_defined @@ -644,7 +644,7 @@ collate_byname::collate_byname(const char* n, size_t refs) : collate(refs), - __l(newlocale(LC_ALL_MASK, n, 0)) + __l(_CXX_newlocale(_CXX_LC_ALL_MASK, n, 0)) { #ifndef _LIBCPP_NO_EXCEPTIONS if (__l == 0) @@ -655,7 +655,7 @@ collate_byname::collate_byname(const string& name, size_t refs) : collate(refs), - __l(newlocale(LC_ALL_MASK, name.c_str(), 0)) + __l(_CXX_newlocale(_CXX_LC_ALL_MASK, name.c_str(), 0)) { #ifndef _LIBCPP_NO_EXCEPTIONS if (__l == 0) @@ -666,7 +666,7 @@ collate_byname::~collate_byname() { - freelocale(__l); + _CXX_freelocale(__l); } int @@ -675,7 +675,7 @@ { string_type lhs(__lo1, __hi1); string_type rhs(__lo2, __hi2); - int r = strcoll_l(lhs.c_str(), rhs.c_str(), __l); + int r = _CXX_strcoll_l(lhs.c_str(), rhs.c_str(), __l); if (r < 0) return -1; if (r > 0) @@ -687,8 +687,8 @@ collate_byname::do_transform(const char_type* lo, const char_type* hi) const { const string_type in(lo, hi); - string_type out(strxfrm_l(0, in.c_str(), 0, __l), char()); - strxfrm_l(const_cast(out.c_str()), in.c_str(), out.size()+1, __l); + string_type out(_CXX_strxfrm_l(0, in.c_str(), 0, __l), char()); + _CXX_strxfrm_l(const_cast(out.c_str()), in.c_str(), out.size()+1, __l); return out; } @@ -696,7 +696,7 @@ collate_byname::collate_byname(const char* n, size_t refs) : collate(refs), - __l(newlocale(LC_ALL_MASK, n, 0)) + __l(_CXX_newlocale(_CXX_LC_ALL_MASK, n, 0)) { #ifndef _LIBCPP_NO_EXCEPTIONS if (__l == 0) @@ -707,7 +707,7 @@ collate_byname::collate_byname(const string& name, size_t refs) : collate(refs), - __l(newlocale(LC_ALL_MASK, name.c_str(), 0)) + __l(_CXX_newlocale(_CXX_LC_ALL_MASK, name.c_str(), 0)) { #ifndef _LIBCPP_NO_EXCEPTIONS if (__l == 0) @@ -718,7 +718,7 @@ collate_byname::~collate_byname() { - freelocale(__l); + _CXX_freelocale(__l); } int @@ -727,7 +727,7 @@ { string_type lhs(__lo1, __hi1); string_type rhs(__lo2, __hi2); - int r = wcscoll_l(lhs.c_str(), rhs.c_str(), __l); + int r = _CXX_wcscoll_l(lhs.c_str(), rhs.c_str(), __l); if (r < 0) return -1; if (r > 0) @@ -739,8 +739,8 @@ collate_byname::do_transform(const char_type* lo, const char_type* hi) const { const string_type in(lo, hi); - string_type out(wcsxfrm_l(0, in.c_str(), 0, __l), wchar_t()); - wcsxfrm_l(const_cast(out.c_str()), in.c_str(), out.size()+1, __l); + string_type out(_CXX_wcsxfrm_l(0, in.c_str(), 0, __l), wchar_t()); + _CXX_wcsxfrm_l(const_cast(out.c_str()), in.c_str(), out.size()+1, __l); return out; } @@ -807,7 +807,7 @@ defined(__NetBSD__) return isascii(c) ? ctype::__classic_upper_table()[c] : c; #else - return (isascii(c) && iswlower_l(c, _LIBCPP_GET_C_LOCALE)) ? c-L'a'+L'A' : c; + return (isascii(c) && _CXX_iswlower_l(c, _LIBCPP_GET_C_LOCALE)) ? c-L'a'+L'A' : c; #endif } @@ -822,7 +822,7 @@ *low = isascii(*low) ? ctype::__classic_upper_table()[*low] : *low; #else - *low = (isascii(*low) && islower_l(*low, _LIBCPP_GET_C_LOCALE)) ? (*low-L'a'+L'A') : *low; + *low = (isascii(*low) && _CXX_islower_l(*low, _LIBCPP_GET_C_LOCALE)) ? (*low-L'a'+L'A') : *low; #endif return low; } @@ -836,7 +836,7 @@ defined(__NetBSD__) return isascii(c) ? ctype::__classic_lower_table()[c] : c; #else - return (isascii(c) && isupper_l(c, _LIBCPP_GET_C_LOCALE)) ? c-L'A'+'a' : c; + return (isascii(c) && _CXX_isupper_l(c, _LIBCPP_GET_C_LOCALE)) ? c-L'A'+'a' : c; #endif } @@ -851,7 +851,7 @@ *low = isascii(*low) ? ctype::__classic_lower_table()[*low] : *low; #else - *low = (isascii(*low) && isupper_l(*low, _LIBCPP_GET_C_LOCALE)) ? *low-L'A'+L'a' : *low; + *low = (isascii(*low) && _CXX_isupper_l(*low, _LIBCPP_GET_C_LOCALE)) ? *low-L'A'+L'a' : *low; #endif return low; } @@ -920,7 +920,7 @@ return isascii(c) ? static_cast(__classic_upper_table()[static_cast(c)]) : c; #else - return (isascii(c) && islower_l(c, _LIBCPP_GET_C_LOCALE)) ? c-'a'+'A' : c; + return (isascii(c) && _CXX_islower_l(c, _LIBCPP_GET_C_LOCALE)) ? c-'a'+'A' : c; #endif } @@ -937,7 +937,7 @@ *low = isascii(*low) ? static_cast(__classic_upper_table()[static_cast(*low)]) : *low; #else - *low = (isascii(*low) && islower_l(*low, _LIBCPP_GET_C_LOCALE)) ? *low-'a'+'A' : *low; + *low = (isascii(*low) && _CXX_islower_l(*low, _LIBCPP_GET_C_LOCALE)) ? *low-'a'+'A' : *low; #endif return low; } @@ -954,7 +954,7 @@ return isascii(c) ? static_cast(__classic_lower_table()[static_cast(c)]) : c; #else - return (isascii(c) && isupper_l(c, _LIBCPP_GET_C_LOCALE)) ? c-'A'+'a' : c; + return (isascii(c) && _CXX_isupper_l(c, _LIBCPP_GET_C_LOCALE)) ? c-'A'+'a' : c; #endif } @@ -969,7 +969,7 @@ #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) *low = isascii(*low) ? static_cast(__classic_lower_table()[static_cast(*low)]) : *low; #else - *low = (isascii(*low) && isupper_l(*low, _LIBCPP_GET_C_LOCALE)) ? *low-'A'+'a' : *low; + *low = (isascii(*low) && _CXX_isupper_l(*low, _LIBCPP_GET_C_LOCALE)) ? *low-'A'+'a' : *low; #endif return low; } @@ -1115,7 +1115,7 @@ // Newlib has a 257-entry table in ctype_.c, where (char)0 starts at [1]. return _ctype_ + 1; #elif defined(_AIX) - return (const unsigned int *)__lc_ctype_ptr->obj->mask; + return (const unsigned int *)_CXX_LC_ctype_ptr->obj->mask; #else // Platform not supported: abort so the person doing the port knows what to // fix @@ -1170,7 +1170,7 @@ ctype_byname::ctype_byname(const char* name, size_t refs) : ctype(0, false, refs), - __l(newlocale(LC_ALL_MASK, name, 0)) + __l(_CXX_newlocale(_CXX_LC_ALL_MASK, name, 0)) { #ifndef _LIBCPP_NO_EXCEPTIONS if (__l == 0) @@ -1181,7 +1181,7 @@ ctype_byname::ctype_byname(const string& name, size_t refs) : ctype(0, false, refs), - __l(newlocale(LC_ALL_MASK, name.c_str(), 0)) + __l(_CXX_newlocale(_CXX_LC_ALL_MASK, name.c_str(), 0)) { #ifndef _LIBCPP_NO_EXCEPTIONS if (__l == 0) @@ -1192,34 +1192,34 @@ ctype_byname::~ctype_byname() { - freelocale(__l); + _CXX_freelocale(__l); } char ctype_byname::do_toupper(char_type c) const { - return static_cast(toupper_l(static_cast(c), __l)); + return static_cast(_CXX_toupper_l(static_cast(c), __l)); } const char* ctype_byname::do_toupper(char_type* low, const char_type* high) const { for (; low != high; ++low) - *low = static_cast(toupper_l(static_cast(*low), __l)); + *low = static_cast(_CXX_toupper_l(static_cast(*low), __l)); return low; } char ctype_byname::do_tolower(char_type c) const { - return static_cast(tolower_l(static_cast(c), __l)); + return static_cast(_CXX_tolower_l(static_cast(c), __l)); } const char* ctype_byname::do_tolower(char_type* low, const char_type* high) const { for (; low != high; ++low) - *low = static_cast(tolower_l(static_cast(*low), __l)); + *low = static_cast(_CXX_tolower_l(static_cast(*low), __l)); return low; } @@ -1227,7 +1227,7 @@ ctype_byname::ctype_byname(const char* name, size_t refs) : ctype(refs), - __l(newlocale(LC_ALL_MASK, name, 0)) + __l(_CXX_newlocale(_CXX_LC_ALL_MASK, name, 0)) { #ifndef _LIBCPP_NO_EXCEPTIONS if (__l == 0) @@ -1238,7 +1238,7 @@ ctype_byname::ctype_byname(const string& name, size_t refs) : ctype(refs), - __l(newlocale(LC_ALL_MASK, name.c_str(), 0)) + __l(_CXX_newlocale(_CXX_LC_ALL_MASK, name.c_str(), 0)) { #ifndef _LIBCPP_NO_EXCEPTIONS if (__l == 0) @@ -1249,27 +1249,27 @@ ctype_byname::~ctype_byname() { - freelocale(__l); + _CXX_freelocale(__l); } bool ctype_byname::do_is(mask m, char_type c) const { #ifdef _LIBCPP_WCTYPE_IS_MASK - return static_cast(iswctype_l(c, m, __l)); + return static_cast(_CXX_iswctype_l(c, m, __l)); #else bool result = false; wint_t ch = static_cast(c); - if ((m & space) == space) result |= (iswspace_l(ch, __l) != 0); - if ((m & print) == print) result |= (iswprint_l(ch, __l) != 0); - if ((m & cntrl) == cntrl) result |= (iswcntrl_l(ch, __l) != 0); - if ((m & upper) == upper) result |= (iswupper_l(ch, __l) != 0); - if ((m & lower) == lower) result |= (iswlower_l(ch, __l) != 0); - if ((m & alpha) == alpha) result |= (iswalpha_l(ch, __l) != 0); - if ((m & digit) == digit) result |= (iswdigit_l(ch, __l) != 0); - if ((m & punct) == punct) result |= (iswpunct_l(ch, __l) != 0); - if ((m & xdigit) == xdigit) result |= (iswxdigit_l(ch, __l) != 0); - if ((m & blank) == blank) result |= (iswblank_l(ch, __l) != 0); + if ((m & space) == space) result |= (_CXX_iswspace_l( ch, __l) != 0); + if ((m & print) == print) result |= (_CXX_iswprint_l( ch, __l) != 0); + if ((m & cntrl) == cntrl) result |= (_CXX_iswcntrl_l( ch, __l) != 0); + if ((m & upper) == upper) result |= (_CXX_iswupper_l( ch, __l) != 0); + if ((m & lower) == lower) result |= (_CXX_iswlower_l( ch, __l) != 0); + if ((m & alpha) == alpha) result |= (_CXX_iswalpha_l( ch, __l) != 0); + if ((m & digit) == digit) result |= (_CXX_iswdigit_l( ch, __l) != 0); + if ((m & punct) == punct) result |= (_CXX_iswpunct_l( ch, __l) != 0); + if ((m & xdigit) == xdigit) result |= (_CXX_iswxdigit_l(ch, __l) != 0); + if ((m & blank) == blank) result |= (_CXX_iswblank_l( ch, __l) != 0); return result; #endif } @@ -1285,32 +1285,32 @@ { *vec = 0; wint_t ch = static_cast(*low); - if (iswspace_l(ch, __l)) + if (_CXX_iswspace_l(ch, __l)) *vec |= space; #ifndef _LIBCPP_CTYPE_MASK_IS_COMPOSITE_PRINT - if (iswprint_l(ch, __l)) + if (_CXX_iswprint_l(ch, __l)) *vec |= print; #endif - if (iswcntrl_l(ch, __l)) + if (_CXX_iswcntrl_l(ch, __l)) *vec |= cntrl; - if (iswupper_l(ch, __l)) + if (_CXX_iswupper_l(ch, __l)) *vec |= upper; - if (iswlower_l(ch, __l)) + if (_CXX_iswlower_l(ch, __l)) *vec |= lower; #ifndef _LIBCPP_CTYPE_MASK_IS_COMPOSITE_ALPHA - if (iswalpha_l(ch, __l)) + if (_CXX_iswalpha_l(ch, __l)) *vec |= alpha; #endif - if (iswdigit_l(ch, __l)) + if (_CXX_iswdigit_l(ch, __l)) *vec |= digit; - if (iswpunct_l(ch, __l)) + if (_CXX_iswpunct_l(ch, __l)) *vec |= punct; #ifndef _LIBCPP_CTYPE_MASK_IS_COMPOSITE_XDIGIT - if (iswxdigit_l(ch, __l)) + if (_CXX_iswxdigit_l(ch, __l)) *vec |= xdigit; #endif #if !defined(__sun__) - if (iswblank_l(ch, __l)) + if (_CXX_iswblank_l(ch, __l)) *vec |= blank; #endif } @@ -1324,20 +1324,20 @@ for (; low != high; ++low) { #ifdef _LIBCPP_WCTYPE_IS_MASK - if (iswctype_l(*low, m, __l)) + if (_CXX_iswctype_l(*low, m, __l)) break; #else wint_t ch = static_cast(*low); - if ((m & space) == space && iswspace_l(ch, __l)) break; - if ((m & print) == print && iswprint_l(ch, __l)) break; - if ((m & cntrl) == cntrl && iswcntrl_l(ch, __l)) break; - if ((m & upper) == upper && iswupper_l(ch, __l)) break; - if ((m & lower) == lower && iswlower_l(ch, __l)) break; - if ((m & alpha) == alpha && iswalpha_l(ch, __l)) break; - if ((m & digit) == digit && iswdigit_l(ch, __l)) break; - if ((m & punct) == punct && iswpunct_l(ch, __l)) break; - if ((m & xdigit) == xdigit && iswxdigit_l(ch, __l)) break; - if ((m & blank) == blank && iswblank_l(ch, __l)) break; + if ((m & space) == space && _CXX_iswspace_l( ch, __l)) break; + if ((m & print) == print && _CXX_iswprint_l( ch, __l)) break; + if ((m & cntrl) == cntrl && _CXX_iswcntrl_l( ch, __l)) break; + if ((m & upper) == upper && _CXX_iswupper_l( ch, __l)) break; + if ((m & lower) == lower && _CXX_iswlower_l( ch, __l)) break; + if ((m & alpha) == alpha && _CXX_iswalpha_l( ch, __l)) break; + if ((m & digit) == digit && _CXX_iswdigit_l( ch, __l)) break; + if ((m & punct) == punct && _CXX_iswpunct_l( ch, __l)) break; + if ((m & xdigit) == xdigit && _CXX_iswxdigit_l(ch, __l)) break; + if ((m & blank) == blank && _CXX_iswblank_l( ch, __l)) break; #endif } return low; @@ -1349,20 +1349,20 @@ for (; low != high; ++low) { #ifdef _LIBCPP_WCTYPE_IS_MASK - if (!iswctype_l(*low, m, __l)) + if (!_CXX_iswctype_l(*low, m, __l)) break; #else wint_t ch = static_cast(*low); - if ((m & space) == space && iswspace_l(ch, __l)) continue; - if ((m & print) == print && iswprint_l(ch, __l)) continue; - if ((m & cntrl) == cntrl && iswcntrl_l(ch, __l)) continue; - if ((m & upper) == upper && iswupper_l(ch, __l)) continue; - if ((m & lower) == lower && iswlower_l(ch, __l)) continue; - if ((m & alpha) == alpha && iswalpha_l(ch, __l)) continue; - if ((m & digit) == digit && iswdigit_l(ch, __l)) continue; - if ((m & punct) == punct && iswpunct_l(ch, __l)) continue; - if ((m & xdigit) == xdigit && iswxdigit_l(ch, __l)) continue; - if ((m & blank) == blank && iswblank_l(ch, __l)) continue; + if ((m & space) == space && _CXX_iswspace_l( ch, __l)) continue; + if ((m & print) == print && _CXX_iswprint_l( ch, __l)) continue; + if ((m & cntrl) == cntrl && _CXX_iswcntrl_l( ch, __l)) continue; + if ((m & upper) == upper && _CXX_iswupper_l( ch, __l)) continue; + if ((m & lower) == lower && _CXX_iswlower_l( ch, __l)) continue; + if ((m & alpha) == alpha && _CXX_iswalpha_l( ch, __l)) continue; + if ((m & digit) == digit && _CXX_iswdigit_l( ch, __l)) continue; + if ((m & punct) == punct && _CXX_iswpunct_l( ch, __l)) continue; + if ((m & xdigit) == xdigit && _CXX_iswxdigit_l(ch, __l)) continue; + if ((m & blank) == blank && _CXX_iswblank_l( ch, __l)) continue; break; #endif } @@ -1372,61 +1372,49 @@ wchar_t ctype_byname::do_toupper(char_type c) const { - return towupper_l(c, __l); + return _CXX_towupper_l(c, __l); } const wchar_t* ctype_byname::do_toupper(char_type* low, const char_type* high) const { for (; low != high; ++low) - *low = towupper_l(*low, __l); + *low = _CXX_towupper_l(*low, __l); return low; } wchar_t ctype_byname::do_tolower(char_type c) const { - return towlower_l(c, __l); + return _CXX_towlower_l(c, __l); } const wchar_t* ctype_byname::do_tolower(char_type* low, const char_type* high) const { for (; low != high; ++low) - *low = towlower_l(*low, __l); + *low = _CXX_towlower_l(*low, __l); return low; } wchar_t ctype_byname::do_widen(char c) const { -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - return btowc_l(c, __l); -#else - return __btowc_l(c, __l); -#endif + return _CXX_btowc_l(c, __l); } const char* ctype_byname::do_widen(const char* low, const char* high, char_type* dest) const { for (; low != high; ++low, ++dest) -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - *dest = btowc_l(*low, __l); -#else - *dest = __btowc_l(*low, __l); -#endif + *dest = _CXX_btowc_l(*low, __l); return low; } char ctype_byname::do_narrow(char_type c, char dfault) const { -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - int r = wctob_l(c, __l); -#else - int r = __wctob_l(c, __l); -#endif + int r = _CXX_wctob_l(c, __l); return r != static_cast(WEOF) ? static_cast(r) : dfault; } @@ -1435,11 +1423,7 @@ { for (; low != high; ++low, ++dest) { -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - int r = wctob_l(*low, __l); -#else - int r = __wctob_l(*low, __l); -#endif + int r = _CXX_wctob_l(*low, __l); *dest = r != static_cast(WEOF) ? static_cast(r) : dfault; } return low; @@ -1518,7 +1502,7 @@ codecvt::codecvt(const char* nm, size_t refs) : locale::facet(refs), - __l(newlocale(LC_ALL_MASK, nm, 0)) + __l(_CXX_newlocale(_CXX_LC_ALL_MASK, nm, 0)) { #ifndef _LIBCPP_NO_EXCEPTIONS if (__l == 0) @@ -1530,7 +1514,7 @@ codecvt::~codecvt() { if (__l != _LIBCPP_GET_C_LOCALE) - freelocale(__l); + _CXX_freelocale(__l); } codecvt::result @@ -1549,22 +1533,13 @@ { // save state in case it is needed to recover to_nxt on error mbstate_t save_state = st; -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - size_t n = wcsnrtombs_l(to, &frm_nxt, static_cast(fend-frm), - static_cast(to_end-to), &st, __l); -#else - size_t n = __wcsnrtombs_l(to, &frm_nxt, fend-frm, to_end-to, &st, __l); -#endif + size_t n = _CXX_wcsnrtombs_l(to, &frm_nxt, fend-frm, to_end-to, &st, __l); if (n == size_t(-1)) { // need to recover to_nxt for (to_nxt = to; frm != frm_nxt; ++frm) { -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - n = wcrtomb_l(to_nxt, *frm, &save_state, __l); -#else - n = __wcrtomb_l(to_nxt, *frm, &save_state, __l); -#endif + n = _CXX_wcrtomb_l(to_nxt, *frm, &save_state, __l); if (n == size_t(-1)) break; to_nxt += n; @@ -1581,11 +1556,7 @@ { // Try to write the terminating null extern_type tmp[MB_LEN_MAX]; -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - n = wcrtomb_l(tmp, intern_type(), &st, __l); -#else - n = __wcrtomb_l(tmp, intern_type(), &st, __l); -#endif + n = _CXX_wcrtomb_l(tmp, intern_type(), &st, __l); if (n == size_t(-1)) // on error return error; if (n > static_cast(to_end-to_nxt)) // is there room? @@ -1618,23 +1589,13 @@ { // save state in case it is needed to recover to_nxt on error mbstate_t save_state = st; -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - size_t n = mbsnrtowcs_l(to, &frm_nxt, static_cast(fend-frm), - static_cast(to_end-to), &st, __l); -#else - size_t n = __mbsnrtowcs_l(to, &frm_nxt, fend-frm, to_end-to, &st, __l); -#endif + size_t n = _CXX_mbsnrtowcs_l(to, &frm_nxt, fend-frm, to_end-to, &st, __l); if (n == size_t(-1)) { // need to recover to_nxt for (to_nxt = to; frm != frm_nxt; ++to_nxt) { -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - n = mbrtowc_l(to_nxt, frm, static_cast(fend-frm), - &save_state, __l); -#else - n = __mbrtowc_l(to_nxt, frm, fend-frm, &save_state, __l); -#endif + n = _CXX_mbrtowc_l(to_nxt, frm, fend-frm, &save_state, __l); switch (n) { case 0: @@ -1662,11 +1623,7 @@ if (fend != frm_end) // set up next null terminated sequence { // Try to write the terminating null -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - n = mbrtowc_l(to_nxt, frm_nxt, 1, &st, __l); -#else - n = __mbrtowc_l(to_nxt, frm_nxt, 1, &st, __l); -#endif + n = _CXX_mbrtowc_l(to_nxt, frm_nxt, 1, &st, __l); if (n != 0) // on error return error; ++to_nxt; @@ -1686,11 +1643,7 @@ { to_nxt = to; extern_type tmp[MB_LEN_MAX]; -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - size_t n = wcrtomb_l(tmp, intern_type(), &st, __l); -#else - size_t n = __wcrtomb_l(tmp, intern_type(), &st, __l); -#endif + size_t n = _CXX_wcrtomb_l(tmp, intern_type(), &st, __l); if (n == size_t(-1) || n == 0) // on error return error; --n; @@ -1705,20 +1658,12 @@ codecvt::do_encoding() const _NOEXCEPT { #ifndef __CloudABI__ -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - if (mbtowc_l(nullptr, nullptr, MB_LEN_MAX, __l) != 0) -#else - if (__mbtowc_l(nullptr, nullptr, MB_LEN_MAX, __l) != 0) -#endif + if (_CXX_mbtowc_l(nullptr, nullptr, MB_LEN_MAX, __l) != 0) return -1; #endif // stateless encoding -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - if (__l == 0 || MB_CUR_MAX_L(__l) == 1) // there are no known constant length encodings -#else - if (__l == 0 || __mb_cur_max_l(__l) == 1) // there are no known constant length encodings -#endif + if (__l == 0 || _CXX_mb_cur_max_l(__l) == 1) // there are no known constant length encodings return 1; // which take more than 1 char to form a wchar_t return 0; } @@ -1736,11 +1681,7 @@ int nbytes = 0; for (size_t nwchar_t = 0; nwchar_t < mx && frm != frm_end; ++nwchar_t) { -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - size_t n = mbrlen_l(frm, static_cast(frm_end-frm), &st, __l); -#else - size_t n = __mbrlen_l(frm, frm_end-frm, &st, __l); -#endif + size_t n = _CXX_mbrlen_l(frm, frm_end-frm, &st, __l); switch (n) { case 0: @@ -1762,11 +1703,7 @@ int codecvt::do_max_length() const _NOEXCEPT { -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - return __l == 0 ? 1 : static_cast( MB_CUR_MAX_L(__l)); -#else - return __l == 0 ? 1 : static_cast(__mb_cur_max_l(__l)); -#endif + return __l == 0 ? 1 : static_cast(_CXX_mb_cur_max_l(__l)); } // Valid UTF ranges @@ -4318,17 +4255,13 @@ { if (strcmp(nm, "C") != 0) { - __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale); + __locale_unique_ptr loc(_CXX_newlocale(_CXX_LC_ALL_MASK, nm, 0), _CXX_freelocale); #ifndef _LIBCPP_NO_EXCEPTIONS if (loc == nullptr) throw runtime_error("numpunct_byname::numpunct_byname" " failed to construct for " + string(nm)); #endif // _LIBCPP_NO_EXCEPTIONS -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - lconv* lc = localeconv_l(loc.get()); -#else - lconv* lc = __localeconv_l(loc.get()); -#endif + lconv* lc = _CXX_localeconv_l(loc.get()); if (*lc->decimal_point) __decimal_point_ = *lc->decimal_point; if (*lc->thousands_sep) @@ -4361,17 +4294,13 @@ { if (strcmp(nm, "C") != 0) { - __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale); + __locale_unique_ptr loc(_CXX_newlocale(_CXX_LC_ALL_MASK, nm, 0), _CXX_freelocale); #ifndef _LIBCPP_NO_EXCEPTIONS if (loc == nullptr) throw runtime_error("numpunct_byname::numpunct_byname" " failed to construct for " + string(nm)); #endif // _LIBCPP_NO_EXCEPTIONS -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - lconv* lc = localeconv_l(loc.get()); -#else - lconv* lc = __localeconv_l(loc.get()); -#endif + lconv* lc = _CXX_localeconv_l(loc.get()); if (*lc->decimal_point) __decimal_point_ = *lc->decimal_point; if (*lc->thousands_sep) @@ -4771,7 +4700,7 @@ // time_get_byname __time_get::__time_get(const char* nm) - : __loc_(newlocale(LC_ALL_MASK, nm, 0)) + : __loc_(_CXX_newlocale(_CXX_LC_ALL_MASK, nm, 0)) { #ifndef _LIBCPP_NO_EXCEPTIONS if (__loc_ == 0) @@ -4781,7 +4710,7 @@ } __time_get::__time_get(const string& nm) - : __loc_(newlocale(LC_ALL_MASK, nm.c_str(), 0)) + : __loc_(_CXX_newlocale(_CXX_LC_ALL_MASK, nm.c_str(), 0)) { #ifndef _LIBCPP_NO_EXCEPTIONS if (__loc_ == 0) @@ -4792,7 +4721,7 @@ __time_get::~__time_get() { - freelocale(__loc_); + _CXX_freelocale(__loc_); } #if defined(__clang__) #pragma clang diagnostic ignored "-Wmissing-field-initializers" @@ -4819,7 +4748,7 @@ char f[3] = {0}; f[0] = '%'; f[1] = fmt; - size_t n = strftime_l(buf, countof(buf), f, &t, __loc_); + size_t n = _CXX_strftime_l(buf, countof(buf), f, &t, __loc_); char* bb = buf; char* be = buf + n; string result; @@ -4967,16 +4896,12 @@ char f[3] = {0}; f[0] = '%'; f[1] = fmt; - strftime_l(buf, countof(buf), f, &t, __loc_); + _CXX_strftime_l(buf, countof(buf), f, &t, __loc_); wchar_t wbuf[100]; wchar_t* wbb = wbuf; mbstate_t mb = {0}; const char* bb = buf; -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - size_t j = mbsrtowcs_l( wbb, &bb, countof(wbuf), &mb, __loc_); -#else - size_t j = __mbsrtowcs_l( wbb, &bb, countof(wbuf), &mb, __loc_); -#endif + size_t j = _CXX_mbsrtowcs_l( wbb, &bb, countof(wbuf), &mb, __loc_); if (j == size_t(-1)) __throw_runtime_error("locale not supported"); wchar_t* wbe = wbb + j; @@ -5113,26 +5038,26 @@ for (int i = 0; i < 7; ++i) { t.tm_wday = i; - strftime_l(buf, countof(buf), "%A", &t, __loc_); + _CXX_strftime_l(buf, countof(buf), "%A", &t, __loc_); __weeks_[i] = buf; - strftime_l(buf, countof(buf), "%a", &t, __loc_); + _CXX_strftime_l(buf, countof(buf), "%a", &t, __loc_); __weeks_[i+7] = buf; } // __months_ for (int i = 0; i < 12; ++i) { t.tm_mon = i; - strftime_l(buf, countof(buf), "%B", &t, __loc_); + _CXX_strftime_l(buf, countof(buf), "%B", &t, __loc_); __months_[i] = buf; - strftime_l(buf, countof(buf), "%b", &t, __loc_); + _CXX_strftime_l(buf, countof(buf), "%b", &t, __loc_); __months_[i+12] = buf; } // __am_pm_ t.tm_hour = 1; - strftime_l(buf, countof(buf), "%p", &t, __loc_); + _CXX_strftime_l(buf, countof(buf), "%p", &t, __loc_); __am_pm_[0] = buf; t.tm_hour = 13; - strftime_l(buf, countof(buf), "%p", &t, __loc_); + _CXX_strftime_l(buf, countof(buf), "%p", &t, __loc_); __am_pm_[1] = buf; __c_ = __analyze('c', ct); __r_ = __analyze('r', ct); @@ -5153,26 +5078,18 @@ for (int i = 0; i < 7; ++i) { t.tm_wday = i; - strftime_l(buf, countof(buf), "%A", &t, __loc_); + _CXX_strftime_l(buf, countof(buf), "%A", &t, __loc_); mb = mbstate_t(); const char* bb = buf; -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - size_t j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); -#else - size_t j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); -#endif + size_t j = _CXX_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); if (j == size_t(-1)) __throw_runtime_error("locale not supported"); wbe = wbuf + j; __weeks_[i].assign(wbuf, wbe); - strftime_l(buf, countof(buf), "%a", &t, __loc_); + _CXX_strftime_l(buf, countof(buf), "%a", &t, __loc_); mb = mbstate_t(); bb = buf; -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); -#else - j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); -#endif + j = _CXX_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); if (j == size_t(-1)) __throw_runtime_error("locale not supported"); wbe = wbuf + j; @@ -5182,26 +5099,18 @@ for (int i = 0; i < 12; ++i) { t.tm_mon = i; - strftime_l(buf, countof(buf), "%B", &t, __loc_); + _CXX_strftime_l(buf, countof(buf), "%B", &t, __loc_); mb = mbstate_t(); const char* bb = buf; -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - size_t j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); -#else - size_t j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); -#endif + size_t j = _CXX_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); if (j == size_t(-1)) __throw_runtime_error("locale not supported"); wbe = wbuf + j; __months_[i].assign(wbuf, wbe); - strftime_l(buf, countof(buf), "%b", &t, __loc_); + _CXX_strftime_l(buf, countof(buf), "%b", &t, __loc_); mb = mbstate_t(); bb = buf; -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); -#else - j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); -#endif + j = _CXX_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); if (j == size_t(-1)) __throw_runtime_error("locale not supported"); wbe = wbuf + j; @@ -5209,27 +5118,19 @@ } // __am_pm_ t.tm_hour = 1; - strftime_l(buf, countof(buf), "%p", &t, __loc_); + _CXX_strftime_l(buf, countof(buf), "%p", &t, __loc_); mb = mbstate_t(); const char* bb = buf; -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - size_t j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); -#else - size_t j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); -#endif + size_t j = _CXX_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); if (j == size_t(-1)) __throw_runtime_error("locale not supported"); wbe = wbuf + j; __am_pm_[0].assign(wbuf, wbe); t.tm_hour = 13; - strftime_l(buf, countof(buf), "%p", &t, __loc_); + _CXX_strftime_l(buf, countof(buf), "%p", &t, __loc_); mb = mbstate_t(); bb = buf; -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); -#else - j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); -#endif + j = _CXX_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); if (j == size_t(-1)) __throw_runtime_error("locale not supported"); wbe = wbuf + j; @@ -5459,7 +5360,7 @@ // time_put __time_put::__time_put(const char* nm) - : __loc_(newlocale(LC_ALL_MASK, nm, 0)) + : __loc_(_CXX_newlocale(_CXX_LC_ALL_MASK, nm, 0)) { #ifndef _LIBCPP_NO_EXCEPTIONS if (__loc_ == 0) @@ -5469,7 +5370,7 @@ } __time_put::__time_put(const string& nm) - : __loc_(newlocale(LC_ALL_MASK, nm.c_str(), 0)) + : __loc_(_CXX_newlocale(_CXX_LC_ALL_MASK, nm.c_str(), 0)) { #ifndef _LIBCPP_NO_EXCEPTIONS if (__loc_ == 0) @@ -5481,7 +5382,7 @@ __time_put::~__time_put() { if (__loc_ != _LIBCPP_GET_C_LOCALE) - freelocale(__loc_); + _CXX_freelocale(__loc_); } void @@ -5491,7 +5392,7 @@ char fmt[] = {'%', __fmt, __mod, 0}; if (__mod != 0) swap(fmt[1], fmt[2]); - size_t n = strftime_l(__nb, countof(__nb, __ne), fmt, __tm, __loc_); + size_t n = _CXX_strftime_l(__nb, countof(__nb, __ne), fmt, __tm, __loc_); __ne = __nb + n; } @@ -5504,11 +5405,7 @@ __do_put(__nar, __ne, __tm, __fmt, __mod); mbstate_t mb = {0}; const char* __nb = __nar; -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - size_t j = mbsrtowcs_l(__wb, &__nb, countof(__wb, __we), &mb, __loc_); -#else - size_t j = __mbsrtowcs_l(__wb, &__nb, countof(__wb, __we), &mb, __loc_); -#endif + size_t j = _CXX_mbsrtowcs_l(__wb, &__nb, countof(__wb, __we), &mb, __loc_); if (j == size_t(-1)) __throw_runtime_error("locale not supported"); __we = __wb + j; @@ -5893,17 +5790,13 @@ moneypunct_byname::init(const char* nm) { typedef moneypunct base; - __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale); + __locale_unique_ptr loc(_CXX_newlocale(_CXX_LC_ALL_MASK, nm, 0), _CXX_freelocale); #ifndef _LIBCPP_NO_EXCEPTIONS if (loc == nullptr) throw runtime_error("moneypunct_byname" " failed to construct for " + string(nm)); #endif // _LIBCPP_NO_EXCEPTIONS -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - lconv* lc = localeconv_l(loc.get()); -#else - lconv* lc = __localeconv_l(loc.get()); -#endif + lconv* lc = _CXX_localeconv_l(loc.get()); if (*lc->mon_decimal_point) __decimal_point_ = *lc->mon_decimal_point; else @@ -5941,17 +5834,13 @@ moneypunct_byname::init(const char* nm) { typedef moneypunct base; - __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale); + __locale_unique_ptr loc(_CXX_newlocale(_CXX_LC_ALL_MASK, nm, 0), _CXX_freelocale); #ifndef _LIBCPP_NO_EXCEPTIONS if (loc == nullptr) throw runtime_error("moneypunct_byname" " failed to construct for " + string(nm)); #endif // _LIBCPP_NO_EXCEPTIONS -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - lconv* lc = localeconv_l(loc.get()); -#else - lconv* lc = __localeconv_l(loc.get()); -#endif + lconv* lc = _CXX_localeconv_l(loc.get()); if (*lc->mon_decimal_point) __decimal_point_ = *lc->mon_decimal_point; else @@ -6006,17 +5895,13 @@ moneypunct_byname::init(const char* nm) { typedef moneypunct base; - __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale); + __locale_unique_ptr loc(_CXX_newlocale(_CXX_LC_ALL_MASK, nm, 0), _CXX_freelocale); #ifndef _LIBCPP_NO_EXCEPTIONS if (loc == nullptr) throw runtime_error("moneypunct_byname" " failed to construct for " + string(nm)); #endif // _LIBCPP_NO_EXCEPTIONS -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - lconv* lc = localeconv_l(loc.get()); -#else - lconv* lc = __localeconv_l(loc.get()); -#endif + lconv* lc = _CXX_localeconv_l(loc.get()); if (*lc->mon_decimal_point) __decimal_point_ = static_cast(*lc->mon_decimal_point); else @@ -6029,11 +5914,7 @@ wchar_t wbuf[100]; mbstate_t mb = {0}; const char* bb = lc->currency_symbol; -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - size_t j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get()); -#else - size_t j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get()); -#endif + size_t j = _CXX_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get()); if (j == size_t(-1)) __throw_runtime_error("locale not supported"); wchar_t* wbe = wbuf + j; @@ -6048,11 +5929,7 @@ { mb = mbstate_t(); bb = lc->positive_sign; -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get()); -#else - j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get()); -#endif + j = _CXX_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get()); if (j == size_t(-1)) __throw_runtime_error("locale not supported"); wbe = wbuf + j; @@ -6064,11 +5941,7 @@ { mb = mbstate_t(); bb = lc->negative_sign; -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get()); -#else - j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get()); -#endif + j = _CXX_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get()); if (j == size_t(-1)) __throw_runtime_error("locale not supported"); wbe = wbuf + j; @@ -6089,17 +5962,13 @@ moneypunct_byname::init(const char* nm) { typedef moneypunct base; - __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale); + __locale_unique_ptr loc(_CXX_newlocale(_CXX_LC_ALL_MASK, nm, 0), _CXX_freelocale); #ifndef _LIBCPP_NO_EXCEPTIONS if (loc == nullptr) throw runtime_error("moneypunct_byname" " failed to construct for " + string(nm)); #endif // _LIBCPP_NO_EXCEPTIONS -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - lconv* lc = localeconv_l(loc.get()); -#else - lconv* lc = __localeconv_l(loc.get()); -#endif + lconv* lc = _CXX_localeconv_l(loc.get()); if (*lc->mon_decimal_point) __decimal_point_ = static_cast(*lc->mon_decimal_point); else @@ -6112,11 +5981,7 @@ wchar_t wbuf[100]; mbstate_t mb = {0}; const char* bb = lc->int_curr_symbol; -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - size_t j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get()); -#else - size_t j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get()); -#endif + size_t j = _CXX_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get()); if (j == size_t(-1)) __throw_runtime_error("locale not supported"); wchar_t* wbe = wbuf + j; @@ -6135,11 +6000,7 @@ { mb = mbstate_t(); bb = lc->positive_sign; -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get()); -#else - j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get()); -#endif + j = _CXX_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get()); if (j == size_t(-1)) __throw_runtime_error("locale not supported"); wbe = wbuf + j; @@ -6155,11 +6016,7 @@ { mb = mbstate_t(); bb = lc->negative_sign; -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get()); -#else - j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get()); -#endif + j = _CXX_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get()); if (j == size_t(-1)) __throw_runtime_error("locale not supported"); wbe = wbuf + j; Index: src/support/solaris/xlocale.c =================================================================== --- src/support/solaris/xlocale.c +++ src/support/solaris/xlocale.c @@ -15,51 +15,52 @@ #include -int isxdigit_l(int __c, locale_t __l) { +int _CXX_isxdigit_l(int __c, _CXX_locale_t __l) { + __locale_sentry __current(__l); return isxdigit(__c); } -int iswxdigit_l(wchar_t __c, locale_t __l) { +int _CXX_iswxdigit_l(wchar_t __c, _CXX_locale_t __l) { + __locale_sentry __current(__l); return isxdigit(__c); } -// FIXME: This disregards the locale, which is Very Wrong -#define vsnprintf_l(__s, __n, __l, __format, __va) \ - vsnprintf(__s, __n, __format, __va) - -int snprintf_l(char *__s, size_t __n, locale_t __l, const char *__format, ...) +int _CXX_snprintf_l(char *__s, size_t __n, _CXX_locale_t __l, const char *__format, ...) { va_list __va; va_start(__va, __format); - int __res = vsnprintf_l(__s, __n , __l, __format, __va); + __locale_sentry __current(__l); + int __res = vsnprintf(__s, __n, __format, __va); va_end(__va); return __res; } -int asprintf_l(char **__s, locale_t __l, const char *__format, ...) { +int _CXX_asprintf_l(char **__s, _CXX_locale_t __l, const char *__format, ...) { va_list __va; va_start(__va, __format); - // FIXME: + __locale_sentry __current(__l); int __res = vasprintf(__s, __format, __va); va_end(__va); return __res; } -int sscanf_l(const char *__s, locale_t __l, const char *__format, ...) { +int _CXX_sscanf_l(const char *__s, _CXX_locale_t __l, const char *__format, ...) { va_list __va; va_start(__va, __format); - // FIXME: + __locale_sentry __current(__l); int __res = vsscanf(__s, __format, __va); va_end(__va); return __res; } -size_t mbrtowc_l(wchar_t *__pwc, const char *__pmb, - size_t __max, mbstate_t *__ps, locale_t __loc) { +size_t _CXX_mbrtowc_l(wchar_t *__pwc, const char *__pmb, + size_t __max, mbstate_t *__ps, _CXX_locale_t __loc) { + __locale_sentry __current(__loc); return mbrtowc(__pwc, __pmb, __max, __ps); } -struct lconv *localeconv_l(locale_t __l) { +struct lconv *_CXX_localeconv_l(_CXX_locale_t __l) { + __locale_sentry __current(__l); return localeconv(); } Index: src/support/win32/locale_win32.cpp =================================================================== --- src/support/win32/locale_win32.cpp +++ src/support/win32/locale_win32.cpp @@ -11,78 +11,90 @@ #include #include // va_start, va_end +// The mingw headers already define these as static. +#ifndef __MINGW32__ +extern "C" { +int __vasprintf(char **sptr, const char *__restrict fmt, va_list ap); +int __asprintf(char **sptr, const char *__restrict fmt, ...); +size_t __mbsnrtowcs(wchar_t *__restrict dst, const char **__restrict src, + size_t nmc, size_t len, mbstate_t *__restrict ps); +size_t __wcsnrtombs(char *__restrict dst, const wchar_t **__restrict src, + size_t nwc, size_t len, mbstate_t *__restrict ps); +} +#endif // __MINGW32__ + // FIXME: base currently unused. Needs manual work to construct the new locale -locale_t newlocale( int mask, const char * locale, locale_t /*base*/ ) +_CXX_locale_t _CXX_newlocale( int mask, const char * locale, _CXX_locale_t /*base*/ ) { return _create_locale( mask, locale ); } -locale_t uselocale( locale_t newloc ) +_CXX_locale_t _CXX_uselocale( _CXX_locale_t newloc ) { - locale_t old_locale = _get_current_locale(); + _CXX_locale_t old_locale = _get_current_locale(); if ( newloc == NULL ) return old_locale; // uselocale sets the thread's locale by definition, so unconditionally use thread-local locale _configthreadlocale( _ENABLE_PER_THREAD_LOCALE ); // uselocale sets all categories setlocale( LC_ALL, newloc->locinfo->lc_category[LC_ALL].locale ); - // uselocale returns the old locale_t + // uselocale returns the old _CXX_locale_t return old_locale; } -lconv *localeconv_l( locale_t loc ) +lconv *_CXX_localeconv_l( _CXX_locale_t loc ) { - __locale_raii __current( uselocale(loc), uselocale ); + __locale_sentry __current(loc); return localeconv(); } -size_t mbrlen_l( const char *__restrict s, size_t n, - mbstate_t *__restrict ps, locale_t loc ) +size_t _CXX_mbrlen_l( const char *__restrict s, size_t n, + mbstate_t *__restrict ps, _CXX_locale_t loc ) { - __locale_raii __current( uselocale(loc), uselocale ); + __locale_sentry __current(loc); return mbrlen( s, n, ps ); } -size_t mbsrtowcs_l( wchar_t *__restrict dst, const char **__restrict src, - size_t len, mbstate_t *__restrict ps, locale_t loc ) +size_t _CXX_mbsrtowcs_l( wchar_t *__restrict dst, const char **__restrict src, + size_t len, mbstate_t *__restrict ps, _CXX_locale_t loc ) { - __locale_raii __current( uselocale(loc), uselocale ); + __locale_sentry __current(loc); return mbsrtowcs( dst, src, len, ps ); } -size_t wcrtomb_l( char *__restrict s, wchar_t wc, mbstate_t *__restrict ps, - locale_t loc ) +size_t _CXX_wcrtomb_l( char *__restrict s, wchar_t wc, mbstate_t *__restrict ps, + _CXX_locale_t loc ) { - __locale_raii __current( uselocale(loc), uselocale ); + __locale_sentry __current(loc); return wcrtomb( s, wc, ps ); } -size_t mbrtowc_l( wchar_t *__restrict pwc, const char *__restrict s, - size_t n, mbstate_t *__restrict ps, locale_t loc ) +size_t _CXX_mbrtowc_l( wchar_t *__restrict pwc, const char *__restrict s, + size_t n, mbstate_t *__restrict ps, _CXX_locale_t loc ) { - __locale_raii __current( uselocale(loc), uselocale ); + __locale_sentry __current(loc); return mbrtowc( pwc, s, n, ps ); } -size_t mbsnrtowcs_l( wchar_t *__restrict dst, const char **__restrict src, - size_t nms, size_t len, mbstate_t *__restrict ps, locale_t loc ) +size_t _CXX_mbsnrtowcs_l( wchar_t *__restrict dst, const char **__restrict src, + size_t nms, size_t len, mbstate_t *__restrict ps, _CXX_locale_t loc ) { - __locale_raii __current( uselocale(loc), uselocale ); - return mbsnrtowcs( dst, src, nms, len, ps ); + __locale_sentry __current(loc); + return __mbsnrtowcs( dst, src, nms, len, ps ); } -size_t wcsnrtombs_l( char *__restrict dst, const wchar_t **__restrict src, - size_t nwc, size_t len, mbstate_t *__restrict ps, locale_t loc ) +size_t _CXX_wcsnrtombs_l( char *__restrict dst, const wchar_t **__restrict src, + size_t nwc, size_t len, mbstate_t *__restrict ps, _CXX_locale_t loc ) { - __locale_raii __current( uselocale(loc), uselocale ); - return wcsnrtombs( dst, src, nwc, len, ps ); + __locale_sentry __current(loc); + return __wcsnrtombs( dst, src, nwc, len, ps ); } -wint_t btowc_l( int c, locale_t loc ) +wint_t _CXX_btowc_l( int c, _CXX_locale_t loc ) { - __locale_raii __current( uselocale(loc), uselocale ); + __locale_sentry __current(loc); return btowc( c ); } -int wctob_l( wint_t c, locale_t loc ) +int _CXX_wctob_l( wint_t c, _CXX_locale_t loc ) { - __locale_raii __current( uselocale(loc), uselocale ); + __locale_sentry __current(loc); return wctob( c ); } -int snprintf_l(char *ret, size_t n, locale_t loc, const char *format, ...) +int _CXX_snprintf_l(char *ret, size_t n, _CXX_locale_t loc, const char *format, ...) { - __locale_raii __current( uselocale(loc), uselocale ); + __locale_sentry __current(loc); va_list ap; va_start( ap, format ); int result = vsnprintf( ret, n, format, ap ); @@ -90,16 +102,17 @@ return result; } -int asprintf_l( char **ret, locale_t loc, const char *format, ... ) +int _CXX_vasprintf_l( char **ret, _CXX_locale_t loc, const char *format, va_list ap ) +{ + __locale_sentry __current(loc); + return __vasprintf( ret, format, ap ); +} + +int _CXX_asprintf_l( char **ret, _CXX_locale_t loc, const char *format, ... ) { va_list ap; va_start( ap, format ); - int result = vasprintf_l( ret, loc, format, ap ); + int result = _CXX_vasprintf_l( ret, loc, format, ap ); va_end(ap); return result; } -int vasprintf_l( char **ret, locale_t loc, const char *format, va_list ap ) -{ - __locale_raii __current( uselocale(loc), uselocale ); - return vasprintf( ret, format, ap ); -} Index: src/support/win32/support.cpp =================================================================== --- src/support/win32/support.cpp +++ src/support/win32/support.cpp @@ -1,5 +1,5 @@ // -*- C++ -*- -//===----------------------- support/win32/support.h ----------------------===// +//===--------------------- support/win32/support.cpp ----------------------===// // // The LLVM Compiler Infrastructure // @@ -17,12 +17,12 @@ // Some of these functions aren't standard or if they conform, the name does not. -int asprintf(char **sptr, const char *__restrict format, ...) +int __asprintf(char **sptr, const char *__restrict format, ...) { va_list ap; va_start(ap, format); int result; - result = vasprintf(sptr, format, ap); + result = __vasprintf(sptr, format, ap); va_end(ap); return result; } @@ -30,7 +30,7 @@ // Like sprintf, but when return value >= 0 it returns // a pointer to a malloc'd string in *sptr. // If return >= 0, use free to delete *sptr. -int vasprintf( char **sptr, const char *__restrict format, va_list ap ) +int __vasprintf( char **sptr, const char *__restrict format, va_list ap ) { *sptr = NULL; // Query the count required. @@ -60,7 +60,7 @@ // Returns (size_t) -1: an incomplete sequence encountered. // Leaves *src pointing the next character to convert or NULL // if a null character was converted from *src. -size_t mbsnrtowcs( wchar_t *__restrict dst, const char **__restrict src, +size_t __mbsnrtowcs( wchar_t *__restrict dst, const char **__restrict src, size_t src_size_bytes, size_t max_dest_chars, mbstate_t *__restrict ps ) { const size_t terminated_sequence = static_cast(0); @@ -112,7 +112,7 @@ // Returns size_t(-1) if an error occurs, also sets errno. // If dst is NULL dst_size_bytes is ignored and no bytes are copied to dst // and no "out" parameters are updated. -size_t wcsnrtombs( char *__restrict dst, const wchar_t **__restrict src, +size_t __wcsnrtombs( char *__restrict dst, const wchar_t **__restrict src, size_t max_source_chars, size_t dst_size_bytes, mbstate_t *__restrict ps ) { //const size_t invalid_sequence = static_cast(-1);