summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libcxx/include/support/win32/locale_win32.h73
-rw-r--r--libcxx/src/support/win32/locale_win32.cpp8
2 files changed, 74 insertions, 7 deletions
diff --git a/libcxx/include/support/win32/locale_win32.h b/libcxx/include/support/win32/locale_win32.h
index 9c73f20a09f..8d7779e0cca 100644
--- a/libcxx/include/support/win32/locale_win32.h
+++ b/libcxx/include/support/win32/locale_win32.h
@@ -28,14 +28,72 @@
| LC_NUMERIC_MASK \
| LC_TIME_MASK )
+class __lconv_storage {
+public:
+ __lconv_storage(const lconv *__lc_input) {
+ __lc = *__lc_input;
+
+ __decimal_point = __lc_input->decimal_point;
+ __thousands_sep = __lc_input->thousands_sep;
+ __grouping = __lc_input->grouping;
+ __int_curr_symbol = __lc_input->int_curr_symbol;
+ __currency_symbol = __lc_input->currency_symbol;
+ __mon_decimal_point = __lc_input->mon_decimal_point;
+ __mon_thousands_sep = __lc_input->mon_thousands_sep;
+ __mon_grouping = __lc_input->mon_grouping;
+ __positive_sign = __lc_input->positive_sign;
+ __negative_sign = __lc_input->negative_sign;
+
+ __lc.decimal_point = const_cast<char *>(__decimal_point.c_str());
+ __lc.thousands_sep = const_cast<char *>(__thousands_sep.c_str());
+ __lc.grouping = const_cast<char *>(__grouping.c_str());
+ __lc.int_curr_symbol = const_cast<char *>(__int_curr_symbol.c_str());
+ __lc.currency_symbol = const_cast<char *>(__currency_symbol.c_str());
+ __lc.mon_decimal_point = const_cast<char *>(__mon_decimal_point.c_str());
+ __lc.mon_thousands_sep = const_cast<char *>(__mon_thousands_sep.c_str());
+ __lc.mon_grouping = const_cast<char *>(__mon_grouping.c_str());
+ __lc.positive_sign = const_cast<char *>(__positive_sign.c_str());
+ __lc.negative_sign = const_cast<char *>(__negative_sign.c_str());
+ }
+
+ lconv *__get() {
+ return &__lc;
+ }
+private:
+ lconv __lc;
+ std::string __decimal_point;
+ std::string __thousands_sep;
+ std::string __grouping;
+ std::string __int_curr_symbol;
+ std::string __currency_symbol;
+ std::string __mon_decimal_point;
+ std::string __mon_thousands_sep;
+ std::string __mon_grouping;
+ std::string __positive_sign;
+ std::string __negative_sign;
+};
+
class locale_t {
public:
locale_t()
- : __locale(nullptr), __locale_str(nullptr) {}
+ : __locale(nullptr), __locale_str(nullptr), __lc(nullptr) {}
locale_t(std::nullptr_t)
- : __locale(nullptr), __locale_str(nullptr) {}
+ : __locale(nullptr), __locale_str(nullptr), __lc(nullptr) {}
locale_t(_locale_t __xlocale, const char* __xlocale_str)
- : __locale(__xlocale), __locale_str(__xlocale_str) {}
+ : __locale(__xlocale), __locale_str(__xlocale_str), __lc(nullptr) {}
+ locale_t(const locale_t &__l)
+ : __locale(__l.__locale), __locale_str(__l.__locale_str), __lc(nullptr) {}
+
+ ~locale_t() {
+ delete __lc;
+ }
+
+ locale_t &operator =(const locale_t &__l) {
+ __locale = __l.__locale;
+ __locale_str = __l.__locale_str;
+ // __lc not copied
+ return *this;
+ }
friend bool operator==(const locale_t& __left, const locale_t& __right) {
return __left.__locale == __right.__locale;
@@ -94,9 +152,16 @@ public:
operator _locale_t() const {
return __locale;
}
+
+ lconv *__store_lconv(const lconv *__input_lc) {
+ delete __lc;
+ __lc = new __lconv_storage(__input_lc);
+ return __lc->__get();
+ }
private:
_locale_t __locale;
const char* __locale_str;
+ __lconv_storage *__lc = nullptr;
};
// Locale management functions
@@ -109,7 +174,7 @@ locale_t newlocale( int mask, const char * locale, locale_t base );
// We can still implement raii even without uselocale though.
-lconv *localeconv_l( locale_t loc );
+lconv *localeconv_l( locale_t &loc );
size_t mbrlen_l( const char *__restrict s, size_t n,
mbstate_t *__restrict ps, locale_t loc);
size_t mbsrtowcs_l( wchar_t *__restrict dst, const char **__restrict src,
diff --git a/libcxx/src/support/win32/locale_win32.cpp b/libcxx/src/support/win32/locale_win32.cpp
index a64788685c2..b7062db352a 100644
--- a/libcxx/src/support/win32/locale_win32.cpp
+++ b/libcxx/src/support/win32/locale_win32.cpp
@@ -32,11 +32,13 @@ decltype(MB_CUR_MAX) MB_CUR_MAX_L( locale_t __l )
#endif
}
-
-lconv *localeconv_l( locale_t loc )
+lconv *localeconv_l( locale_t &loc )
{
__libcpp_locale_guard __current(loc);
- return localeconv();
+ lconv *lc = localeconv();
+ if (!lc)
+ return lc;
+ return loc.__store_lconv(lc);
}
size_t mbrlen_l( const char *__restrict s, size_t n,
mbstate_t *__restrict ps, locale_t loc )
OpenPOWER on IntegriCloud