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::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; Index: include/__locale =================================================================== --- include/__locale +++ include/__locale @@ -19,6 +19,7 @@ #include #include #include +#include <__locale_mgmt.h> #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__) # include #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 : public collate { - locale_t __l; + __newlocale_raii __l; public: typedef char char_type; typedef basic_string string_type; @@ -300,7 +301,7 @@ class _LIBCPP_TYPE_VIS collate_byname : public collate { - locale_t __l; + __newlocale_raii __l; public: typedef wchar_t char_type; typedef basic_string string_type; @@ -659,7 +660,7 @@ class _LIBCPP_TYPE_VIS ctype_byname : public ctype { - 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 : public ctype { - 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/__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 + +#if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__) +#include +#elif defined(_AIX) +#include +#elif defined(_NEWLIB_VERSION) +# include +#elif __has_include() +# include +# 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/__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 =================================================================== --- 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::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/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/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/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/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/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 // _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/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 #include -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::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/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(nullptr)+1; + if(name[0] == 'P' && name[1] == 'O' && name[2] == 'S' && name[3] == 'I' && name[4] == 'X' && name[5] == 0) + return static_cast(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/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/__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: 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::collate_byname(const char* n, size_t refs) : collate(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::collate_byname" " failed to construct for " + string(n)); #endif // _LIBCPP_NO_EXCEPTIONS @@ -655,19 +655,17 @@ collate_byname::collate_byname(const string& name, size_t refs) : collate(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::collate_byname" " failed to construct for " + name); #endif // _LIBCPP_NO_EXCEPTIONS } collate_byname::~collate_byname() -{ - freelocale(__l); -} +{} int collate_byname::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::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(strxfrm_l(0, in.c_str(), 0, __l.get()), char()); + strxfrm_l(const_cast(out.c_str()), in.c_str(), out.size()+1, __l.get()); return out; } @@ -696,10 +694,10 @@ collate_byname::collate_byname(const char* n, size_t refs) : collate(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::collate_byname(size_t refs)" " failed to construct for " + string(n)); #endif // _LIBCPP_NO_EXCEPTIONS @@ -707,19 +705,17 @@ collate_byname::collate_byname(const string& name, size_t refs) : collate(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::collate_byname(size_t refs)" " failed to construct for " + name); #endif // _LIBCPP_NO_EXCEPTIONS } collate_byname::~collate_byname() -{ - freelocale(__l); -} +{} int collate_byname::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::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(wcsxfrm_l(0, in.c_str(), 0, __l.get()), wchar_t()); + wcsxfrm_l(const_cast(out.c_str()), in.c_str(), out.size()+1, __l.get()); return out; } @@ -1170,10 +1166,10 @@ ctype_byname::ctype_byname(const char* name, size_t refs) : ctype(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::ctype_byname" " failed to construct for " + string(name)); #endif // _LIBCPP_NO_EXCEPTIONS @@ -1181,45 +1177,43 @@ ctype_byname::ctype_byname(const string& name, size_t refs) : ctype(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::ctype_byname" " failed to construct for " + name); #endif // _LIBCPP_NO_EXCEPTIONS } ctype_byname::~ctype_byname() -{ - freelocale(__l); -} +{} char ctype_byname::do_toupper(char_type c) const { - return static_cast(toupper_l(static_cast(c), __l)); + return static_cast(toupper_l(static_cast(c), __l.get())); } 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(toupper_l(static_cast(*low), __l.get())); return low; } char ctype_byname::do_tolower(char_type c) const { - return static_cast(tolower_l(static_cast(c), __l)); + return static_cast(tolower_l(static_cast(c), __l.get())); } 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(tolower_l(static_cast(*low), __l.get())); return low; } @@ -1227,10 +1221,10 @@ ctype_byname::ctype_byname(const char* name, size_t refs) : ctype(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::ctype_byname" " failed to construct for " + string(name)); #endif // _LIBCPP_NO_EXCEPTIONS @@ -1238,38 +1232,36 @@ ctype_byname::ctype_byname(const string& name, size_t refs) : ctype(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::ctype_byname" " failed to construct for " + name); #endif // _LIBCPP_NO_EXCEPTIONS } ctype_byname::~ctype_byname() -{ - 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(iswctype_l(c, m, __l.get())); #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 |= (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(*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(*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(*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::do_toupper(char_type c) const { - return towupper_l(c, __l); + return towupper_l(c, __l.get()); } 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 = towupper_l(*low, __l.get()); return low; } wchar_t ctype_byname::do_tolower(char_type c) const { - return towlower_l(c, __l); + return towlower_l(c, __l.get()); } 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 = towlower_l(*low, __l.get()); return low; } wchar_t ctype_byname::do_widen(char c) const { - return __libcpp_btowc_l(c, __l); + return __libcpp_btowc_l(c, __l.get()); } const char* ctype_byname::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::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(WEOF) ? static_cast(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(WEOF) ? static_cast(r) : dfault; } return low; @@ -1496,26 +1488,23 @@ codecvt::codecvt(size_t refs) : locale::facet(refs), - __l(_LIBCPP_GET_C_LOCALE) + __l() { } codecvt::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::codecvt_byname" " failed to construct for " + string(nm)); #endif // _LIBCPP_NO_EXCEPTIONS } codecvt::~codecvt() -{ - if (__l != _LIBCPP_GET_C_LOCALE) - freelocale(__l); -} +{} codecvt::result codecvt::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(fend-frm), - static_cast(to_end-to), &st, __l); + static_cast(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(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(fend-frm), - static_cast(to_end-to), &st, __l); + static_cast(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(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::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(frm_end-frm), &st, __l); + size_t n = __libcpp_mbrlen_l(frm, static_cast(frm_end-frm), &st, __l.get()); switch (n) { case 0: @@ -1706,7 +1695,7 @@ int codecvt::do_max_length() const _NOEXCEPT { - return __l == 0 ? 1 : static_cast(__libcpp_mb_cur_max_l(__l)); + return __l.get() == 0 ? 1 : static_cast(__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::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::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::init(const char* nm) { typedef moneypunct 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::init(const char* nm) { typedef moneypunct 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::init(const char* nm) { typedef moneypunct 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::init(const char* nm) { typedef moneypunct 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: 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/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/xlocale.c =================================================================== --- src/support/solaris/xlocale.c +++ src/support/solaris/xlocale.c @@ -15,11 +15,11 @@ #include -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/win32/locale_win32.cpp =================================================================== --- src/support/win32/locale_win32.cpp +++ src/support/win32/locale_win32.cpp @@ -12,13 +12,13 @@ #include // 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 ); }