2006-09-27 Paolo Carlini <pcarlini@suse.de> PR libstdc++/29217 * src/localename.cc (locale::_Impl::_M_replace_categories)): Compensate for the inconsistent numerical encodings of the collate and time categories vs the corresponding names. * testsuite/22_locale/locale/cons/29217.cc: New. --- libstdc++-v3/src/localename.cc (revision 117246) +++ libstdc++-v3/src/localename.cc (revision 117247) @@ -288,13 +288,23 @@ _GLIBCXX_BEGIN_NAMESPACE(std) std::memcpy(_M_names[__i], _M_names[0], __len); } } - char* __src = __imp->_M_names[__ix] ? __imp->_M_names[__ix] - : __imp->_M_names[0]; + + // 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]; - _M_names[__ix] = __new; + delete [] _M_names[__ix_name]; + _M_names[__ix_name] = __new; } } } --- libstdc++-v3/testsuite/22_locale/locale/cons/29217.cc (revision 0) +++ libstdc++-v3/testsuite/22_locale/locale/cons/29217.cc (revision 117247) @@ -0,0 +1,54 @@ +// { dg-require-namedlocale "" } + +// Copyright (C) 2006 Free Software Foundation +// +// 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) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +// USA. + +// 22.1.1.2 locale constructors and destructors [lib.locale.cons] + +#include <locale> +#include <testsuite_hooks.h> + +// libstdc++/29217 +void test01() +{ + bool test __attribute__((unused)) = true; + using namespace std; + + locale::global(locale(locale(), "en_US.UTF-8", + locale::collate | locale::ctype)); + + VERIFY( locale().name() == "LC_CTYPE=en_US.UTF-8;LC_NUMERIC=C;" + "LC_TIME=C;LC_COLLATE=en_US.UTF-8;LC_MONETARY=C;LC_MESSAGES=C;" + "LC_PAPER=C;LC_NAME=C;LC_ADDRESS=C;LC_TELEPHONE=C;" + "LC_MEASUREMENT=C;LC_IDENTIFICATION=C" ); + + VERIFY( locale().name() == setlocale(LC_ALL, NULL) ); + + locale loc1 = locale(locale::classic(), "en_US.UTF-8", locale::time); + + VERIFY( loc1.name() == "LC_CTYPE=C;LC_NUMERIC=C;LC_TIME=en_US.UTF-8;" + "LC_COLLATE=C;LC_MONETARY=C;LC_MESSAGES=C;LC_PAPER=C;LC_NAME=C;" + "LC_ADDRESS=C;LC_TELEPHONE=C;LC_MEASUREMENT=C;" + "LC_IDENTIFICATION=C" ); +} + +int main() +{ + test01(); + return 0; +}