diff options
Diffstat (limited to 'system/include/libcxx/locale')
-rw-r--r-- | system/include/libcxx/locale | 408 |
1 files changed, 245 insertions, 163 deletions
diff --git a/system/include/libcxx/locale b/system/include/libcxx/locale index e9a18e32..83259214 100644 --- a/system/include/libcxx/locale +++ b/system/include/libcxx/locale @@ -187,28 +187,42 @@ template <class charT> class messages_byname; #include <cstdlib> #include <ctime> #if _WIN32 -#include <support/win32/support.h> // vasprintf +#include <support/win32/locale_win32.h> #else // _WIN32 #include <nl_types.h> #endif // !_WIN32 +#if __APPLE__ +#include <Availability.h> +#endif + +#include <__undef_min_max> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header +#endif _LIBCPP_BEGIN_NAMESPACE_STD -#ifndef _LIBCPP_STABLE_APPLE_ABI -// Get the C locale object -locale_t __cloc(); +#if __APPLE__ || __FreeBSD__ +# define _LIBCPP_GET_C_LOCALE 0 +#else +# define _LIBCPP_GET_C_LOCALE __cloc() + // Get the C locale object + 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; +#ifndef _LIBCPP_LOCALE__L_EXTENSIONS typedef _VSTD::unique_ptr<__locale_struct, decltype(&uselocale)> __locale_raii; +#endif // OSX has nice foo_l() functions that let you turn off use of the global // locale. Linux, not so much. The following functions avoid the locale when // that's possible and otherwise do the wrong thing. FIXME. -#ifndef _LIBCPP_STABLE_APPLE_ABI +#if defined(__linux__) || defined(EMSCRIPTEN) #ifdef _LIBCPP_LOCALE__L_EXTENSIONS decltype(MB_CUR_MAX_L(_VSTD::declval<locale_t>())) @@ -229,7 +243,7 @@ decltype(MB_CUR_MAX) __mb_cur_max_l(locale_t __l) _LIBCPP_ALWAYS_INLINE inline wint_t __btowc_l(int __c, locale_t __l) { -#ifdef _LIBCPP_STABLE_APPLE_ABI +#ifdef _LIBCPP_LOCALE__L_EXTENSIONS return btowc_l(__c, __l); #else __locale_raii __current(uselocale(__l), uselocale); @@ -340,7 +354,7 @@ size_t __mbsrtowcs_l(wchar_t *__dest, const char **__src, size_t __len, #endif } -_LIBCPP_ALWAYS_INLINE inline +inline int __sprintf_l(char *__s, locale_t __l, const char *__format, ...) { va_list __va; va_start(__va, __format); @@ -354,7 +368,7 @@ int __sprintf_l(char *__s, locale_t __l, const char *__format, ...) { return __res; } -_LIBCPP_ALWAYS_INLINE inline +inline int __snprintf_l(char *__s, size_t __n, locale_t __l, const char *__format, ...) { va_list __va; va_start(__va, __format); @@ -368,7 +382,7 @@ int __snprintf_l(char *__s, size_t __n, locale_t __l, const char *__format, ...) return __res; } -_LIBCPP_ALWAYS_INLINE inline +inline int __asprintf_l(char **__s, locale_t __l, const char *__format, ...) { va_list __va; va_start(__va, __format); @@ -382,7 +396,7 @@ int __asprintf_l(char **__s, locale_t __l, const char *__format, ...) { return __res; } -_LIBCPP_ALWAYS_INLINE inline +inline int __sscanf_l(const char *__s, locale_t __l, const char *__format, ...) { va_list __va; va_start(__va, __format); @@ -396,7 +410,7 @@ int __sscanf_l(const char *__s, locale_t __l, const char *__format, ...) { return __res; } -#endif // _LIBCPP_STABLE_APPLE_ABI +#endif // __linux__ // __scan_keyword // Scans [__b, __e) until a match is found in the basic_strings range @@ -425,7 +439,7 @@ __scan_keyword(_InputIterator& __b, _InputIterator __e, bool __case_sensitive = true) { typedef typename iterator_traits<_InputIterator>::value_type _CharT; - size_t __nkw = _VSTD::distance(__kb, __ke); + size_t __nkw = static_cast<size_t>(_VSTD::distance(__kb, __ke)); const unsigned char __doesnt_match = '\0'; const unsigned char __might_match = '\1'; const unsigned char __does_match = '\2'; @@ -590,7 +604,7 @@ __num_get<_CharT>::__stage2_int_loop(_CharT __ct, int __base, char* __a, char*& __dc = 0; return 0; } - if (__ct == __thousands_sep && __grouping.size() != 0) + if (__grouping.size() != 0 && __ct == __thousands_sep) { if (__g_end-__g < __num_get_buf_sz) { @@ -657,6 +671,15 @@ __num_get<_CharT>::__stage2_float_loop(_CharT __ct, bool& __in_units, char& __ex if (__f >= 32) return -1; char __x = __src[__f]; + if (__x == '-' || __x == '+') + { + if (__a_end == __a || (__a_end[-1] & 0xDF) == __exp) + { + *__a_end++ = __x; + return 0; + } + return -1; + } if (__a_end-__a < __num_get_buf_sz - 1) *__a_end++ = __x; if (__x == 'x' || __x == 'X') @@ -673,8 +696,8 @@ __num_get<_CharT>::__stage2_float_loop(_CharT __ct, bool& __in_units, char& __ex return 0; } -extern template class __num_get<char>; -extern template class __num_get<wchar_t>; +_LIBCPP_EXTERN_TEMPLATE(struct __num_get<char>) +_LIBCPP_EXTERN_TEMPLATE(struct __num_get<wchar_t>) template <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> > class _LIBCPP_VISIBLE num_get @@ -807,15 +830,11 @@ __num_get_signed_integral(const char* __a, const char* __a_end, { if (__a != __a_end) { - int __save_errno = errno; + typename remove_reference<decltype(errno)>::type __save_errno = errno; errno = 0; char *__p2; -#ifdef _LIBCPP_STABLE_APPLE_ABI - long long __ll = strtoll_l(__a, &__p2, __base, 0); -#else - long long __ll = strtoll_l(__a, &__p2, __base, __cloc()); -#endif - int __current_errno = errno; + long long __ll = strtoll_l(__a, &__p2, __base, _LIBCPP_GET_C_LOCALE); + typename remove_reference<decltype(errno)>::type __current_errno = errno; if (__current_errno == 0) errno = __save_errno; if (__p2 != __a_end) @@ -851,15 +870,11 @@ __num_get_unsigned_integral(const char* __a, const char* __a_end, __err = ios_base::failbit; return 0; } - int __save_errno = errno; + typename remove_reference<decltype(errno)>::type __save_errno = errno; errno = 0; char *__p2; -#ifdef _LIBCPP_STABLE_APPLE_ABI - unsigned long long __ll = strtoull_l(__a, &__p2, __base, 0); -#else - unsigned long long __ll = strtoull_l(__a, &__p2, __base, __cloc()); -#endif - int __current_errno = errno; + unsigned long long __ll = strtoull_l(__a, &__p2, __base, _LIBCPP_GET_C_LOCALE); + typename remove_reference<decltype(errno)>::type __current_errno = errno; if (__current_errno == 0) errno = __save_errno; if (__p2 != __a_end) @@ -886,11 +901,7 @@ __num_get_float(const char* __a, const char* __a_end, ios_base::iostate& __err) if (__a != __a_end) { char *__p2; -#ifdef _LIBCPP_STABLE_APPLE_ABI - long double __ld = strtold_l(__a, &__p2, 0); -#else - long double __ld = strtold_l(__a, &__p2, __cloc()); -#endif + long double __ld = strtold_l(__a, &__p2, _LIBCPP_GET_C_LOCALE); if (__p2 != __a_end) { __err = ios_base::failbit; @@ -1279,7 +1290,7 @@ num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e, int __base = 16; // Stage 2 char_type __atoms[26]; - char_type __thousands_sep; + char_type __thousands_sep = 0; string __grouping; use_facet<ctype<_CharT> >(__iob.getloc()).widen(__num_get_base::__src, __num_get_base::__src + 26, __atoms); @@ -1295,8 +1306,8 @@ num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e, break; // Stage 3 __a[sizeof(__a)-1] = 0; -#ifdef _LIBCPP_STABLE_APPLE_ABI - if (sscanf_l(__a, 0, "%p", &__v) != 1) +#ifdef _LIBCPP_LOCALE__L_EXTENSIONS + if (sscanf_l(__a, _LIBCPP_GET_C_LOCALE, "%p", &__v) != 1) #else if (__sscanf_l(__a, __cloc(), "%p", &__v) != 1) #endif @@ -1307,8 +1318,8 @@ num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e, return __b; } -extern template class num_get<char>; -extern template class num_get<wchar_t>; +_LIBCPP_EXTERN_TEMPLATE(class num_get<char>) +_LIBCPP_EXTERN_TEMPLATE(class num_get<wchar_t>) struct __num_put_base { @@ -1404,21 +1415,13 @@ __num_put<_CharT>::__widen_and_group_float(char* __nb, char* __np, char* __ne, *__oe++ = __ct.widen(*__nf++); *__oe++ = __ct.widen(*__nf++); for (__ns = __nf; __ns < __ne; ++__ns) -#ifdef _LIBCPP_STABLE_APPLE_ABI - if (!isxdigit_l(*__ns, 0)) -#else - if (!isxdigit_l(*__ns, __cloc())) -#endif + if (!isxdigit_l(*__ns, _LIBCPP_GET_C_LOCALE)) break; } else { for (__ns = __nf; __ns < __ne; ++__ns) -#ifdef _LIBCPP_STABLE_APPLE_ABI - if (!isdigit_l(*__ns, 0)) -#else - if (!isdigit_l(*__ns, __cloc())) -#endif + if (!isdigit_l(*__ns, _LIBCPP_GET_C_LOCALE)) break; } if (__grouping.empty()) @@ -1465,8 +1468,8 @@ __num_put<_CharT>::__widen_and_group_float(char* __nb, char* __np, char* __ne, __op = __ob + (__np - __nb); } -extern template class __num_put<char>; -extern template class __num_put<wchar_t>; +_LIBCPP_EXTERN_TEMPLATE(struct __num_put<char>) +_LIBCPP_EXTERN_TEMPLATE(struct __num_put<wchar_t>) template <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> > class _LIBCPP_VISIBLE num_put @@ -1588,6 +1591,58 @@ __pad_and_output(_OutputIterator __s, return __s; } +#if !defined(__APPLE__) || \ + (defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED > __MAC_10_8) || \ + (defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED > __IPHONE_6_0) + +template <class _CharT, class _Traits> +_LIBCPP_HIDDEN +ostreambuf_iterator<_CharT, _Traits> +__pad_and_output(ostreambuf_iterator<_CharT, _Traits> __s, + const _CharT* __ob, const _CharT* __op, const _CharT* __oe, + ios_base& __iob, _CharT __fl) +{ + if (__s.__sbuf_ == nullptr) + return __s; + streamsize __sz = __oe - __ob; + streamsize __ns = __iob.width(); + if (__ns > __sz) + __ns -= __sz; + else + __ns = 0; + streamsize __np = __op - __ob; + if (__np > 0) + { + if (__s.__sbuf_->sputn(__ob, __np) != __np) + { + __s.__sbuf_ = nullptr; + return __s; + } + } + if (__ns > 0) + { + basic_string<_CharT, _Traits> __sp(__ns, __fl); + if (__s.__sbuf_->sputn(__sp.data(), __ns) != __ns) + { + __s.__sbuf_ = nullptr; + return __s; + } + } + __np = __oe - __op; + if (__np > 0) + { + if (__s.__sbuf_->sputn(__op, __np) != __np) + { + __s.__sbuf_ = nullptr; + return __s; + } + } + __iob.width(0); + return __s; +} + +#endif + template <class _CharT, class _OutputIterator> _OutputIterator num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, @@ -1616,8 +1671,8 @@ num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, + ((numeric_limits<long>::digits % 3) != 0) + 1; char __nar[__nbuf]; -#ifdef _LIBCPP_STABLE_APPLE_ABI - int __nc = sprintf_l(__nar, 0, __fmt, __v); +#ifdef _LIBCPP_LOCALE__L_EXTENSIONS + int __nc = sprintf_l(__nar, _LIBCPP_GET_C_LOCALE, __fmt, __v); #else int __nc = __sprintf_l(__nar, __cloc(), __fmt, __v); #endif @@ -1646,8 +1701,8 @@ num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, + ((numeric_limits<long long>::digits % 3) != 0) + 1; char __nar[__nbuf]; -#ifdef _LIBCPP_STABLE_APPLE_ABI - int __nc = sprintf_l(__nar, 0, __fmt, __v); +#ifdef _LIBCPP_LOCALE__L_EXTENSIONS + int __nc = sprintf_l(__nar, _LIBCPP_GET_C_LOCALE, __fmt, __v); #else int __nc = __sprintf_l(__nar, __cloc(), __fmt, __v); #endif @@ -1676,8 +1731,8 @@ num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, + ((numeric_limits<unsigned long>::digits % 3) != 0) + 1; char __nar[__nbuf]; -#ifdef _LIBCPP_STABLE_APPLE_ABI - int __nc = sprintf_l(__nar, 0, __fmt, __v); +#ifdef _LIBCPP_LOCALE__L_EXTENSIONS + int __nc = sprintf_l(__nar, _LIBCPP_GET_C_LOCALE, __fmt, __v); #else int __nc = __sprintf_l(__nar, __cloc(), __fmt, __v); #endif @@ -1706,8 +1761,8 @@ num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, + ((numeric_limits<unsigned long long>::digits % 3) != 0) + 1; char __nar[__nbuf]; -#ifdef _LIBCPP_STABLE_APPLE_ABI - int __nc = sprintf_l(__nar, 0, __fmt, __v); +#ifdef _LIBCPP_LOCALE__L_EXTENSIONS + int __nc = sprintf_l(__nar, _LIBCPP_GET_C_LOCALE, __fmt, __v); #else int __nc = __sprintf_l(__nar, __cloc(), __fmt, __v); #endif @@ -1737,16 +1792,16 @@ num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, char* __nb = __nar; int __nc; if (__specify_precision) -#ifdef _LIBCPP_STABLE_APPLE_ABI - __nc = snprintf_l(__nb, __nbuf, 0, __fmt, +#ifdef _LIBCPP_LOCALE__L_EXTENSIONS + __nc = snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, (int)__iob.precision(), __v); #else __nc = __snprintf_l(__nb, __nbuf, __cloc(), __fmt, (int)__iob.precision(), __v); #endif else -#ifdef _LIBCPP_STABLE_APPLE_ABI - __nc = snprintf_l(__nb, __nbuf, 0, __fmt, __v); +#ifdef _LIBCPP_LOCALE__L_EXTENSIONS + __nc = snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, __v); #else __nc = __snprintf_l(__nb, __nbuf, __cloc(), __fmt, __v); #endif @@ -1754,15 +1809,15 @@ num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, if (__nc > static_cast<int>(__nbuf-1)) { if (__specify_precision) -#ifdef _LIBCPP_STABLE_APPLE_ABI - __nc = asprintf_l(&__nb, 0, __fmt, (int)__iob.precision(), __v); +#ifdef _LIBCPP_LOCALE__L_EXTENSIONS + __nc = asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, (int)__iob.precision(), __v); #else __nc = __asprintf_l(&__nb, __cloc(), __fmt, (int)__iob.precision(), __v); #endif else -#ifdef _LIBCPP_STABLE_APPLE_ABI - __nc = asprintf_l(&__nb, 0, __fmt, __v); +#ifdef _LIBCPP_LOCALE__L_EXTENSIONS + __nc = asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, __v); #else __nc = __asprintf_l(&__nb, __cloc(), __fmt, (int)__iob.precision(), __v); #endif @@ -1778,7 +1833,7 @@ num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, unique_ptr<char_type, void(*)(void*)> __obh(0, free); if (__nb != __nar) { - __ob = (char_type*)malloc((2*__nc)*sizeof(char_type)); + __ob = (char_type*)malloc(2*static_cast<size_t>(__nc)*sizeof(char_type)); if (__ob == 0) __throw_bad_alloc(); __obh.reset(__ob); @@ -1806,16 +1861,16 @@ num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, char* __nb = __nar; int __nc; if (__specify_precision) -#ifdef _LIBCPP_STABLE_APPLE_ABI - __nc = snprintf_l(__nb, __nbuf, 0, __fmt, +#ifdef _LIBCPP_LOCALE__L_EXTENSIONS + __nc = snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, (int)__iob.precision(), __v); #else __nc = __snprintf_l(__nb, __nbuf, __cloc(), __fmt, (int)__iob.precision(), __v); #endif else -#ifdef _LIBCPP_STABLE_APPLE_ABI - __nc = snprintf_l(__nb, __nbuf, 0, __fmt, __v); +#ifdef _LIBCPP_LOCALE__L_EXTENSIONS + __nc = snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, __v); #else __nc = __snprintf_l(__nb, __nbuf, __cloc(), __fmt, __v); #endif @@ -1823,15 +1878,15 @@ num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, if (__nc > static_cast<int>(__nbuf-1)) { if (__specify_precision) -#ifdef _LIBCPP_STABLE_APPLE_ABI - __nc = asprintf_l(&__nb, 0, __fmt, (int)__iob.precision(), __v); +#ifdef _LIBCPP_LOCALE__L_EXTENSIONS + __nc = asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, (int)__iob.precision(), __v); #else __nc = __asprintf_l(&__nb, __cloc(), __fmt, (int)__iob.precision(), __v); #endif else -#ifdef _LIBCPP_STABLE_APPLE_ABI - __nc = asprintf_l(&__nb, 0, __fmt, __v); +#ifdef _LIBCPP_LOCALE__L_EXTENSIONS + __nc = asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, __v); #else __nc = __asprintf_l(&__nb, __cloc(), __fmt, __v); #endif @@ -1847,7 +1902,7 @@ num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, unique_ptr<char_type, void(*)(void*)> __obh(0, free); if (__nb != __nar) { - __ob = (char_type*)malloc((2*__nc)*sizeof(char_type)); + __ob = (char_type*)malloc(2*static_cast<size_t>(__nc)*sizeof(char_type)); if (__ob == 0) __throw_bad_alloc(); __obh.reset(__ob); @@ -1870,8 +1925,8 @@ num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, char __fmt[6] = "%p"; const unsigned __nbuf = 20; char __nar[__nbuf]; -#ifdef _LIBCPP_STABLE_APPLE_ABI - int __nc = sprintf_l(__nar, 0, __fmt, __v); +#ifdef _LIBCPP_LOCALE__L_EXTENSIONS + int __nc = sprintf_l(__nar, _LIBCPP_GET_C_LOCALE, __fmt, __v); #else int __nc = __sprintf_l(__nar, __cloc(), __fmt, __v); #endif @@ -1893,8 +1948,8 @@ num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, return __pad_and_output(__s, __o, __op, __oe, __iob, __fl); } -extern template class num_put<char>; -extern template class num_put<wchar_t>; +_LIBCPP_EXTERN_TEMPLATE(class num_put<char>) +_LIBCPP_EXTERN_TEMPLATE(class num_put<wchar_t>) template <class _CharT, class _InputIterator> _LIBCPP_HIDDEN @@ -2114,7 +2169,7 @@ time_get<_CharT, _InputIterator>::__get_weekdayname(int& __w, { // Note: ignoring case comes from the POSIX strptime spec const string_type* __wk = this->__weeks(); - int __i = __scan_keyword(__b, __e, __wk, __wk+14, __ct, __err, false) - __wk; + ptrdiff_t __i = __scan_keyword(__b, __e, __wk, __wk+14, __ct, __err, false) - __wk; if (__i < 14) __w = __i % 7; } @@ -2128,7 +2183,7 @@ time_get<_CharT, _InputIterator>::__get_monthname(int& __m, { // Note: ignoring case comes from the POSIX strptime spec const string_type* __month = this->__months(); - int __i = __scan_keyword(__b, __e, __month, __month+24, __ct, __err, false) - __month; + ptrdiff_t __i = __scan_keyword(__b, __e, __month, __month+24, __ct, __err, false) - __month; if (__i < 24) __m = __i % 12; } @@ -2300,7 +2355,7 @@ time_get<_CharT, _InputIterator>::__get_am_pm(int& __h, __err |= ios_base::failbit; return; } - int __i = __scan_keyword(__b, __e, __ap, __ap+2, __ct, __err, false) - __ap; + ptrdiff_t __i = __scan_keyword(__b, __e, __ap, __ap+2, __ct, __err, false) - __ap; if (__i == 0 && __h == 12) __h = 0; else if (__i == 1 && __h < 12) @@ -2409,7 +2464,6 @@ time_get<_CharT, _InputIterator>::do_get_date(iter_type __b, iter_type __e, ios_base::iostate& __err, tm* __tm) const { - const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc()); const string_type& __fmt = this->__x(); return get(__b, __e, __iob, __err, __tm, __fmt.data(), __fmt.data() + __fmt.size()); } @@ -2472,8 +2526,8 @@ time_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e, break; case 'c': { - const string_type& __fmt = this->__c(); - __b = get(__b, __e, __iob, __err, __tm, __fmt.data(), __fmt.data() + __fmt.size()); + const string_type& __fm = this->__c(); + __b = get(__b, __e, __iob, __err, __tm, __fm.data(), __fm.data() + __fm.size()); } break; case 'd': @@ -2482,14 +2536,14 @@ time_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e, break; case 'D': { - const char_type __fmt[] = {'%', 'm', '/', '%', 'd', '/', '%', 'y'}; - __b = get(__b, __e, __iob, __err, __tm, __fmt, __fmt + sizeof(__fmt)/sizeof(__fmt[0])); + const char_type __fm[] = {'%', 'm', '/', '%', 'd', '/', '%', 'y'}; + __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0])); } break; case 'F': { - const char_type __fmt[] = {'%', 'Y', '-', '%', 'm', '-', '%', 'd'}; - __b = get(__b, __e, __iob, __err, __tm, __fmt, __fmt + sizeof(__fmt)/sizeof(__fmt[0])); + const char_type __fm[] = {'%', 'Y', '-', '%', 'm', '-', '%', 'd'}; + __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0])); } break; case 'H': @@ -2516,14 +2570,14 @@ time_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e, break; case 'r': { - const char_type __fmt[] = {'%', 'I', ':', '%', 'M', ':', '%', 'S', ' ', '%', 'p'}; - __b = get(__b, __e, __iob, __err, __tm, __fmt, __fmt + sizeof(__fmt)/sizeof(__fmt[0])); + const char_type __fm[] = {'%', 'I', ':', '%', 'M', ':', '%', 'S', ' ', '%', 'p'}; + __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0])); } break; case 'R': { - const char_type __fmt[] = {'%', 'H', ':', '%', 'M'}; - __b = get(__b, __e, __iob, __err, __tm, __fmt, __fmt + sizeof(__fmt)/sizeof(__fmt[0])); + const char_type __fm[] = {'%', 'H', ':', '%', 'M'}; + __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0])); } break; case 'S': @@ -2531,8 +2585,8 @@ time_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e, break; case 'T': { - const char_type __fmt[] = {'%', 'H', ':', '%', 'M', ':', '%', 'S'}; - __b = get(__b, __e, __iob, __err, __tm, __fmt, __fmt + sizeof(__fmt)/sizeof(__fmt[0])); + const char_type __fm[] = {'%', 'H', ':', '%', 'M', ':', '%', 'S'}; + __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0])); } break; case 'w': @@ -2542,8 +2596,8 @@ time_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e, return do_get_date(__b, __e, __iob, __err, __tm); case 'X': { - const string_type& __fmt = this->__X(); - __b = get(__b, __e, __iob, __err, __tm, __fmt.data(), __fmt.data() + __fmt.size()); + const string_type& __fm = this->__X(); + __b = get(__b, __e, __iob, __err, __tm, __fm.data(), __fm.data() + __fm.size()); } break; case 'y': @@ -2561,8 +2615,8 @@ time_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e, return __b; } -extern template class time_get<char>; -extern template class time_get<wchar_t>; +_LIBCPP_EXTERN_TEMPLATE(class time_get<char>) +_LIBCPP_EXTERN_TEMPLATE(class time_get<wchar_t>) class __time_get { @@ -2644,18 +2698,14 @@ private: virtual const string_type& __X() const {return this->__X_;} }; -extern template class time_get_byname<char>; -extern template class time_get_byname<wchar_t>; +_LIBCPP_EXTERN_TEMPLATE(class time_get_byname<char>) +_LIBCPP_EXTERN_TEMPLATE(class time_get_byname<wchar_t>) class __time_put { locale_t __loc_; protected: -#ifdef _LIBCPP_STABLE_APPLE_ABI - _LIBCPP_ALWAYS_INLINE __time_put() : __loc_(0) {} -#else // _LIBCPP_STABLE_APPLE_ABI - _LIBCPP_ALWAYS_INLINE __time_put() : __loc_(__cloc()) {} -#endif // _LIBCPP_STABLE_APPLE_ABI + _LIBCPP_ALWAYS_INLINE __time_put() : __loc_(_LIBCPP_GET_C_LOCALE) {} __time_put(const char* __nm); __time_put(const string& __nm); ~__time_put(); @@ -2750,7 +2800,7 @@ time_put<_CharT, _OutputIterator>::put(iter_type __s, ios_base& __iob, template <class _CharT, class _OutputIterator> _OutputIterator -time_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, +time_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base&, char_type, const tm* __tm, char __fmt, char __mod) const { @@ -2761,8 +2811,8 @@ time_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, return _VSTD::copy(__nb, __ne, __s); } -extern template class time_put<char>; -extern template class time_put<wchar_t>; +_LIBCPP_EXTERN_TEMPLATE(class time_put<char>) +_LIBCPP_EXTERN_TEMPLATE(class time_put<wchar_t>) template <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> > class _LIBCPP_VISIBLE time_put_byname @@ -2782,8 +2832,8 @@ protected: ~time_put_byname() {} }; -extern template class time_put_byname<char>; -extern template class time_put_byname<wchar_t>; +_LIBCPP_EXTERN_TEMPLATE(class time_put_byname<char>) +_LIBCPP_EXTERN_TEMPLATE(class time_put_byname<wchar_t>) // money_base @@ -2836,19 +2886,23 @@ protected: virtual string_type do_negative_sign() const {return string_type(1, '-');} virtual int do_frac_digits() const {return 0;} virtual pattern do_pos_format() const - {pattern __p = {symbol, sign, none, value}; return __p;} + {pattern __p = {{symbol, sign, none, value}}; return __p;} virtual pattern do_neg_format() const - {pattern __p = {symbol, sign, none, value}; return __p;} + {pattern __p = {{symbol, sign, none, value}}; return __p;} }; template <class _CharT, bool _International> locale::id moneypunct<_CharT, _International>::id; -extern template class moneypunct<char, false>; -extern template class moneypunct<char, true>; -extern template class moneypunct<wchar_t, false>; -extern template class moneypunct<wchar_t, true>; +template <class _CharT, bool _International> +const bool +moneypunct<_CharT, _International>::intl; + +_LIBCPP_EXTERN_TEMPLATE(class moneypunct<char, false>) +_LIBCPP_EXTERN_TEMPLATE(class moneypunct<char, true>) +_LIBCPP_EXTERN_TEMPLATE(class moneypunct<wchar_t, false>) +_LIBCPP_EXTERN_TEMPLATE(class moneypunct<wchar_t, true>) // moneypunct_byname @@ -2902,10 +2956,10 @@ template<> void moneypunct_byname<char, true>::init(const char*); template<> void moneypunct_byname<wchar_t, false>::init(const char*); template<> void moneypunct_byname<wchar_t, true>::init(const char*); -extern template class moneypunct_byname<char, false>; -extern template class moneypunct_byname<char, true>; -extern template class moneypunct_byname<wchar_t, false>; -extern template class moneypunct_byname<wchar_t, true>; +_LIBCPP_EXTERN_TEMPLATE(class moneypunct_byname<char, false>) +_LIBCPP_EXTERN_TEMPLATE(class moneypunct_byname<char, true>) +_LIBCPP_EXTERN_TEMPLATE(class moneypunct_byname<wchar_t, false>) +_LIBCPP_EXTERN_TEMPLATE(class moneypunct_byname<wchar_t, true>) // money_get @@ -2961,8 +3015,8 @@ __money_get<_CharT>::__gather_info(bool __intl, const locale& __loc, } } -extern template class __money_get<char>; -extern template class __money_get<wchar_t>; +_LIBCPP_EXTERN_TEMPLATE(class __money_get<char>) +_LIBCPP_EXTERN_TEMPLATE(class __money_get<wchar_t>) template <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> > class _LIBCPP_VISIBLE money_get @@ -3027,10 +3081,10 @@ void __double_or_nothing(unique_ptr<_Tp, void(*)(void*)>& __b, _Tp*& __n, _Tp*& __e) { bool __owns = __b.get_deleter() != __do_nothing; - size_t __cur_cap = (__e-__b.get()) * sizeof(_Tp); + size_t __cur_cap = static_cast<size_t>(__e-__b.get()) * sizeof(_Tp); size_t __new_cap = __cur_cap < numeric_limits<size_t>::max() / 2 ? 2 * __cur_cap : numeric_limits<size_t>::max(); - size_t __n_off = __n - __b.get(); + size_t __n_off = static_cast<size_t>(__n - __b.get()); _Tp* __t = (_Tp*)realloc(__owns ? __b.get() : 0, __new_cap); if (__t == 0) __throw_bad_alloc(); @@ -3066,6 +3120,9 @@ money_get<_CharT, _InputIterator>::__do_get(iter_type& __b, iter_type __e, string_type __sym; string_type __psn; string_type __nsn; + // Capture the spaces read into money_base::{space,none} so they + // can be compared to initial spaces in __sym. + string_type __spaces; int __fd; __money_get<_CharT>::__gather_info(__intl, __loc, __pat, __dp, __ts, __grp, __sym, __psn, __nsn, __fd); @@ -3079,7 +3136,7 @@ money_get<_CharT, _InputIterator>::__do_get(iter_type& __b, iter_type __e, if (__p != 3) { if (__ct.is(ctype_base::space, *__b)) - ++__b; + __spaces.push_back(*__b++); else { __err |= ios_base::failbit; @@ -3091,7 +3148,7 @@ money_get<_CharT, _InputIterator>::__do_get(iter_type& __b, iter_type __e, if (__p != 3) { while (__b != __e && __ct.is(ctype_base::space, *__b)) - ++__b; + __spaces.push_back(*__b++); } break; case money_base::sign: @@ -3149,10 +3206,31 @@ money_get<_CharT, _InputIterator>::__do_get(iter_type& __b, iter_type __e, bool __sb = __flags & ios_base::showbase; if (__sb || __more_needed) { - ios_base::iostate __et = ios_base::goodbit; - string_type* __k = __scan_keyword(__b, __e, &__sym, &__sym+1, - __ct, __et); - if (__sb && __k != &__sym) + typename string_type::const_iterator __sym_space_end = __sym.begin(); + if (__p > 0 && (__pat.field[__p - 1] == money_base::none || + __pat.field[__p - 1] == money_base::space)) { + // Match spaces we've already read against spaces at + // the beginning of __sym. + while (__sym_space_end != __sym.end() && + __ct.is(ctype_base::space, *__sym_space_end)) + ++__sym_space_end; + const size_t __num_spaces = __sym_space_end - __sym.begin(); + if (__num_spaces > __spaces.size() || + !equal(__spaces.end() - __num_spaces, __spaces.end(), + __sym.begin())) { + // No match. Put __sym_space_end back at the + // beginning of __sym, which will prevent a + // match in the next loop. + __sym_space_end = __sym.begin(); + } + } + typename string_type::const_iterator __sym_curr_char = __sym_space_end; + while (__sym_curr_char != __sym.end() && __b != __e && + *__b == *__sym_curr_char) { + ++__b; + ++__sym_curr_char; + } + if (__sb && __sym_curr_char != __sym.end()) { __err |= ios_base::failbit; return false; @@ -3248,7 +3326,7 @@ money_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e, ios_base::iostate& __err, long double& __v) const { - const unsigned __bz = 100; + const int __bz = 100; char_type __wbuf[__bz]; unique_ptr<char_type, void(*)(void*)> __wb(__wbuf, __do_nothing); char_type* __wn; @@ -3267,7 +3345,7 @@ money_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e, unique_ptr<char, void(*)(void*)> __h(0, free); if (__wn - __wb.get() > __bz-2) { - __h.reset((char*)malloc(__wn - __wb.get() + 2)); + __h.reset((char*)malloc(static_cast<size_t>(__wn - __wb.get() + 2))); if (__h.get() == 0) __throw_bad_alloc(); __nc = __h.get(); @@ -3292,7 +3370,7 @@ money_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e, ios_base::iostate& __err, string_type& __v) const { - const unsigned __bz = 100; + const int __bz = 100; char_type __wbuf[__bz]; unique_ptr<char_type, void(*)(void*)> __wb(__wbuf, __do_nothing); char_type* __wn; @@ -3318,8 +3396,8 @@ money_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e, return __b; } -extern template class money_get<char>; -extern template class money_get<wchar_t>; +_LIBCPP_EXTERN_TEMPLATE(class money_get<char>) +_LIBCPP_EXTERN_TEMPLATE(class money_get<wchar_t>) // money_put @@ -3493,8 +3571,8 @@ __money_put<_CharT>::__format(char_type* __mb, char_type*& __mi, char_type*& __m __mi = __mb; } -extern template class __money_put<char>; -extern template class __money_put<wchar_t>; +_LIBCPP_EXTERN_TEMPLATE(class __money_put<char>) +_LIBCPP_EXTERN_TEMPLATE(class __money_put<wchar_t>) template <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> > class _LIBCPP_VISIBLE money_put @@ -3552,14 +3630,14 @@ money_put<_CharT, _OutputIterator>::do_put(iter_type __s, bool __intl, char* __bb = __buf; char_type __digits[__bs]; char_type* __db = __digits; - size_t __n = snprintf(__bb, __bs, "%.0Lf", __units); + size_t __n = static_cast<size_t>(snprintf(__bb, __bs, "%.0Lf", __units)); unique_ptr<char, void(*)(void*)> __hn(0, free); unique_ptr<char_type, void(*)(void*)> __hd(0, free); // secure memory for digit storage if (__n > __bs-1) { -#ifdef _LIBCPP_STABLE_APPLE_ABI - __n = asprintf_l(&__bb, 0, "%.0Lf", __units); +#ifdef _LIBCPP_LOCALE__L_EXTENSIONS + __n = static_cast<size_t>(asprintf_l(&__bb, _LIBCPP_GET_C_LOCALE, "%.0Lf", __units)); #else __n = __asprintf_l(&__bb, __cloc(), "%.0Lf", __units); #endif @@ -3567,7 +3645,7 @@ money_put<_CharT, _OutputIterator>::do_put(iter_type __s, bool __intl, __throw_bad_alloc(); __hn.reset(__bb); __hd.reset((char_type*)malloc(__n * sizeof(char_type))); - if (__hd == 0) + if (__hd == nullptr) __throw_bad_alloc(); __db = __hd.get(); } @@ -3589,8 +3667,9 @@ money_put<_CharT, _OutputIterator>::do_put(iter_type __s, bool __intl, char_type* __mb = __mbuf; unique_ptr<char_type, void(*)(void*)> __hw(0, free); size_t __exn = static_cast<int>(__n) > __fd ? - (__n - __fd) * 2 + __sn.size() + __sym.size() + __fd + 1 - : __sn.size() + __sym.size() + __fd + 2; + (__n - static_cast<size_t>(__fd)) * 2 + __sn.size() + + __sym.size() + static_cast<size_t>(__fd) + 1 + : __sn.size() + __sym.size() + static_cast<size_t>(__fd) + 2; if (__exn > __bs) { __hw.reset((char_type*)malloc(__exn * sizeof(char_type))); @@ -3629,9 +3708,10 @@ money_put<_CharT, _OutputIterator>::do_put(iter_type __s, bool __intl, char_type __mbuf[100]; char_type* __mb = __mbuf; unique_ptr<char_type, void(*)(void*)> __h(0, free); - size_t __exn = __digits.size() > __fd ? - (__digits.size() - __fd) * 2 + __sn.size() + __sym.size() + __fd + 1 - : __sn.size() + __sym.size() + __fd + 2; + size_t __exn = static_cast<int>(__digits.size()) > __fd ? + (__digits.size() - static_cast<size_t>(__fd)) * 2 + + __sn.size() + __sym.size() + static_cast<size_t>(__fd) + 1 + : __sn.size() + __sym.size() + static_cast<size_t>(__fd) + 2; if (__exn > 100) { __h.reset((char_type*)malloc(__exn * sizeof(char_type))); @@ -3648,8 +3728,8 @@ money_put<_CharT, _OutputIterator>::do_put(iter_type __s, bool __intl, return __pad_and_output(__s, __mb, __mi, __me, __iob, __fl); } -extern template class money_put<char>; -extern template class money_put<wchar_t>; +_LIBCPP_EXTERN_TEMPLATE(class money_put<char>) +_LIBCPP_EXTERN_TEMPLATE(class money_put<wchar_t>) // messages @@ -3716,7 +3796,7 @@ messages<_CharT>::do_open(const basic_string<char>& __nm, const locale&) const #if _WIN32 return -1; #else // _WIN32 - catalog __cat = reinterpret_cast<catalog>(catopen(__nm.c_str(), NL_CAT_LOCALE)); + catalog __cat = (catalog)catopen(__nm.c_str(), NL_CAT_LOCALE); if (__cat != -1) __cat = static_cast<catalog>((static_cast<size_t>(__cat) >> 1)); return __cat; @@ -3737,7 +3817,7 @@ messages<_CharT>::do_get(catalog __c |