-// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003
+// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
+// 2006, 2007, 2008, 2009, 2010
// Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
-// Free Software Foundation; either version 2, or (at your option)
+// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License along
-// with this library; see the file COPYING. If not, write to the Free
-// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
-// USA.
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
-// As a special exception, you may use this file as part of a free software
-// library without restriction. Specifically, if other files instantiate
-// templates or use macros or inline functions from this file, or you compile
-// this file and link it with other files to produce an executable, this
-// file does not by itself cause the resulting executable to be covered by
-// the GNU General Public License. This exception does not however
-// invalidate any other reasons why the executable file might be covered by
-// the GNU General Public License.
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+// <http://www.gnu.org/licenses/>.
#include <clocale>
#include <cstring>
+#include <cstdlib>
#include <locale>
-namespace __gnu_cxx
+namespace std _GLIBCXX_VISIBILITY(default)
{
- using namespace std;
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
- // Defined in globals.cc.
- extern locale::facet* facet_vec[_GLIBCPP_NUM_FACETS];
- extern char* name_vec[6 + _GLIBCPP_NUM_CATEGORIES];
- extern char name_c[6 + _GLIBCPP_NUM_CATEGORIES][2];
-
- extern std::ctype<char> ctype_c;
- extern std::collate<char> collate_c;
- extern numpunct<char> numpunct_c;
- extern num_get<char> num_get_c;
- extern num_put<char> num_put_c;
- extern codecvt<char, char, mbstate_t> codecvt_c;
- extern moneypunct<char, false> moneypunct_fc;
- extern moneypunct<char, true> moneypunct_tc;
- extern money_get<char> money_get_c;
- extern money_put<char> money_put_c;
- extern __timepunct<char> timepunct_c;
- extern time_get<char> time_get_c;
- extern time_put<char> time_put_c;
- extern std::messages<char> messages_c;
-#ifdef _GLIBCPP_USE_WCHAR_T
- extern std::ctype<wchar_t> ctype_w;
- extern std::collate<wchar_t> collate_w;
- extern numpunct<wchar_t> numpunct_w;
- extern num_get<wchar_t> num_get_w;
- extern num_put<wchar_t> num_put_w;
- extern codecvt<wchar_t, char, mbstate_t> codecvt_w;
- extern moneypunct<wchar_t, false> moneypunct_fw;
- extern moneypunct<wchar_t, true> moneypunct_tw;
- extern money_get<wchar_t> money_get_w;
- extern money_put<wchar_t> money_put_w;
- extern __timepunct<wchar_t> timepunct_w;
- extern time_get<wchar_t> time_get_w;
- extern time_put<wchar_t> time_put_w;
- extern std::messages<wchar_t> messages_w;
-#endif
-} // namespace __gnu_cxx
-
-namespace std
-{
using namespace __gnu_cxx;
- locale::_Impl::
- ~_Impl() throw()
+ locale::locale(const char* __s) : _M_impl(0)
{
- for (size_t __i = 0; __i < _M_facets_size; ++__i)
- if (_M_facets[__i])
- _M_facets[__i]->_M_remove_reference();
- delete [] _M_facets;
+ if (__s)
+ {
+ _S_initialize();
+ if (std::strcmp(__s, "C") == 0 || std::strcmp(__s, "POSIX") == 0)
+ (_M_impl = _S_classic)->_M_add_reference();
+ else if (std::strcmp(__s, "") != 0)
+ _M_impl = new _Impl(__s, 1);
+ else
+ {
+ // Get it from the environment.
+ char* __env = std::getenv("LC_ALL");
+ // If LC_ALL is set we are done.
+ if (__env && std::strcmp(__env, "") != 0)
+ {
+ if (std::strcmp(__env, "C") == 0
+ || std::strcmp(__env, "POSIX") == 0)
+ (_M_impl = _S_classic)->_M_add_reference();
+ else
+ _M_impl = new _Impl(__env, 1);
+ }
+ else
+ {
+ // LANG may set a default different from "C".
+ string __lang;
+ __env = std::getenv("LANG");
+ if (!__env || std::strcmp(__env, "") == 0
+ || std::strcmp(__env, "C") == 0
+ || std::strcmp(__env, "POSIX") == 0)
+ __lang = "C";
+ else
+ __lang = __env;
+
+ // Scan the categories looking for the first one
+ // different from LANG.
+ size_t __i = 0;
+ if (__lang == "C")
+ for (; __i < _S_categories_size; ++__i)
+ {
+ __env = std::getenv(_S_categories[__i]);
+ if (__env && std::strcmp(__env, "") != 0
+ && std::strcmp(__env, "C") != 0
+ && std::strcmp(__env, "POSIX") != 0)
+ break;
+ }
+ else
+ for (; __i < _S_categories_size; ++__i)
+ {
+ __env = std::getenv(_S_categories[__i]);
+ if (__env && std::strcmp(__env, "") != 0
+ && __lang != __env)
+ break;
+ }
+
+ // If one is found, build the complete string of
+ // the form LC_CTYPE=xxx;LC_NUMERIC=yyy; and so on...
+ if (__i < _S_categories_size)
+ {
+ string __str;
+ __str.reserve(128);
+ for (size_t __j = 0; __j < __i; ++__j)
+ {
+ __str += _S_categories[__j];
+ __str += '=';
+ __str += __lang;
+ __str += ';';
+ }
+ __str += _S_categories[__i];
+ __str += '=';
+ __str += __env;
+ __str += ';';
+ ++__i;
+ for (; __i < _S_categories_size; ++__i)
+ {
+ __env = std::getenv(_S_categories[__i]);
+ __str += _S_categories[__i];
+ if (!__env || std::strcmp(__env, "") == 0)
+ {
+ __str += '=';
+ __str += __lang;
+ __str += ';';
+ }
+ else if (std::strcmp(__env, "C") == 0
+ || std::strcmp(__env, "POSIX") == 0)
+ __str += "=C;";
+ else
+ {
+ __str += '=';
+ __str += __env;
+ __str += ';';
+ }
+ }
+ __str.erase(__str.end() - 1);
+ _M_impl = new _Impl(__str.c_str(), 1);
+ }
+ // ... otherwise either an additional instance of
+ // the "C" locale or LANG.
+ else if (__lang == "C")
+ (_M_impl = _S_classic)->_M_add_reference();
+ else
+ _M_impl = new _Impl(__lang.c_str(), 1);
+ }
+ }
+ }
+ else
+ __throw_runtime_error(__N("locale::locale null not valid"));
+ }
- for (size_t __i = 0; __i < _S_categories_size; ++__i)
- delete [] _M_names[__i];
- delete [] _M_names;
+ locale::locale(const locale& __base, const char* __s, category __cat)
+ : _M_impl(0)
+ {
+ // NB: There are complicated, yet more efficient ways to do
+ // this. Building up locales on a per-category way is tedious, so
+ // let's do it this way until people complain.
+ locale __add(__s);
+ _M_coalesce(__base, __add, __cat);
}
- // Clone existing _Impl object.
- locale::_Impl::
- _Impl(const _Impl& __imp, size_t __refs)
- : _M_references(__refs), _M_facets_size(__imp._M_facets_size) // XXX
+ locale::locale(const locale& __base, const locale& __add, category __cat)
+ : _M_impl(0)
+ { _M_coalesce(__base, __add, __cat); }
+
+ void
+ locale::_M_coalesce(const locale& __base, const locale& __add,
+ category __cat)
{
- try
- {
- _M_facets = new const facet*[_M_facets_size];
- for (size_t __i = 0; __i < _M_facets_size; ++__i)
- _M_facets[__i] = 0;
- }
- catch(...)
- {
- delete [] _M_facets;
- __throw_exception_again;
- }
- for (size_t __i = 0; __i < _M_facets_size; ++__i)
- {
- _M_facets[__i] = __imp._M_facets[__i];
- if (_M_facets[__i])
- _M_facets[__i]->_M_add_reference();
- }
+ __cat = _S_normalize_category(__cat);
+ _M_impl = new _Impl(*__base._M_impl, 1);
- try
- {
- _M_names = new char*[_S_categories_size];
- }
- catch(...)
- {
- delete [] _M_names;
+ __try
+ { _M_impl->_M_replace_categories(__add._M_impl, __cat); }
+ __catch(...)
+ {
+ _M_impl->_M_remove_reference();
__throw_exception_again;
}
- for (size_t __i = 0; __i < _S_categories_size; ++__i)
- {
- char* __new = new char[strlen(__imp._M_names[__i]) + 1];
- strcpy(__new, __imp._M_names[__i]);
- _M_names[__i] = __new;
- }
}
// Construct named _Impl.
locale::_Impl::
- _Impl(const char* __s, size_t __refs)
- : _M_references(__refs), _M_facets_size(_GLIBCPP_NUM_FACETS)
+ _Impl(const char* __s, size_t __refs)
+ : _M_refcount(__refs), _M_facets(0), _M_facets_size(_GLIBCXX_NUM_FACETS),
+ _M_caches(0), _M_names(0)
{
- // Initialize the underlying locale model, which also checks
- // to see if the given name is valid.
+ // Initialize the underlying locale model, which also checks to
+ // see if the given name is valid.
__c_locale __cloc;
locale::facet::_S_create_c_locale(__cloc, __s);
+ __c_locale __clocm = __cloc;
- try
- {
- _M_facets = new const facet*[_M_facets_size];
+ __try
+ {
+ _M_facets = new const facet*[_M_facets_size];
for (size_t __i = 0; __i < _M_facets_size; ++__i)
_M_facets[__i] = 0;
- }
- catch(...)
- {
- delete [] _M_facets;
- __throw_exception_again;
- }
+ _M_caches = new const facet*[_M_facets_size];
+ for (size_t __j = 0; __j < _M_facets_size; ++__j)
+ _M_caches[__j] = 0;
+ _M_names = new char*[_S_categories_size];
+ for (size_t __k = 0; __k < _S_categories_size; ++__k)
+ _M_names[__k] = 0;
- // Name all the categories.
- try
- {
- _M_names = new char*[_S_categories_size];
- }
- catch(...)
- {
- delete [] _M_names;
- __throw_exception_again;
- }
- size_t __len = strlen(__s);
- if (!strchr(__s, ';'))
- {
- for (size_t __i = 0; __i < _S_categories_size; ++__i)
+ // Name the categories.
+ const char* __smon = __s;
+ const size_t __len = std::strlen(__s);
+ if (!std::memchr(__s, ';', __len))
{
- _M_names[__i] = new char[__len + 1];
- strcpy(_M_names[__i], __s);
+ _M_names[0] = new char[__len + 1];
+ std::memcpy(_M_names[0], __s, __len + 1);
}
- }
- else
- {
- const char* __beg = __s;
- for (size_t __i = 0; __i < _S_categories_size; ++__i)
+ else
{
- __beg = strchr(__beg, '=') + 1;
- const char* __end = strchr(__beg, ';');
- if (!__end)
- __end = __s + __len;
- char* __new = new char[__end - __beg + 1];
- memcpy(__new, __beg, __end - __beg);
- __new[__end - __beg] = '\0';
- _M_names[__i] = __new;
- }
- }
+ const char* __end = __s;
+ bool __found_ctype = false;
+ bool __found_monetary = false;
+ size_t __ci = 0, __mi = 0;
+ for (size_t __i = 0; __i < _S_categories_size; ++__i)
+ {
+ const char* __beg = std::strchr(__end + 1, '=') + 1;
+ __end = std::strchr(__beg, ';');
+ if (!__end)
+ __end = __s + __len;
+ _M_names[__i] = new char[__end - __beg + 1];
+ std::memcpy(_M_names[__i], __beg, __end - __beg);
+ _M_names[__i][__end - __beg] = '\0';
+ if (!__found_ctype
+ && *(__beg - 2) == 'E' && *(__beg - 3) == 'P')
+ {
+ __found_ctype = true;
+ __ci = __i;
+ }
+ else if (!__found_monetary && *(__beg - 2) == 'Y')
+ {
+ __found_monetary = true;
+ __mi = __i;
+ }
+ }
- // Construct all standard facets and add them to _M_facets.
- _M_init_facet(new std::ctype<char>(__cloc, 0, false));
- _M_init_facet(new codecvt<char, char, mbstate_t>(__cloc));
- _M_init_facet(new numpunct<char>(__cloc));
- _M_init_facet(new num_get<char>);
- _M_init_facet(new num_put<char>);
- _M_init_facet(new std::collate<char>(__cloc));
- _M_init_facet(new moneypunct<char, false>(__cloc, __s));
- _M_init_facet(new moneypunct<char, true>(__cloc, __s));
- _M_init_facet(new money_get<char>);
- _M_init_facet(new money_put<char>);
- _M_init_facet(new __timepunct<char>(__cloc, __s));
- _M_init_facet(new time_get<char>);
- _M_init_facet(new time_put<char>);
- _M_init_facet(new std::messages<char>(__cloc, __s));
+ if (std::strcmp(_M_names[__ci], _M_names[__mi]))
+ {
+ __smon = _M_names[__mi];
+ __clocm = locale::facet::_S_lc_ctype_c_locale(__cloc,
+ __smon);
+ }
+ }
+
+ // Construct all standard facets and add them to _M_facets.
+ _M_init_facet(new std::ctype<char>(__cloc, 0, false));
+ _M_init_facet(new codecvt<char, char, mbstate_t>(__cloc));
+ _M_init_facet(new numpunct<char>(__cloc));
+ _M_init_facet(new num_get<char>);
+ _M_init_facet(new num_put<char>);
+ _M_init_facet(new std::collate<char>(__cloc));
+ _M_init_facet(new moneypunct<char, false>(__cloc, 0));
+ _M_init_facet(new moneypunct<char, true>(__cloc, 0));
+ _M_init_facet(new money_get<char>);
+ _M_init_facet(new money_put<char>);
+ _M_init_facet(new __timepunct<char>(__cloc, __s));
+ _M_init_facet(new time_get<char>);
+ _M_init_facet(new time_put<char>);
+ _M_init_facet(new std::messages<char>(__cloc, __s));
-#ifdef _GLIBCPP_USE_WCHAR_T
- _M_init_facet(new std::ctype<wchar_t>(__cloc));
- _M_init_facet(new codecvt<wchar_t, char, mbstate_t>(__cloc));
- _M_init_facet(new numpunct<wchar_t>(__cloc));
- _M_init_facet(new num_get<wchar_t>);
- _M_init_facet(new num_put<wchar_t>);
- _M_init_facet(new std::collate<wchar_t>(__cloc));
- _M_init_facet(new moneypunct<wchar_t, false>(__cloc, __s));
- _M_init_facet(new moneypunct<wchar_t, true>(__cloc, __s));
- _M_init_facet(new money_get<wchar_t>);
- _M_init_facet(new money_put<wchar_t>);
- _M_init_facet(new __timepunct<wchar_t>(__cloc, __s));
- _M_init_facet(new time_get<wchar_t>);
- _M_init_facet(new time_put<wchar_t>);
- _M_init_facet(new std::messages<wchar_t>(__cloc, __s));
+#ifdef _GLIBCXX_USE_WCHAR_T
+ _M_init_facet(new std::ctype<wchar_t>(__cloc));
+ _M_init_facet(new codecvt<wchar_t, char, mbstate_t>(__cloc));
+ _M_init_facet(new numpunct<wchar_t>(__cloc));
+ _M_init_facet(new num_get<wchar_t>);
+ _M_init_facet(new num_put<wchar_t>);
+ _M_init_facet(new std::collate<wchar_t>(__cloc));
+ _M_init_facet(new moneypunct<wchar_t, false>(__clocm, __smon));
+ _M_init_facet(new moneypunct<wchar_t, true>(__clocm, __smon));
+ _M_init_facet(new money_get<wchar_t>);
+ _M_init_facet(new money_put<wchar_t>);
+ _M_init_facet(new __timepunct<wchar_t>(__cloc, __s));
+ _M_init_facet(new time_get<wchar_t>);
+ _M_init_facet(new time_put<wchar_t>);
+ _M_init_facet(new std::messages<wchar_t>(__cloc, __s));
#endif
- locale::facet::_S_destroy_c_locale(__cloc);
- }
-
- // Construct "C" _Impl.
- locale::_Impl::
- _Impl(facet**, size_t __refs, bool)
- : _M_references(__refs), _M_facets_size(_GLIBCPP_NUM_FACETS)
- {
- // Initialize the underlying locale model.
- locale::facet::_S_c_name[0] = 'C';
- locale::facet::_S_c_name[1] = '\0';
- locale::facet::_S_create_c_locale(locale::facet::_S_c_locale,
- locale::facet::_S_c_name);
-
- _M_facets = new (&facet_vec) const facet*[_M_facets_size];
- for (size_t __i = 0; __i < _M_facets_size; ++__i)
- _M_facets[__i] = 0;
-
- // Name all the categories.
- _M_names = new (&name_vec) char*[_S_categories_size];
- for (size_t __i = 0; __i < _S_categories_size; ++__i)
- {
- _M_names[__i] = new (&name_c[__i]) char[2];
- strcpy(_M_names[__i], locale::facet::_S_c_name);
+ locale::facet::_S_destroy_c_locale(__cloc);
+ if (__clocm != __cloc)
+ locale::facet::_S_destroy_c_locale(__clocm);
}
-
- // This is needed as presently the C++ version of "C" locales
- // != data in the underlying locale model for __timepunct,
- // numpunct, and moneypunct. Also, the "C" locales must be
- // constructed in a way such that they are pre-allocated.
- // NB: Set locale::facets(ref) count to one so that each individual
- // facet is not destroyed when the locale (and thus locale::_Impl) is
- // destroyed.
- _M_init_facet(new (&ctype_c) std::ctype<char>(0, false, 1));
- _M_init_facet(new (&codecvt_c) codecvt<char, char, mbstate_t>(1));
- _M_init_facet(new (&numpunct_c) numpunct<char>(1));
- _M_init_facet(new (&num_get_c) num_get<char>(1));
- _M_init_facet(new (&num_put_c) num_put<char>(1));
- _M_init_facet(new (&collate_c) std::collate<char>(1));
- _M_init_facet(new (&moneypunct_fc) moneypunct<char, false>(1));
- _M_init_facet(new (&moneypunct_tc) moneypunct<char, true>(1));
- _M_init_facet(new (&money_get_c) money_get<char>(1));
- _M_init_facet(new (&money_put_c) money_put<char>(1));
- _M_init_facet(new (&timepunct_c) __timepunct<char>(1));
- _M_init_facet(new (&time_get_c) time_get<char>(1));
- _M_init_facet(new (&time_put_c) time_put<char>(1));
- _M_init_facet(new (&messages_c) std::messages<char>(1));
-#ifdef _GLIBCPP_USE_WCHAR_T
- _M_init_facet(new (&ctype_w) std::ctype<wchar_t>(1));
- _M_init_facet(new (&codecvt_w) codecvt<wchar_t, char, mbstate_t>(1));
- _M_init_facet(new (&numpunct_w) numpunct<wchar_t>(1));
- _M_init_facet(new (&num_get_w) num_get<wchar_t>(1));
- _M_init_facet(new (&num_put_w) num_put<wchar_t>(1));
- _M_init_facet(new (&collate_w) std::collate<wchar_t>(1));
- _M_init_facet(new (&moneypunct_fw) moneypunct<wchar_t, false>(1));
- _M_init_facet(new (&moneypunct_tw) moneypunct<wchar_t, true>(1));
- _M_init_facet(new (&money_get_w) money_get<wchar_t>(1));
- _M_init_facet(new (&money_put_w) money_put<wchar_t>(1));
- _M_init_facet(new (&timepunct_w) __timepunct<wchar_t>(1));
- _M_init_facet(new (&time_get_w) time_get<wchar_t>(1));
- _M_init_facet(new (&time_put_w) time_put<wchar_t>(1));
- _M_init_facet(new (&messages_w) std::messages<wchar_t>(1));
-#endif
+ __catch(...)
+ {
+ locale::facet::_S_destroy_c_locale(__cloc);
+ if (__clocm != __cloc)
+ locale::facet::_S_destroy_c_locale(__clocm);
+ this->~_Impl();
+ __throw_exception_again;
+ }
}
-
+
void
locale::_Impl::
_M_replace_categories(const _Impl* __imp, category __cat)
{
- category __mask;
- for (size_t __ix = 0; __ix < _S_categories_size; ++__ix)
+ category __mask = 1;
+ if (!_M_names[0] || !__imp->_M_names[0])
{
- __mask = 1 << __ix;
- if (__mask & __cat)
+ if (_M_names[0])
{
- // Need to replace entry in _M_facets with other locale's info.
- _M_replace_category(__imp, _S_facet_categories[__ix]);
- // If both have names, go ahead and mangle.
- if (strcmp(_M_names[__ix], "*") != 0
- && strcmp(__imp->_M_names[__ix], "*") != 0)
- {
- delete [] _M_names[__ix];
- char* __new = new char[strlen(__imp->_M_names[__ix]) + 1];
- strcpy(__new, __imp->_M_names[__ix]);
- _M_names[__ix] = __new;
- }
+ delete [] _M_names[0];
+ _M_names[0] = 0; // Unnamed.
}
- }
- }
-
- void
- locale::_Impl::
- _M_replace_category(const _Impl* __imp, const locale::id* const* __idpp)
- {
- for (; *__idpp; ++__idpp)
- _M_replace_facet(__imp, *__idpp);
- }
-
- void
- locale::_Impl::
- _M_replace_facet(const _Impl* __imp, const locale::id* __idp)
- {
- size_t __index = __idp->_M_id();
- if ((__index > (__imp->_M_facets_size - 1)) || !__imp->_M_facets[__index])
- __throw_runtime_error("locale::_Impl::_M_replace_facet");
- _M_install_facet(__idp, __imp->_M_facets[__index]);
- }
- void
- locale::_Impl::
- _M_install_facet(const locale::id* __idp, const facet* __fp)
- {
- if (__fp)
- {
- size_t __index = __idp->_M_id();
-
- // Check size of facet vector to ensure adequate room.
- if (__index > _M_facets_size - 1)
+ for (size_t __ix = 0; __ix < _S_categories_size; ++__ix, __mask <<= 1)
{
- const facet** __old = _M_facets;
- const facet** __new;
- const size_t __new_size = __index + 4;
- __new = new const facet*[__new_size];
- for (size_t __i = 0; __i < _M_facets_size; ++__i)
- __new[__i] = _M_facets[__i];
- for (size_t __i2 = _M_facets_size; __i2 < __new_size; ++__i2)
- __new[__i2] = 0;
-
- _M_facets_size = __new_size;
- _M_facets = __new;
- delete [] __old;
+ if (__mask & __cat)
+ // Need to replace entry in _M_facets with other locale's info.
+ _M_replace_category(__imp, _S_facet_categories[__ix]);
}
-
- __fp->_M_add_reference();
- const facet*& __fpr = _M_facets[__index];
- if (__fpr)
+ }
+ else
+ {
+ if (!_M_names[1])
{
- // Replacing an existing facet. Order matters.
- __fpr->_M_remove_reference();
- __fpr = __fp;
+ // A full set of _M_names must be prepared, all identical
+ // to _M_names[0] to begin with. Then, below, a few will
+ // be replaced by the corresponding __imp->_M_names. I.e.,
+ // not a "simple" locale anymore (see locale::operator==).
+ const size_t __len = std::strlen(_M_names[0]) + 1;
+ for (size_t __i = 1; __i < _S_categories_size; ++__i)
+ {
+ _M_names[__i] = new char[__len];
+ std::memcpy(_M_names[__i], _M_names[0], __len);
+ }
}
- else
+
+ for (size_t __ix = 0; __ix < _S_categories_size; ++__ix, __mask <<= 1)
{
- // Installing a newly created facet into an empty
- // _M_facets container, say a newly-constructed,
- // swanky-fresh _Impl.
- _M_facets[__index] = __fp;
+ if (__mask & __cat)
+ {
+ // Need to replace entry in _M_facets with other locale's info.
+ _M_replace_category(__imp, _S_facet_categories[__ix]);
+
+ // FIXME: Hack for libstdc++/29217: the numerical encodings
+ // of the time and collate categories are swapped vs the
+ // order of the names in locale::_S_categories. We'd like to
+ // adjust the former (the latter is dictated by compatibility
+ // with glibc) but we can't for binary compatibility.
+ size_t __ix_name = __ix;
+ if (__ix == 2 || __ix == 3)
+ __ix_name = 5 - __ix;
+
+ char* __src = __imp->_M_names[__ix_name] ?
+ __imp->_M_names[__ix_name] : __imp->_M_names[0];
+ const size_t __len = std::strlen(__src) + 1;
+ char* __new = new char[__len];
+ std::memcpy(__new, __src, __len);
+ delete [] _M_names[__ix_name];
+ _M_names[__ix_name] = __new;
+ }
}
}
}
-} // namespace std
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace