Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 35 additions & 16 deletions stl/inc/xlocinfo
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,28 @@ private:
void* _Timeptr; // pointer to time information
};

template <class _Elem>
_Elem* _Ntcts_dup_dbg(const _Elem* const _Ptr) noexcept {
_STL_INTERNAL_STATIC_ASSERT(_Is_any_of_v<_Elem, char, wchar_t, unsigned short>);

auto _Iter = _Ptr;
while (*_Iter != _Elem{}) {
++_Iter;
}
const size_t _Count = static_cast<size_t>(_Iter - _Ptr + 1) * sizeof(_Elem);

#ifdef _DEBUG
const auto _Result = static_cast<_Elem*>(_CSTD _malloc_dbg(_Count, _CRT_BLOCK, __FILE__, __LINE__));
#else
const auto _Result = static_cast<_Elem*>(_CSTD malloc(_Count));
#endif
if (_Result) {
_CSTD memcpy(_Result, _Ptr, _Count);
}

return _Result;
}

extern "C++" template <class _Elem>
class _CRTIMP2_PURE_IMPORT _Yarn { // wrap a NTCTS
public:
Expand All @@ -156,26 +178,22 @@ public:
_Tidy();

if (_Right) { // new is not empty, copy it
const _Elem* _Ptr = _Right;
while (*_Ptr != _Elem{}) {
++_Ptr;
}
_Myptr = _STD _Ntcts_dup_dbg(_Right);
}
}

const auto _Count = (++_Ptr - _Right) * sizeof(_Elem);
return *this;
}

#ifdef _DEBUG
_Myptr = static_cast<_Elem*>(_malloc_dbg(_Count, _CRT_BLOCK, __FILE__, __LINE__));
#else
_Myptr = static_cast<_Elem*>(_CSTD malloc(_Count));
#endif
template <class _Elem2 = _Elem, enable_if_t<is_same_v<_Elem2, char>, int> = 0>
void _From_wide(const wchar_t* const _Right) noexcept {
if (reinterpret_cast<wchar_t*>(_Myptr) != _Right) { // new value, discard old and copy new
_Tidy();

if (_Myptr) {
_CSTD memcpy(_Myptr, _Right, _Count);
}
if (_Right) { // new is not empty, copy it
_Myptr = reinterpret_cast<char*>(_STD _Ntcts_dup_dbg(_Right));
}
}

return *this;
}

__CLR_OR_THIS_CALL ~_Yarn() noexcept {
Expand Down Expand Up @@ -382,7 +400,8 @@ private:
_Yarn<char> _Months; // month names
_Yarn<wchar_t> _W_Days; // wide weekday names
_Yarn<wchar_t> _W_Months; // wide month names
_Yarn<wchar_t> _Oldlocname; // old locale name to revert to on destruction
// TRANSITION, ABI, `_Oldlocname._Myptr` is reinterpreted as `wchar_t*`. `wchar` should be wrapped instead.
_Yarn<char> _Oldlocname; // old locale name to revert to on destruction
_Yarn<char> _Newlocname; // new locale name for this object
};
_STD_END
Expand Down
2 changes: 1 addition & 1 deletion stl/src/locale.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ void __CLRCALL_PURE_OR_CDECL locale::_Locimp::_Locimp_Addfac(

void __CLRCALL_PURE_OR_CDECL _Locinfo::_Locinfo_ctor(
_Locinfo* pLocinfo, int cat, const char* locname) { // capture a named locale
pLocinfo->_Oldlocname = _wsetlocale(LC_ALL, nullptr);
pLocinfo->_Oldlocname._From_wide(_wsetlocale(LC_ALL, nullptr));
_Locinfo_Addcats(pLocinfo, cat, locname);
}

Expand Down
10 changes: 8 additions & 2 deletions stl/src/locale0.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ void __CLRCALL_PURE_OR_CDECL locale::_Locimp::_Locimp_dtor(_Locimp* _This) { //

void __CLRCALL_PURE_OR_CDECL _Locinfo::_Locinfo_ctor(
_Locinfo* pLocinfo, const char* locname) { // switch to a named locale
pLocinfo->_Oldlocname = _wsetlocale(LC_ALL, nullptr);
pLocinfo->_Oldlocname._From_wide(_wsetlocale(LC_ALL, nullptr));

if (locname != nullptr) {
locname = setlocale(LC_ALL, locname);
Expand All @@ -232,7 +232,13 @@ void __CLRCALL_PURE_OR_CDECL _Locinfo::_Locinfo_ctor(
}

void __CLRCALL_PURE_OR_CDECL _Locinfo::_Locinfo_dtor(_Locinfo* pLocinfo) { // destroy a _Locinfo object, revert locale
_wsetlocale(LC_ALL, pLocinfo->_Oldlocname._C_str());
if (pLocinfo->_Oldlocname._Empty()) {
// `pLocinfo->_Oldlocname._C_str()` points to a single `char` of value 0 in this case,
// so reinterpret_cast is not reliable.
_wsetlocale(LC_ALL, L"");
} else {
_wsetlocale(LC_ALL, reinterpret_cast<const wchar_t*>(pLocinfo->_Oldlocname._C_str()));
}
}
_STD_END

Expand Down