bcraig created this revision. bcraig added reviewers: mclow.lists, EricWF, joerg, jroelofs. bcraig added a subscriber: cfe-commits. Herald added a subscriber: jfb.
This patch cleans up libcxx's usage of newlocale, freelocale, uselocale, and locale_t. First, libcxx no longer defines the posix newlocale, freelocale, uselocale, and locale_t names on non-posix compliant systems. Those names don't belong to libcxx, so _libcpp variants and forwarders have been created. The renaming is the bulk of the diff. Second, improved locale management RAII objects have been created and used. _locale_raii was a typedef for a unique_ptr with a function pointer deleter. That requires a fatter object and an indirect call. Instead, a small, custom RAII object was added to manage the switching of locales with uselocale. This also allows for a terser syntax. An RAII object for the newlocale / freelocale pair was also created, as was a fancier RAII object to handle the case when we are handed a locale that (maybe) isn't supposed to be deleted. The last significant change is that the nop_locale_mgmt's newlocale (used by newlib) will now attempt to support the "C" and "POSIX" locales, rather than return 0. Tested on Linux x64, and on an embedded target that also happens to use all the trivial locale wrappers (like nop_locale_mgmt). http://reviews.llvm.org/D20596 Files: include/__bsd_locale_fallbacks.h include/__locale include/__locale_mgmt.h include/__posix_locale_mgmt_defaults.h include/locale include/support/ibm/locale_mgmt_aix.h include/support/ibm/xlocale.h include/support/musl/xlocale.h include/support/solaris/xlocale.h include/support/win32/locale_mgmt_win32.h include/support/win32/locale_win32.h include/support/xlocale/__nop_locale_mgmt.h include/support/xlocale/__posix_l_fallback.h include/support/xlocale/__strtonum_fallback.h src/locale.cpp src/support/solaris/mbsnrtowcs.inc src/support/solaris/wcsnrtombs.inc src/support/solaris/xlocale.c src/support/win32/locale_win32.cpp
Index: src/support/win32/locale_win32.cpp =================================================================== --- src/support/win32/locale_win32.cpp +++ src/support/win32/locale_win32.cpp @@ -12,13 +12,13 @@ #include <cstdarg> // va_start, va_end // FIXME: base currently unused. Needs manual work to construct the new locale -locale_t newlocale( int mask, const char * locale, locale_t /*base*/ ) +__libcpp_locale_t newlocale( int mask, const char * locale, __libcpp_locale_t /*base*/ ) { return _create_locale( mask, locale ); } -locale_t uselocale( locale_t newloc ) +__libcpp_locale_t uselocale( __libcpp_locale_t newloc ) { - locale_t old_locale = _get_current_locale(); + __libcpp_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 @@ -28,61 +28,61 @@ // uselocale returns the old locale_t return old_locale; } -lconv *localeconv_l( locale_t loc ) +lconv *localeconv_l( __libcpp_locale_t loc ) { - __locale_raii __current( uselocale(loc), uselocale ); + std::__locale_sentry __current(loc); return localeconv(); } size_t mbrlen_l( const char *__restrict s, size_t n, - mbstate_t *__restrict ps, locale_t loc ) + mbstate_t *__restrict ps, __libcpp_locale_t loc ) { - __locale_raii __current( uselocale(loc), uselocale ); + std::__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 len, mbstate_t *__restrict ps, __libcpp_locale_t loc ) { - __locale_raii __current( uselocale(loc), uselocale ); + std::__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 ) + __libcpp_locale_t loc ) { - __locale_raii __current( uselocale(loc), uselocale ); + std::__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 n, mbstate_t *__restrict ps, __libcpp_locale_t loc ) { - __locale_raii __current( uselocale(loc), uselocale ); + std::__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 nms, size_t len, mbstate_t *__restrict ps, __libcpp_locale_t loc ) { - __locale_raii __current( uselocale(loc), uselocale ); + std::__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 nwc, size_t len, mbstate_t *__restrict ps, __libcpp_locale_t loc ) { - __locale_raii __current( uselocale(loc), uselocale ); + std::__locale_sentry __current(loc); return wcsnrtombs( dst, src, nwc, len, ps ); } -wint_t btowc_l( int c, locale_t loc ) +wint_t btowc_l( int c, __libcpp_locale_t loc ) { - __locale_raii __current( uselocale(loc), uselocale ); + std::__locale_sentry __current(loc); return btowc( c ); } -int wctob_l( wint_t c, locale_t loc ) +int wctob_l( wint_t c, __libcpp_locale_t loc ) { - __locale_raii __current( uselocale(loc), uselocale ); + std::__locale_sentry __current(loc); return wctob( c ); } -int snprintf_l(char *ret, size_t n, locale_t loc, const char *format, ...) +int snprintf_l(char *ret, size_t n, __libcpp_locale_t loc, const char *format, ...) { - __locale_raii __current( uselocale(loc), uselocale ); + std::__locale_sentry __current(loc); va_list ap; va_start( ap, format ); int result = vsnprintf( ret, n, format, ap ); @@ -90,7 +90,7 @@ return result; } -int asprintf_l( char **ret, locale_t loc, const char *format, ... ) +int asprintf_l( char **ret, __libcpp_locale_t loc, const char *format, ... ) { va_list ap; va_start( ap, format ); @@ -98,8 +98,8 @@ va_end(ap); return result; } -int vasprintf_l( char **ret, locale_t loc, const char *format, va_list ap ) +int vasprintf_l( char **ret, __libcpp_locale_t loc, const char *format, va_list ap ) { - __locale_raii __current( uselocale(loc), uselocale ); + std::__locale_sentry __current(loc); return vasprintf( ret, format, ap ); } Index: src/support/solaris/xlocale.c =================================================================== --- src/support/solaris/xlocale.c +++ src/support/solaris/xlocale.c @@ -15,11 +15,11 @@ #include <sys/localedef.h> -int isxdigit_l(int __c, locale_t __l) { +int isxdigit_l(int __c, __libcpp_locale_t __l) { return isxdigit(__c); } -int iswxdigit_l(wchar_t __c, locale_t __l) { +int iswxdigit_l(wchar_t __c, __libcpp_locale_t __l) { return isxdigit(__c); } @@ -27,7 +27,7 @@ #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 snprintf_l(char *__s, size_t __n, __libcpp_locale_t __l, const char *__format, ...) { va_list __va; va_start(__va, __format); @@ -36,7 +36,7 @@ return __res; } -int asprintf_l(char **__s, locale_t __l, const char *__format, ...) { +int asprintf_l(char **__s, __libcpp_locale_t __l, const char *__format, ...) { va_list __va; va_start(__va, __format); // FIXME: @@ -45,7 +45,7 @@ return __res; } -int sscanf_l(const char *__s, locale_t __l, const char *__format, ...) { +int sscanf_l(const char *__s, __libcpp_locale_t __l, const char *__format, ...) { va_list __va; va_start(__va, __format); // FIXME: @@ -55,11 +55,11 @@ } size_t mbrtowc_l(wchar_t *__pwc, const char *__pmb, - size_t __max, mbstate_t *__ps, locale_t __loc) { + size_t __max, mbstate_t *__ps, __libcpp_locale_t __loc) { return mbrtowc(__pwc, __pmb, __max, __ps); } -struct lconv *localeconv_l(locale_t __l) { +struct lconv *localeconv_l(__libcpp_locale_t __l) { return localeconv(); } Index: src/support/solaris/wcsnrtombs.inc =================================================================== --- src/support/solaris/wcsnrtombs.inc +++ src/support/solaris/wcsnrtombs.inc @@ -26,7 +26,7 @@ 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 nwc, size_t len, mbstate_t * __restrict ps, __libcpp_locale_t loc) { FIX_LOCALE(loc); mbstate_t mbsbak; Index: src/support/solaris/mbsnrtowcs.inc =================================================================== --- src/support/solaris/mbsnrtowcs.inc +++ src/support/solaris/mbsnrtowcs.inc @@ -30,7 +30,7 @@ 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 nms, size_t len, mbstate_t * __restrict ps, __libcpp_locale_t loc) { const char *s; size_t nchr; Index: src/locale.cpp =================================================================== --- src/locale.cpp +++ src/locale.cpp @@ -43,11 +43,11 @@ _LIBCPP_BEGIN_NAMESPACE_STD #ifdef __cloc_defined -locale_t __cloc() { +__libcpp_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 __libcpp_locale_t result = newlocale(LC_ALL_MASK, "C", 0); return result; } #endif // __cloc_defined @@ -644,10 +644,10 @@ collate_byname<char>::collate_byname(const char* n, size_t refs) : collate<char>(refs), - __l(newlocale(LC_ALL_MASK, n, 0)) + __l(n) { #ifndef _LIBCPP_NO_EXCEPTIONS - if (__l == 0) + if (__l.get() == 0) throw runtime_error("collate_byname<char>::collate_byname" " failed to construct for " + string(n)); #endif // _LIBCPP_NO_EXCEPTIONS @@ -655,19 +655,17 @@ collate_byname<char>::collate_byname(const string& name, size_t refs) : collate<char>(refs), - __l(newlocale(LC_ALL_MASK, name.c_str(), 0)) + __l(name.c_str()) { #ifndef _LIBCPP_NO_EXCEPTIONS - if (__l == 0) + if (__l.get() == 0) throw runtime_error("collate_byname<char>::collate_byname" " failed to construct for " + name); #endif // _LIBCPP_NO_EXCEPTIONS } collate_byname<char>::~collate_byname() -{ - freelocale(__l); -} +{} int collate_byname<char>::do_compare(const char_type* __lo1, const char_type* __hi1, @@ -675,7 +673,7 @@ { string_type lhs(__lo1, __hi1); string_type rhs(__lo2, __hi2); - int r = strcoll_l(lhs.c_str(), rhs.c_str(), __l); + int r = strcoll_l(lhs.c_str(), rhs.c_str(), __l.get()); if (r < 0) return -1; if (r > 0) @@ -687,8 +685,8 @@ collate_byname<char>::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<char*>(out.c_str()), in.c_str(), out.size()+1, __l); + string_type out(strxfrm_l(0, in.c_str(), 0, __l.get()), char()); + strxfrm_l(const_cast<char*>(out.c_str()), in.c_str(), out.size()+1, __l.get()); return out; } @@ -696,10 +694,10 @@ collate_byname<wchar_t>::collate_byname(const char* n, size_t refs) : collate<wchar_t>(refs), - __l(newlocale(LC_ALL_MASK, n, 0)) + __l(n) { #ifndef _LIBCPP_NO_EXCEPTIONS - if (__l == 0) + if (__l.get() == 0) throw runtime_error("collate_byname<wchar_t>::collate_byname(size_t refs)" " failed to construct for " + string(n)); #endif // _LIBCPP_NO_EXCEPTIONS @@ -707,19 +705,17 @@ collate_byname<wchar_t>::collate_byname(const string& name, size_t refs) : collate<wchar_t>(refs), - __l(newlocale(LC_ALL_MASK, name.c_str(), 0)) + __l(name.c_str()) { #ifndef _LIBCPP_NO_EXCEPTIONS - if (__l == 0) + if (__l.get() == 0) throw runtime_error("collate_byname<wchar_t>::collate_byname(size_t refs)" " failed to construct for " + name); #endif // _LIBCPP_NO_EXCEPTIONS } collate_byname<wchar_t>::~collate_byname() -{ - freelocale(__l); -} +{} int collate_byname<wchar_t>::do_compare(const char_type* __lo1, const char_type* __hi1, @@ -727,7 +723,7 @@ { string_type lhs(__lo1, __hi1); string_type rhs(__lo2, __hi2); - int r = wcscoll_l(lhs.c_str(), rhs.c_str(), __l); + int r = wcscoll_l(lhs.c_str(), rhs.c_str(), __l.get()); if (r < 0) return -1; if (r > 0) @@ -739,8 +735,8 @@ collate_byname<wchar_t>::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<wchar_t*>(out.c_str()), in.c_str(), out.size()+1, __l); + string_type out(wcsxfrm_l(0, in.c_str(), 0, __l.get()), wchar_t()); + wcsxfrm_l(const_cast<wchar_t*>(out.c_str()), in.c_str(), out.size()+1, __l.get()); return out; } @@ -1170,10 +1166,10 @@ ctype_byname<char>::ctype_byname(const char* name, size_t refs) : ctype<char>(0, false, refs), - __l(newlocale(LC_ALL_MASK, name, 0)) + __l(name) { #ifndef _LIBCPP_NO_EXCEPTIONS - if (__l == 0) + if (__l.get() == 0) throw runtime_error("ctype_byname<char>::ctype_byname" " failed to construct for " + string(name)); #endif // _LIBCPP_NO_EXCEPTIONS @@ -1181,45 +1177,43 @@ ctype_byname<char>::ctype_byname(const string& name, size_t refs) : ctype<char>(0, false, refs), - __l(newlocale(LC_ALL_MASK, name.c_str(), 0)) + __l(name.c_str()) { #ifndef _LIBCPP_NO_EXCEPTIONS - if (__l == 0) + if (__l.get() == 0) throw runtime_error("ctype_byname<char>::ctype_byname" " failed to construct for " + name); #endif // _LIBCPP_NO_EXCEPTIONS } ctype_byname<char>::~ctype_byname() -{ - freelocale(__l); -} +{} char ctype_byname<char>::do_toupper(char_type c) const { - return static_cast<char>(toupper_l(static_cast<unsigned char>(c), __l)); + return static_cast<char>(toupper_l(static_cast<unsigned char>(c), __l.get())); } const char* ctype_byname<char>::do_toupper(char_type* low, const char_type* high) const { for (; low != high; ++low) - *low = static_cast<char>(toupper_l(static_cast<unsigned char>(*low), __l)); + *low = static_cast<char>(toupper_l(static_cast<unsigned char>(*low), __l.get())); return low; } char ctype_byname<char>::do_tolower(char_type c) const { - return static_cast<char>(tolower_l(static_cast<unsigned char>(c), __l)); + return static_cast<char>(tolower_l(static_cast<unsigned char>(c), __l.get())); } const char* ctype_byname<char>::do_tolower(char_type* low, const char_type* high) const { for (; low != high; ++low) - *low = static_cast<char>(tolower_l(static_cast<unsigned char>(*low), __l)); + *low = static_cast<char>(tolower_l(static_cast<unsigned char>(*low), __l.get())); return low; } @@ -1227,10 +1221,10 @@ ctype_byname<wchar_t>::ctype_byname(const char* name, size_t refs) : ctype<wchar_t>(refs), - __l(newlocale(LC_ALL_MASK, name, 0)) + __l(name) { #ifndef _LIBCPP_NO_EXCEPTIONS - if (__l == 0) + if (__l.get() == 0) throw runtime_error("ctype_byname<wchar_t>::ctype_byname" " failed to construct for " + string(name)); #endif // _LIBCPP_NO_EXCEPTIONS @@ -1238,38 +1232,36 @@ ctype_byname<wchar_t>::ctype_byname(const string& name, size_t refs) : ctype<wchar_t>(refs), - __l(newlocale(LC_ALL_MASK, name.c_str(), 0)) + __l(name.c_str()) { #ifndef _LIBCPP_NO_EXCEPTIONS - if (__l == 0) + if (__l.get() == 0) throw runtime_error("ctype_byname<wchar_t>::ctype_byname" " failed to construct for " + name); #endif // _LIBCPP_NO_EXCEPTIONS } ctype_byname<wchar_t>::~ctype_byname() -{ - freelocale(__l); -} +{} bool ctype_byname<wchar_t>::do_is(mask m, char_type c) const { #ifdef _LIBCPP_WCTYPE_IS_MASK - return static_cast<bool>(iswctype_l(c, m, __l)); + return static_cast<bool>(iswctype_l(c, m, __l.get())); #else bool result = false; wint_t ch = static_cast<wint_t>(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 |= (iswspace_l(ch, __l.get()) != 0); + if ((m & print) == print) result |= (iswprint_l(ch, __l.get()) != 0); + if ((m & cntrl) == cntrl) result |= (iswcntrl_l(ch, __l.get()) != 0); + if ((m & upper) == upper) result |= (iswupper_l(ch, __l.get()) != 0); + if ((m & lower) == lower) result |= (iswlower_l(ch, __l.get()) != 0); + if ((m & alpha) == alpha) result |= (iswalpha_l(ch, __l.get()) != 0); + if ((m & digit) == digit) result |= (iswdigit_l(ch, __l.get()) != 0); + if ((m & punct) == punct) result |= (iswpunct_l(ch, __l.get()) != 0); + if ((m & xdigit) == xdigit) result |= (iswxdigit_l(ch, __l.get()) != 0); + if ((m & blank) == blank) result |= (iswblank_l(ch, __l.get()) != 0); return result; #endif } @@ -1285,32 +1277,32 @@ { *vec = 0; wint_t ch = static_cast<wint_t>(*low); - if (iswspace_l(ch, __l)) + if (iswspace_l(ch, __l.get())) *vec |= space; #ifndef _LIBCPP_CTYPE_MASK_IS_COMPOSITE_PRINT - if (iswprint_l(ch, __l)) + if (iswprint_l(ch, __l.get())) *vec |= print; #endif - if (iswcntrl_l(ch, __l)) + if (iswcntrl_l(ch, __l.get())) *vec |= cntrl; - if (iswupper_l(ch, __l)) + if (iswupper_l(ch, __l.get())) *vec |= upper; - if (iswlower_l(ch, __l)) + if (iswlower_l(ch, __l.get())) *vec |= lower; #ifndef _LIBCPP_CTYPE_MASK_IS_COMPOSITE_ALPHA - if (iswalpha_l(ch, __l)) + if (iswalpha_l(ch, __l.get())) *vec |= alpha; #endif - if (iswdigit_l(ch, __l)) + if (iswdigit_l(ch, __l.get())) *vec |= digit; - if (iswpunct_l(ch, __l)) + if (iswpunct_l(ch, __l.get())) *vec |= punct; #ifndef _LIBCPP_CTYPE_MASK_IS_COMPOSITE_XDIGIT - if (iswxdigit_l(ch, __l)) + if (iswxdigit_l(ch, __l.get())) *vec |= xdigit; #endif #if !defined(__sun__) - if (iswblank_l(ch, __l)) + if (iswblank_l(ch, __l.get())) *vec |= blank; #endif } @@ -1324,20 +1316,20 @@ for (; low != high; ++low) { #ifdef _LIBCPP_WCTYPE_IS_MASK - if (iswctype_l(*low, m, __l)) + if (iswctype_l(*low, m, __l.get())) break; #else wint_t ch = static_cast<wint_t>(*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 && iswspace_l(ch, __l.get())) break; + if ((m & print) == print && iswprint_l(ch, __l.get())) break; + if ((m & cntrl) == cntrl && iswcntrl_l(ch, __l.get())) break; + if ((m & upper) == upper && iswupper_l(ch, __l.get())) break; + if ((m & lower) == lower && iswlower_l(ch, __l.get())) break; + if ((m & alpha) == alpha && iswalpha_l(ch, __l.get())) break; + if ((m & digit) == digit && iswdigit_l(ch, __l.get())) break; + if ((m & punct) == punct && iswpunct_l(ch, __l.get())) break; + if ((m & xdigit) == xdigit && iswxdigit_l(ch, __l.get())) break; + if ((m & blank) == blank && iswblank_l(ch, __l.get())) break; #endif } return low; @@ -1349,20 +1341,20 @@ for (; low != high; ++low) { #ifdef _LIBCPP_WCTYPE_IS_MASK - if (!iswctype_l(*low, m, __l)) + if (!iswctype_l(*low, m, __l.get())) break; #else wint_t ch = static_cast<wint_t>(*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 && iswspace_l(ch, __l.get())) continue; + if ((m & print) == print && iswprint_l(ch, __l.get())) continue; + if ((m & cntrl) == cntrl && iswcntrl_l(ch, __l.get())) continue; + if ((m & upper) == upper && iswupper_l(ch, __l.get())) continue; + if ((m & lower) == lower && iswlower_l(ch, __l.get())) continue; + if ((m & alpha) == alpha && iswalpha_l(ch, __l.get())) continue; + if ((m & digit) == digit && iswdigit_l(ch, __l.get())) continue; + if ((m & punct) == punct && iswpunct_l(ch, __l.get())) continue; + if ((m & xdigit) == xdigit && iswxdigit_l(ch, __l.get())) continue; + if ((m & blank) == blank && iswblank_l(ch, __l.get())) continue; break; #endif } @@ -1372,49 +1364,49 @@ wchar_t ctype_byname<wchar_t>::do_toupper(char_type c) const { - return towupper_l(c, __l); + return towupper_l(c, __l.get()); } const wchar_t* ctype_byname<wchar_t>::do_toupper(char_type* low, const char_type* high) const { for (; low != high; ++low) - *low = towupper_l(*low, __l); + *low = towupper_l(*low, __l.get()); return low; } wchar_t ctype_byname<wchar_t>::do_tolower(char_type c) const { - return towlower_l(c, __l); + return towlower_l(c, __l.get()); } const wchar_t* ctype_byname<wchar_t>::do_tolower(char_type* low, const char_type* high) const { for (; low != high; ++low) - *low = towlower_l(*low, __l); + *low = towlower_l(*low, __l.get()); return low; } wchar_t ctype_byname<wchar_t>::do_widen(char c) const { - return __libcpp_btowc_l(c, __l); + return __libcpp_btowc_l(c, __l.get()); } const char* ctype_byname<wchar_t>::do_widen(const char* low, const char* high, char_type* dest) const { for (; low != high; ++low, ++dest) - *dest = __libcpp_btowc_l(*low, __l); + *dest = __libcpp_btowc_l(*low, __l.get()); return low; } char ctype_byname<wchar_t>::do_narrow(char_type c, char dfault) const { - int r = __libcpp_wctob_l(c, __l); + int r = __libcpp_wctob_l(c, __l.get()); return r != static_cast<int>(WEOF) ? static_cast<char>(r) : dfault; } @@ -1423,7 +1415,7 @@ { for (; low != high; ++low, ++dest) { - int r = __libcpp_wctob_l(*low, __l); + int r = __libcpp_wctob_l(*low, __l.get()); *dest = r != static_cast<int>(WEOF) ? static_cast<char>(r) : dfault; } return low; @@ -1496,26 +1488,23 @@ codecvt<wchar_t, char, mbstate_t>::codecvt(size_t refs) : locale::facet(refs), - __l(_LIBCPP_GET_C_LOCALE) + __l() { } codecvt<wchar_t, char, mbstate_t>::codecvt(const char* nm, size_t refs) : locale::facet(refs), - __l(newlocale(LC_ALL_MASK, nm, 0)) + __l(nm) { #ifndef _LIBCPP_NO_EXCEPTIONS - if (__l == 0) + if (__l.get() == 0) throw runtime_error("codecvt_byname<wchar_t, char, mbstate_t>::codecvt_byname" " failed to construct for " + string(nm)); #endif // _LIBCPP_NO_EXCEPTIONS } codecvt<wchar_t, char, mbstate_t>::~codecvt() -{ - if (__l != _LIBCPP_GET_C_LOCALE) - freelocale(__l); -} +{} codecvt<wchar_t, char, mbstate_t>::result codecvt<wchar_t, char, mbstate_t>::do_out(state_type& st, @@ -1534,13 +1523,13 @@ // save state in case it is needed to recover to_nxt on error mbstate_t save_state = st; size_t n = __libcpp_wcsnrtombs_l(to, &frm_nxt, static_cast<size_t>(fend-frm), - static_cast<size_t>(to_end-to), &st, __l); + static_cast<size_t>(to_end-to), &st, __l.get()); if (n == size_t(-1)) { // need to recover to_nxt for (to_nxt = to; frm != frm_nxt; ++frm) { - n = __libcpp_wcrtomb_l(to_nxt, *frm, &save_state, __l); + n = __libcpp_wcrtomb_l(to_nxt, *frm, &save_state, __l.get()); if (n == size_t(-1)) break; to_nxt += n; @@ -1557,7 +1546,7 @@ { // Try to write the terminating null extern_type tmp[MB_LEN_MAX]; - n = __libcpp_wcrtomb_l(tmp, intern_type(), &st, __l); + n = __libcpp_wcrtomb_l(tmp, intern_type(), &st, __l.get()); if (n == size_t(-1)) // on error return error; if (n > static_cast<size_t>(to_end-to_nxt)) // is there room? @@ -1591,14 +1580,14 @@ // save state in case it is needed to recover to_nxt on error mbstate_t save_state = st; size_t n = __libcpp_mbsnrtowcs_l(to, &frm_nxt, static_cast<size_t>(fend-frm), - static_cast<size_t>(to_end-to), &st, __l); + static_cast<size_t>(to_end-to), &st, __l.get()); if (n == size_t(-1)) { // need to recover to_nxt for (to_nxt = to; frm != frm_nxt; ++to_nxt) { n = __libcpp_mbrtowc_l(to_nxt, frm, static_cast<size_t>(fend-frm), - &save_state, __l); + &save_state, __l.get()); switch (n) { case 0: @@ -1626,7 +1615,7 @@ if (fend != frm_end) // set up next null terminated sequence { // Try to write the terminating null - n = __libcpp_mbrtowc_l(to_nxt, frm_nxt, 1, &st, __l); + n = __libcpp_mbrtowc_l(to_nxt, frm_nxt, 1, &st, __l.get()); if (n != 0) // on error return error; ++to_nxt; @@ -1646,7 +1635,7 @@ { to_nxt = to; extern_type tmp[MB_LEN_MAX]; - size_t n = __libcpp_wcrtomb_l(tmp, intern_type(), &st, __l); + size_t n = __libcpp_wcrtomb_l(tmp, intern_type(), &st, __l.get()); if (n == size_t(-1) || n == 0) // on error return error; --n; @@ -1661,12 +1650,12 @@ codecvt<wchar_t, char, mbstate_t>::do_encoding() const _NOEXCEPT { #ifndef __CloudABI__ - if (__libcpp_mbtowc_l(nullptr, nullptr, MB_LEN_MAX, __l) != 0) + if (__libcpp_mbtowc_l(nullptr, nullptr, MB_LEN_MAX, __l.get()) != 0) return -1; #endif // stateless encoding - if (__l == 0 || __libcpp_mb_cur_max_l(__l) == 1) // there are no known constant length encodings + if (__l.get() == 0 || __libcpp_mb_cur_max_l(__l.get()) == 1) // there are no known constant length encodings return 1; // which take more than 1 char to form a wchar_t return 0; } @@ -1684,7 +1673,7 @@ int nbytes = 0; for (size_t nwchar_t = 0; nwchar_t < mx && frm != frm_end; ++nwchar_t) { - size_t n = __libcpp_mbrlen_l(frm, static_cast<size_t>(frm_end-frm), &st, __l); + size_t n = __libcpp_mbrlen_l(frm, static_cast<size_t>(frm_end-frm), &st, __l.get()); switch (n) { case 0: @@ -1706,7 +1695,7 @@ int codecvt<wchar_t, char, mbstate_t>::do_max_length() const _NOEXCEPT { - return __l == 0 ? 1 : static_cast<int>(__libcpp_mb_cur_max_l(__l)); + return __l.get() == 0 ? 1 : static_cast<int>(__libcpp_mb_cur_max_l(__l.get())); } // Valid UTF ranges @@ -4258,9 +4247,9 @@ { if (strcmp(nm, "C") != 0) { - __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale); + __newlocale_raii loc(nm); #ifndef _LIBCPP_NO_EXCEPTIONS - if (loc == nullptr) + if (loc.get() == nullptr) throw runtime_error("numpunct_byname<char>::numpunct_byname" " failed to construct for " + string(nm)); #endif // _LIBCPP_NO_EXCEPTIONS @@ -4297,9 +4286,9 @@ { if (strcmp(nm, "C") != 0) { - __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale); + __newlocale_raii loc(nm); #ifndef _LIBCPP_NO_EXCEPTIONS - if (loc == nullptr) + if (loc.get() == nullptr) throw runtime_error("numpunct_byname<char>::numpunct_byname" " failed to construct for " + string(nm)); #endif // _LIBCPP_NO_EXCEPTIONS @@ -4703,29 +4692,27 @@ // time_get_byname __time_get::__time_get(const char* nm) - : __loc_(newlocale(LC_ALL_MASK, nm, 0)) + : __loc_(nm) { #ifndef _LIBCPP_NO_EXCEPTIONS - if (__loc_ == 0) + if (__loc_.get() == 0) throw runtime_error("time_get_byname" " failed to construct for " + string(nm)); #endif // _LIBCPP_NO_EXCEPTIONS } __time_get::__time_get(const string& nm) - : __loc_(newlocale(LC_ALL_MASK, nm.c_str(), 0)) + : __loc_(nm.c_str()) { #ifndef _LIBCPP_NO_EXCEPTIONS - if (__loc_ == 0) + if (__loc_.get() == 0) throw runtime_error("time_get_byname" " failed to construct for " + nm); #endif // _LIBCPP_NO_EXCEPTIONS } __time_get::~__time_get() -{ - freelocale(__loc_); -} +{} #if defined(__clang__) #pragma clang diagnostic ignored "-Wmissing-field-initializers" #endif @@ -4751,7 +4738,7 @@ char f[3] = {0}; f[0] = '%'; f[1] = fmt; - size_t n = strftime_l(buf, countof(buf), f, &t, __loc_); + size_t n = strftime_l(buf, countof(buf), f, &t, __loc_.get()); char* bb = buf; char* be = buf + n; string result; @@ -4899,12 +4886,12 @@ char f[3] = {0}; f[0] = '%'; f[1] = fmt; - strftime_l(buf, countof(buf), f, &t, __loc_); + strftime_l(buf, countof(buf), f, &t, __loc_.get()); wchar_t wbuf[100]; wchar_t* wbb = wbuf; mbstate_t mb = {0}; const char* bb = buf; - size_t j = __libcpp_mbsrtowcs_l( wbb, &bb, countof(wbuf), &mb, __loc_); + size_t j = __libcpp_mbsrtowcs_l( wbb, &bb, countof(wbuf), &mb, __loc_.get()); if (j == size_t(-1)) __throw_runtime_error("locale not supported"); wchar_t* wbe = wbb + j; @@ -5041,26 +5028,26 @@ for (int i = 0; i < 7; ++i) { t.tm_wday = i; - strftime_l(buf, countof(buf), "%A", &t, __loc_); + strftime_l(buf, countof(buf), "%A", &t, __loc_.get()); __weeks_[i] = buf; - strftime_l(buf, countof(buf), "%a", &t, __loc_); + strftime_l(buf, countof(buf), "%a", &t, __loc_.get()); __weeks_[i+7] = buf; } // __months_ for (int i = 0; i < 12; ++i) { t.tm_mon = i; - strftime_l(buf, countof(buf), "%B", &t, __loc_); + strftime_l(buf, countof(buf), "%B", &t, __loc_.get()); __months_[i] = buf; - strftime_l(buf, countof(buf), "%b", &t, __loc_); + strftime_l(buf, countof(buf), "%b", &t, __loc_.get()); __months_[i+12] = buf; } // __am_pm_ t.tm_hour = 1; - strftime_l(buf, countof(buf), "%p", &t, __loc_); + strftime_l(buf, countof(buf), "%p", &t, __loc_.get()); __am_pm_[0] = buf; t.tm_hour = 13; - strftime_l(buf, countof(buf), "%p", &t, __loc_); + strftime_l(buf, countof(buf), "%p", &t, __loc_.get()); __am_pm_[1] = buf; __c_ = __analyze('c', ct); __r_ = __analyze('r', ct); @@ -5081,18 +5068,18 @@ for (int i = 0; i < 7; ++i) { t.tm_wday = i; - strftime_l(buf, countof(buf), "%A", &t, __loc_); + strftime_l(buf, countof(buf), "%A", &t, __loc_.get()); mb = mbstate_t(); const char* bb = buf; - size_t j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); + size_t j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_.get()); 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_); + strftime_l(buf, countof(buf), "%a", &t, __loc_.get()); mb = mbstate_t(); bb = buf; - j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); + j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_.get()); if (j == size_t(-1)) __throw_runtime_error("locale not supported"); wbe = wbuf + j; @@ -5102,18 +5089,18 @@ for (int i = 0; i < 12; ++i) { t.tm_mon = i; - strftime_l(buf, countof(buf), "%B", &t, __loc_); + strftime_l(buf, countof(buf), "%B", &t, __loc_.get()); mb = mbstate_t(); const char* bb = buf; - size_t j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); + size_t j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_.get()); 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_); + strftime_l(buf, countof(buf), "%b", &t, __loc_.get()); mb = mbstate_t(); bb = buf; - j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); + j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_.get()); if (j == size_t(-1)) __throw_runtime_error("locale not supported"); wbe = wbuf + j; @@ -5121,19 +5108,19 @@ } // __am_pm_ t.tm_hour = 1; - strftime_l(buf, countof(buf), "%p", &t, __loc_); + strftime_l(buf, countof(buf), "%p", &t, __loc_.get()); mb = mbstate_t(); const char* bb = buf; - size_t j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); + size_t j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_.get()); 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_); + strftime_l(buf, countof(buf), "%p", &t, __loc_.get()); mb = mbstate_t(); bb = buf; - j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); + j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_.get()); if (j == size_t(-1)) __throw_runtime_error("locale not supported"); wbe = wbuf + j; @@ -5363,30 +5350,27 @@ // time_put __time_put::__time_put(const char* nm) - : __loc_(newlocale(LC_ALL_MASK, nm, 0)) + : __loc_(nm) { #ifndef _LIBCPP_NO_EXCEPTIONS - if (__loc_ == 0) + if (__loc_.get() == 0) throw runtime_error("time_put_byname" " failed to construct for " + string(nm)); #endif // _LIBCPP_NO_EXCEPTIONS } __time_put::__time_put(const string& nm) - : __loc_(newlocale(LC_ALL_MASK, nm.c_str(), 0)) + : __loc_(nm.c_str()) { #ifndef _LIBCPP_NO_EXCEPTIONS - if (__loc_ == 0) + if (__loc_.get() == 0) throw runtime_error("time_put_byname" " failed to construct for " + nm); #endif // _LIBCPP_NO_EXCEPTIONS } __time_put::~__time_put() -{ - if (__loc_ != _LIBCPP_GET_C_LOCALE) - freelocale(__loc_); -} +{} void __time_put::__do_put(char* __nb, char*& __ne, const tm* __tm, @@ -5395,7 +5379,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 = strftime_l(__nb, countof(__nb, __ne), fmt, __tm, __loc_.get()); __ne = __nb + n; } @@ -5408,7 +5392,7 @@ __do_put(__nar, __ne, __tm, __fmt, __mod); mbstate_t mb = {0}; const char* __nb = __nar; - size_t j = __libcpp_mbsrtowcs_l(__wb, &__nb, countof(__wb, __we), &mb, __loc_); + size_t j = __libcpp_mbsrtowcs_l(__wb, &__nb, countof(__wb, __we), &mb, __loc_.get()); if (j == size_t(-1)) __throw_runtime_error("locale not supported"); __we = __wb + j; @@ -5793,9 +5777,9 @@ moneypunct_byname<char, false>::init(const char* nm) { typedef moneypunct<char, false> base; - __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale); + __newlocale_raii loc(nm); #ifndef _LIBCPP_NO_EXCEPTIONS - if (loc == nullptr) + if (loc.get() == nullptr) throw runtime_error("moneypunct_byname" " failed to construct for " + string(nm)); #endif // _LIBCPP_NO_EXCEPTIONS @@ -5837,9 +5821,9 @@ moneypunct_byname<char, true>::init(const char* nm) { typedef moneypunct<char, true> base; - __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale); + __newlocale_raii loc(nm); #ifndef _LIBCPP_NO_EXCEPTIONS - if (loc == nullptr) + if (loc.get() == nullptr) throw runtime_error("moneypunct_byname" " failed to construct for " + string(nm)); #endif // _LIBCPP_NO_EXCEPTIONS @@ -5898,9 +5882,9 @@ moneypunct_byname<wchar_t, false>::init(const char* nm) { typedef moneypunct<wchar_t, false> base; - __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale); + __newlocale_raii loc(nm); #ifndef _LIBCPP_NO_EXCEPTIONS - if (loc == nullptr) + if (loc.get() == nullptr) throw runtime_error("moneypunct_byname" " failed to construct for " + string(nm)); #endif // _LIBCPP_NO_EXCEPTIONS @@ -5965,9 +5949,9 @@ moneypunct_byname<wchar_t, true>::init(const char* nm) { typedef moneypunct<wchar_t, true> base; - __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale); + __newlocale_raii loc(nm); #ifndef _LIBCPP_NO_EXCEPTIONS - if (loc == nullptr) + if (loc.get() == nullptr) throw runtime_error("moneypunct_byname" " failed to construct for " + string(nm)); #endif // _LIBCPP_NO_EXCEPTIONS Index: include/support/xlocale/__strtonum_fallback.h =================================================================== --- include/support/xlocale/__strtonum_fallback.h +++ include/support/xlocale/__strtonum_fallback.h @@ -20,32 +20,32 @@ extern "C" { #endif inline _LIBCPP_ALWAYS_INLINE long double strtold_l(const char *nptr, - char **endptr, locale_t) { + char **endptr, __libcpp_locale_t) { return ::strtold(nptr, endptr); } inline _LIBCPP_ALWAYS_INLINE long long -strtoll_l(const char *nptr, char **endptr, int base, locale_t) { +strtoll_l(const char *nptr, char **endptr, int base, __libcpp_locale_t) { return ::strtoll(nptr, endptr, base); } inline _LIBCPP_ALWAYS_INLINE unsigned long long -strtoull_l(const char *nptr, char **endptr, int base, locale_t) { +strtoull_l(const char *nptr, char **endptr, int base, __libcpp_locale_t) { return ::strtoull(nptr, endptr, base); } inline _LIBCPP_ALWAYS_INLINE long long -wcstoll_l(const wchar_t *nptr, wchar_t **endptr, int base, locale_t) { +wcstoll_l(const wchar_t *nptr, wchar_t **endptr, int base, __libcpp_locale_t) { return ::wcstoll(nptr, endptr, base); } inline _LIBCPP_ALWAYS_INLINE unsigned long long -wcstoull_l(const wchar_t *nptr, wchar_t **endptr, int base, locale_t) { +wcstoull_l(const wchar_t *nptr, wchar_t **endptr, int base, __libcpp_locale_t) { return ::wcstoull(nptr, endptr, base); } inline _LIBCPP_ALWAYS_INLINE long double wcstold_l(const wchar_t *nptr, - wchar_t **endptr, locale_t) { + wchar_t **endptr, __libcpp_locale_t) { return ::wcstold(nptr, endptr); } Index: include/support/xlocale/__posix_l_fallback.h =================================================================== --- include/support/xlocale/__posix_l_fallback.h +++ include/support/xlocale/__posix_l_fallback.h @@ -20,141 +20,141 @@ extern "C" { #endif -inline _LIBCPP_ALWAYS_INLINE int isalnum_l(int c, locale_t) { +inline _LIBCPP_ALWAYS_INLINE int isalnum_l(int c, __libcpp_locale_t) { return ::isalnum(c); } -inline _LIBCPP_ALWAYS_INLINE int isalpha_l(int c, locale_t) { +inline _LIBCPP_ALWAYS_INLINE int isalpha_l(int c, __libcpp_locale_t) { return ::isalpha(c); } -inline _LIBCPP_ALWAYS_INLINE int isblank_l(int c, locale_t) { +inline _LIBCPP_ALWAYS_INLINE int isblank_l(int c, __libcpp_locale_t) { return ::isblank(c); } -inline _LIBCPP_ALWAYS_INLINE int iscntrl_l(int c, locale_t) { +inline _LIBCPP_ALWAYS_INLINE int iscntrl_l(int c, __libcpp_locale_t) { return ::iscntrl(c); } -inline _LIBCPP_ALWAYS_INLINE int isdigit_l(int c, locale_t) { +inline _LIBCPP_ALWAYS_INLINE int isdigit_l(int c, __libcpp_locale_t) { return ::isdigit(c); } -inline _LIBCPP_ALWAYS_INLINE int isgraph_l(int c, locale_t) { +inline _LIBCPP_ALWAYS_INLINE int isgraph_l(int c, __libcpp_locale_t) { return ::isgraph(c); } -inline _LIBCPP_ALWAYS_INLINE int islower_l(int c, locale_t) { +inline _LIBCPP_ALWAYS_INLINE int islower_l(int c, __libcpp_locale_t) { return ::islower(c); } -inline _LIBCPP_ALWAYS_INLINE int isprint_l(int c, locale_t) { +inline _LIBCPP_ALWAYS_INLINE int isprint_l(int c, __libcpp_locale_t) { return ::isprint(c); } -inline _LIBCPP_ALWAYS_INLINE int ispunct_l(int c, locale_t) { +inline _LIBCPP_ALWAYS_INLINE int ispunct_l(int c, __libcpp_locale_t) { return ::ispunct(c); } -inline _LIBCPP_ALWAYS_INLINE int isspace_l(int c, locale_t) { +inline _LIBCPP_ALWAYS_INLINE int isspace_l(int c, __libcpp_locale_t) { return ::isspace(c); } -inline _LIBCPP_ALWAYS_INLINE int isupper_l(int c, locale_t) { +inline _LIBCPP_ALWAYS_INLINE int isupper_l(int c, __libcpp_locale_t) { return ::isupper(c); } -inline _LIBCPP_ALWAYS_INLINE int isxdigit_l(int c, locale_t) { +inline _LIBCPP_ALWAYS_INLINE int isxdigit_l(int c, __libcpp_locale_t) { return ::isxdigit(c); } -inline _LIBCPP_ALWAYS_INLINE int iswalnum_l(wint_t c, locale_t) { +inline _LIBCPP_ALWAYS_INLINE int iswalnum_l(wint_t c, __libcpp_locale_t) { return ::iswalnum(c); } -inline _LIBCPP_ALWAYS_INLINE int iswalpha_l(wint_t c, locale_t) { +inline _LIBCPP_ALWAYS_INLINE int iswalpha_l(wint_t c, __libcpp_locale_t) { return ::iswalpha(c); } -inline _LIBCPP_ALWAYS_INLINE int iswblank_l(wint_t c, locale_t) { +inline _LIBCPP_ALWAYS_INLINE int iswblank_l(wint_t c, __libcpp_locale_t) { return ::iswblank(c); } -inline _LIBCPP_ALWAYS_INLINE int iswcntrl_l(wint_t c, locale_t) { +inline _LIBCPP_ALWAYS_INLINE int iswcntrl_l(wint_t c, __libcpp_locale_t) { return ::iswcntrl(c); } -inline _LIBCPP_ALWAYS_INLINE int iswdigit_l(wint_t c, locale_t) { +inline _LIBCPP_ALWAYS_INLINE int iswdigit_l(wint_t c, __libcpp_locale_t) { return ::iswdigit(c); } -inline _LIBCPP_ALWAYS_INLINE int iswgraph_l(wint_t c, locale_t) { +inline _LIBCPP_ALWAYS_INLINE int iswgraph_l(wint_t c, __libcpp_locale_t) { return ::iswgraph(c); } -inline _LIBCPP_ALWAYS_INLINE int iswlower_l(wint_t c, locale_t) { +inline _LIBCPP_ALWAYS_INLINE int iswlower_l(wint_t c, __libcpp_locale_t) { return ::iswlower(c); } -inline _LIBCPP_ALWAYS_INLINE int iswprint_l(wint_t c, locale_t) { +inline _LIBCPP_ALWAYS_INLINE int iswprint_l(wint_t c, __libcpp_locale_t) { return ::iswprint(c); } -inline _LIBCPP_ALWAYS_INLINE int iswpunct_l(wint_t c, locale_t) { +inline _LIBCPP_ALWAYS_INLINE int iswpunct_l(wint_t c, __libcpp_locale_t) { return ::iswpunct(c); } -inline _LIBCPP_ALWAYS_INLINE int iswspace_l(wint_t c, locale_t) { +inline _LIBCPP_ALWAYS_INLINE int iswspace_l(wint_t c, __libcpp_locale_t) { return ::iswspace(c); } -inline _LIBCPP_ALWAYS_INLINE int iswupper_l(wint_t c, locale_t) { +inline _LIBCPP_ALWAYS_INLINE int iswupper_l(wint_t c, __libcpp_locale_t) { return ::iswupper(c); } -inline _LIBCPP_ALWAYS_INLINE int iswxdigit_l(wint_t c, locale_t) { +inline _LIBCPP_ALWAYS_INLINE int iswxdigit_l(wint_t c, __libcpp_locale_t) { return ::iswxdigit(c); } -inline _LIBCPP_ALWAYS_INLINE int toupper_l(int c, locale_t) { +inline _LIBCPP_ALWAYS_INLINE int toupper_l(int c, __libcpp_locale_t) { return ::toupper(c); } -inline _LIBCPP_ALWAYS_INLINE int tolower_l(int c, locale_t) { +inline _LIBCPP_ALWAYS_INLINE int tolower_l(int c, __libcpp_locale_t) { return ::tolower(c); } -inline _LIBCPP_ALWAYS_INLINE int towupper_l(int c, locale_t) { +inline _LIBCPP_ALWAYS_INLINE int towupper_l(int c, __libcpp_locale_t) { return ::towupper(c); } -inline _LIBCPP_ALWAYS_INLINE int towlower_l(int c, locale_t) { +inline _LIBCPP_ALWAYS_INLINE int towlower_l(int c, __libcpp_locale_t) { return ::towlower(c); } inline _LIBCPP_ALWAYS_INLINE int strcoll_l(const char *s1, const char *s2, - locale_t) { + __libcpp_locale_t) { return ::strcoll(s1, s2); } inline _LIBCPP_ALWAYS_INLINE size_t strxfrm_l(char *dest, const char *src, - size_t n, locale_t) { + size_t n, __libcpp_locale_t) { return ::strxfrm(dest, src, n); } inline _LIBCPP_ALWAYS_INLINE size_t strftime_l(char *s, size_t max, const char *format, - const struct tm *tm, locale_t) { + const struct tm *tm, __libcpp_locale_t) { return ::strftime(s, max, format, tm); } inline _LIBCPP_ALWAYS_INLINE int wcscoll_l(const wchar_t *ws1, - const wchar_t *ws2, locale_t) { + const wchar_t *ws2, __libcpp_locale_t) { return ::wcscoll(ws1, ws2); } inline _LIBCPP_ALWAYS_INLINE size_t wcsxfrm_l(wchar_t *dest, const wchar_t *src, - size_t n, locale_t) { + size_t n, __libcpp_locale_t) { return ::wcsxfrm(dest, src, n); } Index: include/support/xlocale/__nop_locale_mgmt.h =================================================================== --- include/support/xlocale/__nop_locale_mgmt.h +++ include/support/xlocale/__nop_locale_mgmt.h @@ -16,34 +16,36 @@ #endif // Patch over lack of extended locale support -typedef void *locale_t; -static inline locale_t duplocale(locale_t) { - return NULL; -} +typedef void *__libcpp_locale_t; -static inline void freelocale(locale_t) { -} +inline _LIBCPP_ALWAYS_INLINE void __libcpp_freelocale(__libcpp_locale_t) {} -static inline locale_t newlocale(int, const char *, locale_t) { +inline _LIBCPP_ALWAYS_INLINE __libcpp_locale_t __libcpp_newlocale(int, const char *name, __libcpp_locale_t) { + // Big chunks of locale throw exceptions if newlocale returns NULL. + // So make sure we don't return null for the two locales we do support + if(name[0] == 'C' && name[1] == 0) + return static_cast<char *>(nullptr)+1; + if(name[0] == 'P' && name[1] == 'O' && name[2] == 'S' && name[3] == 'I' && name[4] == 'X' && name[5] == 0) + return static_cast<char *>(nullptr)+1; return NULL; } -static inline locale_t uselocale(locale_t) { - return NULL; +inline _LIBCPP_ALWAYS_INLINE __libcpp_locale_t __libcpp_uselocale(__libcpp_locale_t) { + return nullptr; } -#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) +#define _LIBCPP_LC_COLLATE_MASK (1 << LC_COLLATE) +#define _LIBCPP_LC_CTYPE_MASK (1 << LC_CTYPE) +#define _LIBCPP_LC_MESSAGES_MASK (1 << LC_MESSAGES) +#define _LIBCPP_LC_MONETARY_MASK (1 << LC_MONETARY) +#define _LIBCPP_LC_NUMERIC_MASK (1 << LC_NUMERIC) +#define _LIBCPP_LC_TIME_MASK (1 << LC_TIME) +#define _LIBCPP_LC_ALL_MASK (_LIBCPP_LC_COLLATE_MASK|\ + _LIBCPP_LC_CTYPE_MASK|\ + _LIBCPP_LC_MONETARY_MASK|\ + _LIBCPP_LC_NUMERIC_MASK|\ + _LIBCPP_LC_TIME_MASK|\ + _LIBCPP_LC_MESSAGES_MASK) #ifdef __cplusplus } // extern "C" Index: include/support/win32/locale_win32.h =================================================================== --- include/support/win32/locale_win32.h +++ include/support/win32/locale_win32.h @@ -16,30 +16,29 @@ #include "support/win32/support.h" #include "support/win32/locale_mgmt_win32.h" +#include <__locale_mgmt.h> #include <stdio.h> #include <memory> -lconv *localeconv_l( locale_t loc ); +lconv *localeconv_l( __libcpp_locale_t loc ); size_t mbrlen_l( const char *__restrict s, size_t n, - mbstate_t *__restrict ps, locale_t loc); + mbstate_t *__restrict ps, __libcpp_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 len, mbstate_t *__restrict ps, __libcpp_locale_t loc ); size_t wcrtomb_l( char *__restrict s, wchar_t wc, mbstate_t *__restrict ps, - locale_t loc); + __libcpp_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 n, mbstate_t *__restrict ps, __libcpp_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 nms, size_t len, mbstate_t *__restrict ps, __libcpp_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<locale_t>::type __locale_struct; -typedef _VSTD::unique_ptr<__locale_struct, decltype(&uselocale)> __locale_raii; + size_t nwc, size_t len, mbstate_t *__restrict ps, __libcpp_locale_t loc); +wint_t btowc_l( int c, __libcpp_locale_t loc ); +int wctob_l( wint_t c, __libcpp_locale_t loc ); inline _LIBCPP_ALWAYS_INLINE -decltype(MB_CUR_MAX) MB_CUR_MAX_L( locale_t __l ) +decltype(MB_CUR_MAX) MB_CUR_MAX_L( __libcpp_locale_t __l ) { - __locale_raii __current( uselocale(__l), uselocale ); + __locale_sentry __current(__l); return MB_CUR_MAX; } @@ -89,25 +88,25 @@ #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 ); +int snprintf_l(char *ret, size_t n, __libcpp_locale_t loc, const char *format, ...); +int asprintf_l( char **ret, __libcpp_locale_t loc, const char *format, ... ); +int vasprintf_l( char **ret, __libcpp_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*/ ) +inline int isblank_l( int c, __libcpp_locale_t /*loc*/ ) { return ( c == ' ' || c == '\t' ); } -inline int iswblank_l( wint_t c, locale_t /*loc*/ ) +inline int iswblank_l( wint_t c, __libcpp_locale_t /*loc*/ ) { return ( c == L' ' || c == L'\t' ); } #if defined(_LIBCPP_MSVCRT) -inline int isblank( int c, locale_t /*loc*/ ) +inline int isblank( int c, __libcpp_locale_t /*loc*/ ) { return ( c == ' ' || c == '\t' ); } -inline int iswblank( wint_t c, locale_t /*loc*/ ) +inline int iswblank( wint_t c, __libcpp_locale_t /*loc*/ ) { return ( c == L' ' || c == L'\t' ); } #endif // _LIBCPP_MSVCRT #endif // _LIBCPP_SUPPORT_WIN32_LOCALE_WIN32_H Index: include/support/win32/locale_mgmt_win32.h =================================================================== --- include/support/win32/locale_mgmt_win32.h +++ include/support/win32/locale_mgmt_win32.h @@ -12,22 +12,22 @@ #define _LIBCPP_SUPPORT_WIN32_LOCALE_MGMT_WIN32_H #include <xlocinfo.h> // _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 __libcpp_locale_t _locale_t +#define _LIBCPP_LC_COLLATE_MASK _M_COLLATE +#define _LIBCPP_LC_CTYPE_MASK _M_CTYPE +#define _LIBCPP_LC_MONETARY_MASK _M_MONETARY +#define _LIBCPP_LC_NUMERIC_MASK _M_NUMERIC +#define _LIBCPP_LC_TIME_MASK _M_TIME +#define _LIBCPP_LC_MESSAGES_MASK _M_MESSAGES +#define _LIBCPP_LC_ALL_MASK ( _LIBCPP_LC_COLLATE_MASK \ + | _LIBCPP_LC_CTYPE_MASK \ + | _LIBCPP_LC_MESSAGES_MASK \ + | _LIBCPP_LC_MONETARY_MASK \ + | _LIBCPP_LC_NUMERIC_MASK \ + | _LIBCPP_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 ); +__libcpp_locale_t __libcpp_newlocale( int mask, const char * locale, __libcpp_locale_t base ); +__libcpp_locale_t __libcpp_uselocale( __libcpp_locale_t newloc ); #endif // _LIBCPP_SUPPORT_WIN32_LOCALE_MGMT_WIN32_H Index: include/support/solaris/xlocale.h =================================================================== --- include/support/solaris/xlocale.h +++ include/support/solaris/xlocale.h @@ -21,41 +21,41 @@ #endif -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, ...); +int snprintf_l(char *__s, size_t __n, __libcpp_locale_t __l, const char *__format, ...); +int asprintf_l(char **__s, __libcpp_locale_t __l, const char *__format, ...); -int sscanf_l(const char *__s, locale_t __l, const char *__format, ...); +int sscanf_l(const char *__s, __libcpp_locale_t __l, const char *__format, ...); -int toupper_l(int __c, locale_t __l); -int tolower_l(int __c, locale_t __l); +int toupper_l(int __c, __libcpp_locale_t __l); +int tolower_l(int __c, __libcpp_locale_t __l); struct lconv *localeconv(void); -struct lconv *localeconv_l(locale_t __l); +struct lconv *localeconv_l(__libcpp_locale_t __l); // FIXME: These are quick-and-dirty hacks to make things pretend to work static inline long long strtoll_l(const char *__nptr, char **__endptr, - int __base, locale_t __loc) { + int __base, __libcpp_locale_t __loc) { return strtoll(__nptr, __endptr, __base); } static inline long strtol_l(const char *__nptr, char **__endptr, - int __base, locale_t __loc) { + int __base, __libcpp_locale_t __loc) { return strtol(__nptr, __endptr, __base); } static inline long double strtold_l(const char *__nptr, char **__endptr, - locale_t __loc) { + __libcpp_locale_t __loc) { return strtold(__nptr, __endptr); } static inline unsigned long long strtoull_l(const char *__nptr, char **__endptr, - int __base, locale_t __loc) { + int __base, __libcpp_locale_t __loc) { return strtoull(__nptr, __endptr, __base); } static inline unsigned long strtoul_l(const char *__nptr, char **__endptr, - int __base, locale_t __loc) { + int __base, __libcpp_locale_t __loc) { return strtoul(__nptr, __endptr, __base); } Index: include/support/musl/xlocale.h =================================================================== --- include/support/musl/xlocale.h +++ include/support/musl/xlocale.h @@ -26,28 +26,28 @@ #endif static inline long long strtoll_l(const char *nptr, char **endptr, int base, - locale_t) { + __libcpp_locale_t) { return strtoll(nptr, endptr, base); } static inline unsigned long long strtoull_l(const char *nptr, char **endptr, - int base, locale_t) { + int base, __libcpp_locale_t) { return strtoull(nptr, endptr, base); } static inline long long wcstoll_l(const wchar_t *nptr, wchar_t **endptr, - int base, locale_t) { + int base, __libcpp_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) { + __libcpp_locale_t) { return wcstoull(nptr, endptr, base); } static inline long double wcstold_l(const wchar_t *nptr, wchar_t **endptr, - locale_t) { + __libcpp_locale_t) { return wcstold(nptr, endptr); } Index: include/support/ibm/xlocale.h =================================================================== --- include/support/ibm/xlocale.h +++ include/support/ibm/xlocale.h @@ -23,186 +23,186 @@ // AIX 7.1 and higher has these definitions. Definitions and stubs // are provied here as a temporary workaround on AIX 6.1. static inline -int isalnum_l(int c, locale_t locale) +int isalnum_l(int c, __libcpp_locale_t locale) { return __xisalnum(locale, c); } static inline -int isalpha_l(int c, locale_t locale) +int isalpha_l(int c, __libcpp_locale_t locale) { return __xisalpha(locale, c); } static inline -int isblank_l(int c, locale_t locale) +int isblank_l(int c, __libcpp_locale_t locale) { return __xisblank(locale, c); } static inline -int iscntrl_l(int c, locale_t locale) +int iscntrl_l(int c, __libcpp_locale_t locale) { return __xiscntrl(locale, c); } static inline -int isdigit_l(int c, locale_t locale) +int isdigit_l(int c, __libcpp_locale_t locale) { return __xisdigit(locale, c); } static inline -int isgraph_l(int c, locale_t locale) +int isgraph_l(int c, __libcpp_locale_t locale) { return __xisgraph(locale, c); } static inline -int islower_l(int c, locale_t locale) +int islower_l(int c, __libcpp_locale_t locale) { return __xislower(locale, c); } static inline -int isprint_l(int c, locale_t locale) +int isprint_l(int c, __libcpp_locale_t locale) { return __xisprint(locale, c); } static inline -int ispunct_l(int c, locale_t locale) +int ispunct_l(int c, __libcpp_locale_t locale) { return __xispunct(locale, c); } static inline -int isspace_l(int c, locale_t locale) +int isspace_l(int c, __libcpp_locale_t locale) { return __xisspace(locale, c); } static inline -int isupper_l(int c, locale_t locale) +int isupper_l(int c, __libcpp_locale_t locale) { return __xisupper(locale, c); } static inline -int isxdigit_l(int c, locale_t locale) +int isxdigit_l(int c, __libcpp_locale_t locale) { return __xisxdigit(locale, c); } static inline -int iswalnum_l(wchar_t wc, locale_t locale) +int iswalnum_l(wchar_t wc, __libcpp_locale_t locale) { return __xiswalnum(locale, wc); } static inline -int iswalpha_l(wchar_t wc, locale_t locale) +int iswalpha_l(wchar_t wc, __libcpp_locale_t locale) { return __xiswalpha(locale, wc); } static inline -int iswblank_l(wchar_t wc, locale_t locale) +int iswblank_l(wchar_t wc, __libcpp_locale_t locale) { return __xiswblank(locale, wc); } static inline -int iswcntrl_l(wchar_t wc, locale_t locale) +int iswcntrl_l(wchar_t wc, __libcpp_locale_t locale) { return __xiswcntrl(locale, wc); } static inline -int iswdigit_l(wchar_t wc, locale_t locale) +int iswdigit_l(wchar_t wc, __libcpp_locale_t locale) { return __xiswdigit(locale, wc); } static inline -int iswgraph_l(wchar_t wc, locale_t locale) +int iswgraph_l(wchar_t wc, __libcpp_locale_t locale) { return __xiswgraph(locale, wc); } static inline -int iswlower_l(wchar_t wc, locale_t locale) +int iswlower_l(wchar_t wc, __libcpp_locale_t locale) { return __xiswlower(locale, wc); } static inline -int iswprint_l(wchar_t wc, locale_t locale) +int iswprint_l(wchar_t wc, __libcpp_locale_t locale) { return __xiswprint(locale, wc); } static inline -int iswpunct_l(wchar_t wc, locale_t locale) +int iswpunct_l(wchar_t wc, __libcpp_locale_t locale) { return __xiswpunct(locale, wc); } static inline -int iswspace_l(wchar_t wc, locale_t locale) +int iswspace_l(wchar_t wc, __libcpp_locale_t locale) { return __xiswspace(locale, wc); } static inline -int iswupper_l(wchar_t wc, locale_t locale) +int iswupper_l(wchar_t wc, __libcpp_locale_t locale) { return __xiswupper(locale, wc); } static inline -int iswxdigit_l(wchar_t wc, locale_t locale) +int iswxdigit_l(wchar_t wc, __libcpp_locale_t locale) { return __xiswxdigit(locale, wc); } static inline -int iswctype_l(wint_t wc, wctype_t desc, locale_t locale) +int iswctype_l(wint_t wc, wctype_t desc, __libcpp_locale_t locale) { return __xiswctype(locale, wc, desc); } static inline -int toupper_l(int c, locale_t locale) +int toupper_l(int c, __libcpp_locale_t locale) { return __xtoupper(locale, c); } static inline -int tolower_l(int c, locale_t locale) +int tolower_l(int c, __libcpp_locale_t locale) { return __xtolower(locale, c); } static inline -wint_t towupper_l(wint_t wc, locale_t locale) +wint_t towupper_l(wint_t wc, __libcpp_locale_t locale) { return __xtowupper(locale, wc); } static inline -wint_t towlower_l(wint_t wc, locale_t locale) +wint_t towlower_l(wint_t wc, __libcpp_locale_t locale) { return __xtowlower(locale, wc); } static inline -int strcoll_l(const char *__s1, const char *__s2, locale_t locale) +int strcoll_l(const char *__s1, const char *__s2, __libcpp_locale_t locale) { return __xstrcoll(locale, __s1, __s2); } static inline -int wcscoll_l(const wchar_t *__s1, const wchar_t *__s2, locale_t locale) +int wcscoll_l(const wchar_t *__s1, const wchar_t *__s2, __libcpp_locale_t locale) { return __xwcscoll(locale, __s1, __s2); } static inline -size_t strxfrm_l(char *__s1, const char *__s2, size_t __n, locale_t locale) +size_t strxfrm_l(char *__s1, const char *__s2, size_t __n, __libcpp_locale_t locale) { return __xstrxfrm(locale, __s1, __s2, __n); } static inline size_t wcsxfrm_l(wchar_t *__ws1, const wchar_t *__ws2, size_t __n, - locale_t locale) + __libcpp_locale_t locale) { return __xwcsxfrm(locale, __ws1, __ws2, __n); } @@ -212,7 +212,7 @@ // implemented yet. static inline size_t strftime_l(char *__s, size_t __size, const char *__fmt, - const struct tm *__tm, locale_t locale) { + const struct tm *__tm, __libcpp_locale_t locale) { return __xstrftime(locale, __s, __size, __fmt, __tm); } @@ -220,27 +220,27 @@ // to make things pretend to work static inline long long strtoll_l(const char *__nptr, char **__endptr, - int __base, locale_t locale) { + int __base, __libcpp_locale_t locale) { return strtoll(__nptr, __endptr, __base); } static inline long strtol_l(const char *__nptr, char **__endptr, - int __base, locale_t locale) { + int __base, __libcpp_locale_t locale) { return strtol(__nptr, __endptr, __base); } static inline long double strtold_l(const char *__nptr, char **__endptr, - locale_t locale) { + __libcpp_locale_t locale) { return strtold(__nptr, __endptr); } static inline unsigned long long strtoull_l(const char *__nptr, char **__endptr, - int __base, locale_t locale) { + int __base, __libcpp_locale_t locale) { return strtoull(__nptr, __endptr, __base); } static inline unsigned long strtoul_l(const char *__nptr, char **__endptr, - int __base, locale_t locale) { + int __base, __libcpp_locale_t locale) { return strtoul(__nptr, __endptr, __base); } Index: include/support/ibm/locale_mgmt_aix.h =================================================================== --- include/support/ibm/locale_mgmt_aix.h +++ include/support/ibm/locale_mgmt_aix.h @@ -22,59 +22,59 @@ // 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) +#define _LIBCPP_LC_COLLATE_MASK 1 +#define _LIBCPP_LC_CTYPE_MASK 2 +#define _LIBCPP_LC_MESSAGES_MASK 4 +#define _LIBCPP_LC_MONETARY_MASK 8 +#define _LIBCPP_LC_NUMERIC_MASK 16 +#define _LIBCPP_LC_TIME_MASK 32 +#define _LIBCPP_LC_ALL_MASK (_LIBCPP_LC_COLLATE_MASK | _LIBCPP_LC_CTYPE_MASK | \ + _LIBCPP_LC_MESSAGES_MASK | _LIBCPP_LC_MONETARY_MASK |\ + _LIBCPP_LC_NUMERIC_MASK | _LIBCPP_LC_TIME_MASK) -typedef void* locale_t; +typedef void* __libcpp_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) +__libcpp_locale_t __libcpp_newlocale(int category_mask, const char *locale, __libcpp_locale_t base) { _LC_locale_t *newloc, *loc; if ((loc = (_LC_locale_t *)__xopen_locale(locale)) == NULL) { errno = EINVAL; - return (locale_t)0; + return (__libcpp_locale_t)0; } if ((newloc = (_LC_locale_t *)calloc(1, sizeof(_LC_locale_t))) == NULL) { errno = ENOMEM; - return (locale_t)0; + return (__libcpp_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) + if (category_mask & _LIBCPP_LC_COLLATE_MASK) newloc->lc_collate = loc->lc_collate; - if (category_mask & LC_CTYPE_MASK) + if (category_mask & _LIBCPP_LC_CTYPE_MASK) newloc->lc_ctype = loc->lc_ctype; - //if (category_mask & LC_MESSAGES_MASK) + //if (category_mask & _LIBCPP_LC_MESSAGES_MASK) // newloc->lc_messages = loc->lc_messages; - if (category_mask & LC_MONETARY_MASK) + if (category_mask & _LIBCPP_LC_MONETARY_MASK) newloc->lc_monetary = loc->lc_monetary; - if (category_mask & LC_TIME_MASK) + if (category_mask & _LIBCPP_LC_TIME_MASK) newloc->lc_time = loc->lc_time; - if (category_mask & LC_NUMERIC_MASK) + if (category_mask & _LIBCPP_LC_NUMERIC_MASK) newloc->lc_numeric = loc->lc_numeric; - return (locale_t)newloc; + return (__libcpp_locale_t)newloc; } static inline -void freelocale(locale_t locobj) +void __libcpp_freelocale(__libcpp_locale_t locobj) { free(locobj); } static inline -locale_t uselocale(locale_t newloc) +__libcpp_locale_t __libcpp_uselocale(__libcpp_locale_t newloc) { - return (locale_t)0; + return (__libcpp_locale_t)0; } #endif // !defined(_AIX71) Index: include/locale =================================================================== --- include/locale +++ include/locale @@ -221,20 +221,6 @@ _LIBCPP_BEGIN_NAMESPACE_STD -#if defined(__APPLE__) || defined(__FreeBSD__) -# define _LIBCPP_GET_C_LOCALE 0 -#elif defined(__CloudABI__) || defined(__NetBSD__) -# define _LIBCPP_GET_C_LOCALE LC_C_LOCALE -#else -# define _LIBCPP_GET_C_LOCALE __cloc() - // Get the C locale object - _LIBCPP_FUNC_VIS locale_t __cloc(); -#define __cloc_defined -#endif - -typedef _VSTD::remove_pointer<locale_t>::type __locale_struct; -typedef _VSTD::unique_ptr<__locale_struct, decltype(&freelocale)> __locale_unique_ptr; - // __scan_keyword // Scans [__b, __e) until a match is found in the basic_strings range // [__kb, __ke) or until it can be shown that there is no match in [__kb, __ke). @@ -2274,7 +2260,7 @@ class _LIBCPP_TYPE_VIS __time_get { protected: - locale_t __loc_; + __newlocale_raii __loc_; __time_get(const char* __nm); __time_get(const string& __nm); @@ -2356,9 +2342,9 @@ class _LIBCPP_TYPE_VIS __time_put { - locale_t __loc_; + __maybe_clocale_raii __loc_; protected: - _LIBCPP_ALWAYS_INLINE __time_put() : __loc_(_LIBCPP_GET_C_LOCALE) {} + _LIBCPP_ALWAYS_INLINE __time_put() : __loc_() {} __time_put(const char* __nm); __time_put(const string& __nm); ~__time_put(); Index: include/__posix_locale_mgmt_defaults.h =================================================================== --- /dev/null +++ include/__posix_locale_mgmt_defaults.h @@ -0,0 +1,33 @@ +// -*- C++ -*- +//===----------------- __posix_locale_mgmt_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. +// +//===----------------------------------------------------------------------===// +// POSIX has some locale management functions that aren't in ISO C. We don't +// want to define those symbols on other platforms though, for fear of +// conflicts with user code. So here, we will define the mapping from an +// internal macro to the real POSIX symbol. +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_POSIX_LOCALE_MGMT_DEFAULTS_H +#define _LIBCPP_POSIX_LOCALE_MGMT_DEFAULTS_H + +typedef locale_t __libcpp_locale_t; + +#define __libcpp_freelocale(l) freelocale(l) +#define __libcpp_newlocale(mask, name, base) newlocale(mask, name, base) +#define __libcpp_uselocale(l) uselocale(l) + +#define _LIBCPP_LC_COLLATE_MASK LC_COLLATE_MASK +#define _LIBCPP_LC_CTYPE_MASK LC_CTYPE_MASK +#define _LIBCPP_LC_MESSAGES_MASK LC_MESSAGES_MASK +#define _LIBCPP_LC_MONETARY_MASK LC_MONETARY_MASK +#define _LIBCPP_LC_NUMERIC_MASK LC_NUMERIC_MASK +#define _LIBCPP_LC_TIME_MASK LC_TIME_MASK +#define _LIBCPP_LC_ALL_MASK LC_ALL_MASK + +#endif // _LIBCPP_POSIX_LOCALE_MGMT_DEFAULTS_H Index: include/__locale_mgmt.h =================================================================== --- /dev/null +++ include/__locale_mgmt.h @@ -0,0 +1,100 @@ +// -*- C++ -*- +//===------------------------- __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. +// +//===----------------------------------------------------------------------===// +// This file helps consolidate the preprocessor logic to pull in the right +// headers for newlocale, uselocale, and other locale management functions. +// It also includes RAII helpers for locale management. +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_LOCALE_MGMT_H +#define _LIBCPP_LOCALE_MGMT_H +#include <__config> +#include <locale.h> + +#if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__) +#include <support/win32/locale_mgmt_win32.h> +#elif defined(_AIX) +#include <support/ibm/locale_mgmt_aix.h> +#elif defined(_NEWLIB_VERSION) +# include <support/xlocale/__nop_locale_mgmt.h> +#elif __has_include(<xlocale.h>) +# include <xlocale.h> +# include <__posix_locale_mgmt_defaults.h> +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if defined(__APPLE__) || defined(__FreeBSD__) +# define _LIBCPP_GET_C_LOCALE 0 +#elif defined(__CloudABI__) || defined(__NetBSD__) +# define _LIBCPP_GET_C_LOCALE LC_C_LOCALE +#else +# define _LIBCPP_GET_C_LOCALE __cloc() + // Get the C locale object + _LIBCPP_FUNC_VIS __libcpp_locale_t __cloc(); +#define __cloc_defined +#endif + +class _LIBCPP_HIDDEN __locale_sentry +{ +private: + ::__libcpp_locale_t __old_locale; + + __locale_sentry(const __locale_sentry &); + __locale_sentry &operator=(const __locale_sentry &); +public: + _LIBCPP_ALWAYS_INLINE explicit __locale_sentry(::__libcpp_locale_t __l) : __old_locale(__libcpp_uselocale(__l)) {} + _LIBCPP_ALWAYS_INLINE ~__locale_sentry() {__libcpp_uselocale(__old_locale);} +}; + +class _LIBCPP_HIDDEN __newlocale_raii +{ +private: + ::__libcpp_locale_t __l; + + __newlocale_raii(const __newlocale_raii &); + __newlocale_raii &operator=(const __newlocale_raii &); +public: + _LIBCPP_ALWAYS_INLINE explicit __newlocale_raii(const char *__name) : + __l(::__libcpp_newlocale(_LIBCPP_LC_ALL_MASK, __name, 0)) + {} + + _LIBCPP_ALWAYS_INLINE ~__newlocale_raii() {::__libcpp_freelocale(__l);} + + _LIBCPP_ALWAYS_INLINE ::__libcpp_locale_t get() {return __l;} + _LIBCPP_ALWAYS_INLINE ::__libcpp_locale_t get() const {return __l;} +}; + +class _LIBCPP_HIDDEN __maybe_clocale_raii +{ +private: + ::__libcpp_locale_t __l; + + __maybe_clocale_raii(const __maybe_clocale_raii &); + __maybe_clocale_raii &operator=(const __maybe_clocale_raii &); +public: + _LIBCPP_ALWAYS_INLINE __maybe_clocale_raii() : __l(_LIBCPP_GET_C_LOCALE) {} + + _LIBCPP_ALWAYS_INLINE explicit __maybe_clocale_raii(const char *__name) : + __l(::__libcpp_newlocale(_LIBCPP_LC_ALL_MASK, __name, 0)) + {} + + _LIBCPP_ALWAYS_INLINE ~__maybe_clocale_raii() + { + if (__l != _LIBCPP_GET_C_LOCALE) + ::__libcpp_freelocale(__l); + } + + _LIBCPP_ALWAYS_INLINE ::__libcpp_locale_t get() {return __l;} + _LIBCPP_ALWAYS_INLINE ::__libcpp_locale_t get() const {return __l;} +}; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_SUPPORT_XLOCALE_LOCALE_MGMT_H Index: include/__locale =================================================================== --- include/__locale +++ include/__locale @@ -19,6 +19,7 @@ #include <cstdint> #include <cctype> #include <locale.h> +#include <__locale_mgmt.h> #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__) # include <support/win32/locale_win32.h> #elif defined(_AIX) @@ -69,12 +70,12 @@ typedef int category; static const category // values assigned here are for exposition only none = 0, - collate = LC_COLLATE_MASK, - ctype = LC_CTYPE_MASK, - monetary = LC_MONETARY_MASK, - numeric = LC_NUMERIC_MASK, - time = LC_TIME_MASK, - messages = LC_MESSAGES_MASK, + collate = _LIBCPP_LC_COLLATE_MASK, + ctype = _LIBCPP_LC_CTYPE_MASK, + monetary = _LIBCPP_LC_MONETARY_MASK, + numeric = _LIBCPP_LC_NUMERIC_MASK, + time = _LIBCPP_LC_TIME_MASK, + messages = _LIBCPP_LC_MESSAGES_MASK, all = collate | ctype | monetary | numeric | time | messages; // construct/copy/destroy: @@ -281,7 +282,7 @@ class _LIBCPP_TYPE_VIS collate_byname<char> : public collate<char> { - locale_t __l; + __newlocale_raii __l; public: typedef char char_type; typedef basic_string<char_type> string_type; @@ -300,7 +301,7 @@ class _LIBCPP_TYPE_VIS collate_byname<wchar_t> : public collate<wchar_t> { - locale_t __l; + __newlocale_raii __l; public: typedef wchar_t char_type; typedef basic_string<char_type> string_type; @@ -659,7 +660,7 @@ class _LIBCPP_TYPE_VIS ctype_byname<char> : public ctype<char> { - locale_t __l; + __newlocale_raii __l; public: explicit ctype_byname(const char*, size_t = 0); @@ -677,7 +678,7 @@ class _LIBCPP_TYPE_VIS ctype_byname<wchar_t> : public ctype<wchar_t> { - locale_t __l; + __newlocale_raii __l; public: explicit ctype_byname(const char*, size_t = 0); @@ -909,7 +910,7 @@ : public locale::facet, public codecvt_base { - locale_t __l; + __maybe_clocale_raii __l; public: typedef wchar_t intern_type; typedef char extern_type; Index: include/__bsd_locale_fallbacks.h =================================================================== --- include/__bsd_locale_fallbacks.h +++ include/__bsd_locale_fallbacks.h @@ -19,115 +19,112 @@ _LIBCPP_BEGIN_NAMESPACE_STD -typedef _VSTD::remove_pointer<locale_t>::type __use_locale_struct; -typedef _VSTD::unique_ptr<__use_locale_struct, decltype(&uselocale)> __locale_raii; - inline _LIBCPP_ALWAYS_INLINE -decltype(MB_CUR_MAX) __libcpp_mb_cur_max_l(locale_t __l) +decltype(MB_CUR_MAX) __libcpp_mb_cur_max_l(__libcpp_locale_t __l) { - __locale_raii __current( uselocale(__l), uselocale ); + std::__locale_sentry __current(__l); return MB_CUR_MAX; } inline _LIBCPP_ALWAYS_INLINE -wint_t __libcpp_btowc_l(int __c, locale_t __l) +wint_t __libcpp_btowc_l(int __c, __libcpp_locale_t __l) { - __locale_raii __current( uselocale(__l), uselocale ); + std::__locale_sentry __current(__l); return btowc(__c); } inline _LIBCPP_ALWAYS_INLINE -int __libcpp_wctob_l(wint_t __c, locale_t __l) +int __libcpp_wctob_l(wint_t __c, __libcpp_locale_t __l) { - __locale_raii __current( uselocale(__l), uselocale ); + std::__locale_sentry __current(__l); return wctob(__c); } inline _LIBCPP_ALWAYS_INLINE size_t __libcpp_wcsnrtombs_l(char *__dest, const wchar_t **__src, size_t __nwc, - size_t __len, mbstate_t *__ps, locale_t __l) + size_t __len, mbstate_t *__ps, __libcpp_locale_t __l) { - __locale_raii __current( uselocale(__l), uselocale ); + std::__locale_sentry __current(__l); return wcsnrtombs(__dest, __src, __nwc, __len, __ps); } inline _LIBCPP_ALWAYS_INLINE -size_t __libcpp_wcrtomb_l(char *__s, wchar_t __wc, mbstate_t *__ps, locale_t __l) +size_t __libcpp_wcrtomb_l(char *__s, wchar_t __wc, mbstate_t *__ps, __libcpp_locale_t __l) { - __locale_raii __current( uselocale(__l), uselocale ); + std::__locale_sentry __current(__l); return wcrtomb(__s, __wc, __ps); } inline _LIBCPP_ALWAYS_INLINE size_t __libcpp_mbsnrtowcs_l(wchar_t * __dest, const char **__src, size_t __nms, - size_t __len, mbstate_t *__ps, locale_t __l) + size_t __len, mbstate_t *__ps, __libcpp_locale_t __l) { - __locale_raii __current( uselocale(__l), uselocale ); + std::__locale_sentry __current(__l); return mbsnrtowcs(__dest, __src, __nms, __len, __ps); } inline _LIBCPP_ALWAYS_INLINE size_t __libcpp_mbrtowc_l(wchar_t *__pwc, const char *__s, size_t __n, - mbstate_t *__ps, locale_t __l) + mbstate_t *__ps, __libcpp_locale_t __l) { - __locale_raii __current( uselocale(__l), uselocale ); + std::__locale_sentry __current(__l); return mbrtowc(__pwc, __s, __n, __ps); } inline _LIBCPP_ALWAYS_INLINE -int __libcpp_mbtowc_l(wchar_t *__pwc, const char *__pmb, size_t __max, locale_t __l) +int __libcpp_mbtowc_l(wchar_t *__pwc, const char *__pmb, size_t __max, __libcpp_locale_t __l) { - __locale_raii __current( uselocale(__l), uselocale ); + std::__locale_sentry __current(__l); return mbtowc(__pwc, __pmb, __max); } inline _LIBCPP_ALWAYS_INLINE -size_t __libcpp_mbrlen_l(const char *__s, size_t __n, mbstate_t *__ps, locale_t __l) +size_t __libcpp_mbrlen_l(const char *__s, size_t __n, mbstate_t *__ps, __libcpp_locale_t __l) { - __locale_raii __current( uselocale(__l), uselocale ); + std::__locale_sentry __current(__l); return mbrlen(__s, __n, __ps); } inline _LIBCPP_ALWAYS_INLINE -lconv *__libcpp_localeconv_l(locale_t __l) +lconv *__libcpp_localeconv_l(__libcpp_locale_t __l) { - __locale_raii __current( uselocale(__l), uselocale ); + std::__locale_sentry __current(__l); return localeconv(); } inline _LIBCPP_ALWAYS_INLINE size_t __libcpp_mbsrtowcs_l(wchar_t *__dest, const char **__src, size_t __len, - mbstate_t *__ps, locale_t __l) + mbstate_t *__ps, __libcpp_locale_t __l) { - __locale_raii __current( uselocale(__l), uselocale ); + std::__locale_sentry __current(__l); return mbsrtowcs(__dest, __src, __len, __ps); } inline -int __libcpp_snprintf_l(char *__s, size_t __n, locale_t __l, const char *__format, ...) { +int __libcpp_snprintf_l(char *__s, size_t __n, __libcpp_locale_t __l, const char *__format, ...) { va_list __va; va_start(__va, __format); - __locale_raii __current( uselocale(__l), uselocale ); + std::__locale_sentry __current(__l); int __res = vsnprintf(__s, __n, __format, __va); va_end(__va); return __res; } inline -int __libcpp_asprintf_l(char **__s, locale_t __l, const char *__format, ...) { +int __libcpp_asprintf_l(char **__s, __libcpp_locale_t __l, const char *__format, ...) { va_list __va; va_start(__va, __format); - __locale_raii __current( uselocale(__l), uselocale ); + std::__locale_sentry __current(__l); int __res = vasprintf(__s, __format, __va); va_end(__va); return __res; } inline -int __libcpp_sscanf_l(const char *__s, locale_t __l, const char *__format, ...) { +int __libcpp_sscanf_l(const char *__s, __libcpp_locale_t __l, const char *__format, ...) { va_list __va; va_start(__va, __format); - __locale_raii __current( uselocale(__l), uselocale ); + std::__locale_sentry __current(__l); int __res = vsscanf(__s, __format, __va); va_end(__va); return __res;
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits