| From c6092cc576174fcbd433f3b34288255ef30f6510 Mon Sep 17 00:00:00 2001 |
| From: Andrew Hsieh <andrewhsieh@google.com> |
| Date: Wed, 12 Feb 2014 20:07:01 +0800 |
| Subject: [PATCH 03/12] Fallback to locale("C") |
| |
| Android's newlocale() return null for anything other than "", "C", |
| and "POSIX", fallback to "C" to allow more tests to run and uncover |
| other issues. |
| --- |
| src/locale.cpp | 124 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--- |
| 1 file changed, 118 insertions(+), 6 deletions(-) |
| |
| diff --git a/src/locale.cpp b/src/locale.cpp |
| index 66aaca9..0fba54d 100644 |
| --- a/src/locale.cpp |
| +++ b/src/locale.cpp |
| @@ -54,6 +54,10 @@ locale_t __cloc() { |
| } |
| #endif // __cloc_defined |
| |
| +inline locale_t __new_cloc() { |
| + return newlocale(LC_ALL_MASK, "C", 0); |
| +} |
| + |
| namespace { |
| |
| struct release |
| @@ -657,8 +661,14 @@ collate_byname<char>::collate_byname(const char* n, size_t refs) |
| { |
| #ifndef _LIBCPP_NO_EXCEPTIONS |
| if (__l == 0) |
| + { |
| +#if !defined(__ANDROID__) |
| throw runtime_error("collate_byname<char>::collate_byname" |
| " failed to construct for " + string(n)); |
| +#else |
| + __l = __new_cloc(); |
| +#endif |
| + } |
| #endif // _LIBCPP_NO_EXCEPTIONS |
| } |
| |
| @@ -668,8 +678,14 @@ collate_byname<char>::collate_byname(const string& name, size_t refs) |
| { |
| #ifndef _LIBCPP_NO_EXCEPTIONS |
| if (__l == 0) |
| + { |
| +#if !defined(__ANDROID__) |
| throw runtime_error("collate_byname<char>::collate_byname" |
| " failed to construct for " + name); |
| +#else |
| + __l = __new_cloc(); |
| +#endif |
| + } |
| #endif // _LIBCPP_NO_EXCEPTIONS |
| } |
| |
| @@ -709,8 +725,14 @@ collate_byname<wchar_t>::collate_byname(const char* n, size_t refs) |
| { |
| #ifndef _LIBCPP_NO_EXCEPTIONS |
| if (__l == 0) |
| + { |
| +#if !defined(__ANDROID__) |
| throw runtime_error("collate_byname<wchar_t>::collate_byname(size_t refs)" |
| " failed to construct for " + string(n)); |
| +#else |
| + __l = __new_cloc(); |
| +#endif |
| + } |
| #endif // _LIBCPP_NO_EXCEPTIONS |
| } |
| |
| @@ -720,8 +742,14 @@ collate_byname<wchar_t>::collate_byname(const string& name, size_t refs) |
| { |
| #ifndef _LIBCPP_NO_EXCEPTIONS |
| if (__l == 0) |
| + { |
| +#if !defined(__ANDROID__) |
| throw runtime_error("collate_byname<wchar_t>::collate_byname(size_t refs)" |
| " failed to construct for " + name); |
| +#else |
| + __l = __new_cloc(); |
| +#endif |
| + } |
| #endif // _LIBCPP_NO_EXCEPTIONS |
| } |
| |
| @@ -1117,8 +1145,14 @@ ctype_byname<char>::ctype_byname(const char* name, size_t refs) |
| { |
| #ifndef _LIBCPP_NO_EXCEPTIONS |
| if (__l == 0) |
| + { |
| +#if !defined(__ANDROID__) |
| throw runtime_error("ctype_byname<char>::ctype_byname" |
| " failed to construct for " + string(name)); |
| +#else |
| + __l = __new_cloc(); |
| +#endif |
| + } |
| #endif // _LIBCPP_NO_EXCEPTIONS |
| } |
| |
| @@ -1128,8 +1162,14 @@ ctype_byname<char>::ctype_byname(const string& name, size_t refs) |
| { |
| #ifndef _LIBCPP_NO_EXCEPTIONS |
| if (__l == 0) |
| + { |
| +#if !defined(__ANDROID__) |
| throw runtime_error("ctype_byname<char>::ctype_byname" |
| " failed to construct for " + name); |
| +#else |
| + __l = __new_cloc(); |
| +#endif |
| + } |
| #endif // _LIBCPP_NO_EXCEPTIONS |
| } |
| |
| @@ -1174,8 +1214,14 @@ ctype_byname<wchar_t>::ctype_byname(const char* name, size_t refs) |
| { |
| #ifndef _LIBCPP_NO_EXCEPTIONS |
| if (__l == 0) |
| + { |
| +#if !defined(__ANDROID__) |
| throw runtime_error("ctype_byname<wchar_t>::ctype_byname" |
| " failed to construct for " + string(name)); |
| +#else |
| + __l = __new_cloc(); |
| +#endif |
| + } |
| #endif // _LIBCPP_NO_EXCEPTIONS |
| } |
| |
| @@ -1185,8 +1231,14 @@ ctype_byname<wchar_t>::ctype_byname(const string& name, size_t refs) |
| { |
| #ifndef _LIBCPP_NO_EXCEPTIONS |
| if (__l == 0) |
| + { |
| +#if !defined(__ANDROID__) |
| throw runtime_error("ctype_byname<wchar_t>::ctype_byname" |
| " failed to construct for " + name); |
| +#else |
| + __l = __new_cloc(); |
| +#endif |
| + } |
| #endif // _LIBCPP_NO_EXCEPTIONS |
| } |
| |
| @@ -1455,8 +1507,14 @@ codecvt<wchar_t, char, mbstate_t>::codecvt(const char* nm, size_t refs) |
| { |
| #ifndef _LIBCPP_NO_EXCEPTIONS |
| if (__l == 0) |
| + { |
| +#if !defined(__ANDROID__) |
| throw runtime_error("codecvt_byname<wchar_t, char, mbstate_t>::codecvt_byname" |
| " failed to construct for " + string(nm)); |
| +#else |
| + __l = __new_cloc(); |
| +#endif |
| + } |
| #endif // _LIBCPP_NO_EXCEPTIONS |
| } |
| |
| @@ -4250,7 +4308,12 @@ numpunct_byname<char>::__init(const char* nm) |
| { |
| if (strcmp(nm, "C") != 0) |
| { |
| - __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale); |
| + locale_t l = newlocale(LC_ALL_MASK, nm, 0); |
| +#if defined(__ANDROID__) |
| + if (l == 0) |
| + l = __new_cloc(); |
| +#endif |
| + __locale_unique_ptr loc(l, freelocale); |
| #ifndef _LIBCPP_NO_EXCEPTIONS |
| if (loc == nullptr) |
| throw runtime_error("numpunct_byname<char>::numpunct_byname" |
| @@ -4293,7 +4356,12 @@ numpunct_byname<wchar_t>::__init(const char* nm) |
| { |
| if (strcmp(nm, "C") != 0) |
| { |
| - __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale); |
| + locale_t l = newlocale(LC_ALL_MASK, nm, 0); |
| +#if defined(__ANDROID__) |
| + if (l == 0) |
| + l = __new_cloc(); |
| +#endif |
| + __locale_unique_ptr loc(l, freelocale); |
| #ifndef _LIBCPP_NO_EXCEPTIONS |
| if (loc == nullptr) |
| throw runtime_error("numpunct_byname<char>::numpunct_byname" |
| @@ -4707,8 +4775,14 @@ __time_get::__time_get(const char* nm) |
| { |
| #ifndef _LIBCPP_NO_EXCEPTIONS |
| if (__loc_ == 0) |
| + { |
| +#if !defined(__ANDROID__) |
| throw runtime_error("time_get_byname" |
| " failed to construct for " + string(nm)); |
| +#else |
| + __loc_ = __new_cloc(); |
| +#endif |
| + } |
| #endif // _LIBCPP_NO_EXCEPTIONS |
| } |
| |
| @@ -4717,8 +4791,14 @@ __time_get::__time_get(const string& nm) |
| { |
| #ifndef _LIBCPP_NO_EXCEPTIONS |
| if (__loc_ == 0) |
| + { |
| +# if !defined(__ANDROID__) |
| throw runtime_error("time_get_byname" |
| " failed to construct for " + nm); |
| +#else |
| + __loc_ = __new_cloc(); |
| +#endif |
| + } |
| #endif // _LIBCPP_NO_EXCEPTIONS |
| } |
| |
| @@ -5395,8 +5475,14 @@ __time_put::__time_put(const char* nm) |
| { |
| #ifndef _LIBCPP_NO_EXCEPTIONS |
| if (__loc_ == 0) |
| + { |
| +# if !defined(__ANDROID__) |
| throw runtime_error("time_put_byname" |
| " failed to construct for " + string(nm)); |
| +#else |
| + __loc_ = __new_cloc(); |
| +#endif |
| + } |
| #endif // _LIBCPP_NO_EXCEPTIONS |
| } |
| |
| @@ -5405,8 +5491,14 @@ __time_put::__time_put(const string& nm) |
| { |
| #ifndef _LIBCPP_NO_EXCEPTIONS |
| if (__loc_ == 0) |
| + { |
| +# if !defined(__ANDROID__) |
| throw runtime_error("time_put_byname" |
| " failed to construct for " + nm); |
| +#else |
| + __loc_ = __new_cloc(); |
| +#endif |
| + } |
| #endif // _LIBCPP_NO_EXCEPTIONS |
| } |
| |
| @@ -5825,7 +5917,12 @@ void |
| moneypunct_byname<char, false>::init(const char* nm) |
| { |
| typedef moneypunct<char, false> base; |
| - __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale); |
| + locale_t l = newlocale(LC_ALL_MASK, nm, 0); |
| +#if defined(__ANDROID__) |
| + if (l == 0) |
| + l = __new_cloc(); |
| +#endif |
| + __locale_unique_ptr loc(l, freelocale); |
| #ifndef _LIBCPP_NO_EXCEPTIONS |
| if (loc == nullptr) |
| throw runtime_error("moneypunct_byname" |
| @@ -5873,7 +5970,12 @@ void |
| moneypunct_byname<char, true>::init(const char* nm) |
| { |
| typedef moneypunct<char, true> base; |
| - __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale); |
| + locale_t l = newlocale(LC_ALL_MASK, nm, 0); |
| +#if defined(__ANDROID__) |
| + if (l == 0) |
| + l = __new_cloc(); |
| +#endif |
| + __locale_unique_ptr loc(l, freelocale); |
| #ifndef _LIBCPP_NO_EXCEPTIONS |
| if (loc == nullptr) |
| throw runtime_error("moneypunct_byname" |
| @@ -5938,7 +6040,12 @@ void |
| moneypunct_byname<wchar_t, false>::init(const char* nm) |
| { |
| typedef moneypunct<wchar_t, false> base; |
| - __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale); |
| + locale_t l = newlocale(LC_ALL_MASK, nm, 0); |
| +#if defined(__ANDROID__) |
| + if (l == 0) |
| + l = __new_cloc(); |
| +#endif |
| + __locale_unique_ptr loc(l, freelocale); |
| #ifndef _LIBCPP_NO_EXCEPTIONS |
| if (loc == nullptr) |
| throw runtime_error("moneypunct_byname" |
| @@ -6021,7 +6128,12 @@ void |
| moneypunct_byname<wchar_t, true>::init(const char* nm) |
| { |
| typedef moneypunct<wchar_t, true> base; |
| - __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale); |
| + locale_t l = newlocale(LC_ALL_MASK, nm, 0); |
| +#if defined(__ANDROID__) |
| + if (l == 0) |
| + l = __new_cloc(); |
| +#endif |
| + __locale_unique_ptr loc(l, freelocale); |
| #ifndef _LIBCPP_NO_EXCEPTIONS |
| if (loc == nullptr) |
| throw runtime_error("moneypunct_byname" |
| -- |
| 1.9.1.423.g4596e3a |
| |