mirror of git://gcc.gnu.org/git/gcc.git
re PR libstdc++/40184 (locale(const char* std_name) can create invalid facets for nonuniform locale)
2009-05-19 Paolo Carlini <paolo.carlini@oracle.com> PR libstdc++/40184 * include/bits/locale_classes.h (locale::facet::_S_lc_ctype_c_locale): Declare... * config/locale/gnu/c_locale.cc: ... and define. * config/locale/generic/c_locale.cc: Define. * src/localename.cc (locale::_Impl::_Impl(const char*, size_t)): Use it. * testsuite/22_locale/locale/cons/40184.cc: New. From-SVN: r147714
This commit is contained in:
parent
f3a8311127
commit
c8036448d1
|
@ -1,3 +1,14 @@
|
||||||
|
2009-05-19 Paolo Carlini <paolo.carlini@oracle.com>
|
||||||
|
|
||||||
|
PR libstdc++/40184
|
||||||
|
* include/bits/locale_classes.h (locale::facet::_S_lc_ctype_c_locale):
|
||||||
|
Declare...
|
||||||
|
* config/locale/gnu/c_locale.cc: ... and define.
|
||||||
|
* config/locale/generic/c_locale.cc: Define.
|
||||||
|
* src/localename.cc (locale::_Impl::_Impl(const char*, size_t)):
|
||||||
|
Use it.
|
||||||
|
* testsuite/22_locale/locale/cons/40184.cc: New.
|
||||||
|
|
||||||
2009-05-18 Paolo Carlini <paolo.carlini@oracle.com>
|
2009-05-18 Paolo Carlini <paolo.carlini@oracle.com>
|
||||||
|
|
||||||
PR libstdc++/40192
|
PR libstdc++/40192
|
||||||
|
|
|
@ -226,6 +226,10 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
|
||||||
locale::facet::_S_clone_c_locale(__c_locale&)
|
locale::facet::_S_clone_c_locale(__c_locale&)
|
||||||
{ return __c_locale(); }
|
{ return __c_locale(); }
|
||||||
|
|
||||||
|
__c_locale
|
||||||
|
locale::facet::_S_lc_ctype_c_locale(__c_locale, const char*)
|
||||||
|
{ return __c_locale(); }
|
||||||
|
|
||||||
_GLIBCXX_END_NAMESPACE
|
_GLIBCXX_END_NAMESPACE
|
||||||
|
|
||||||
_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
|
_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
|
||||||
|
|
|
@ -148,6 +148,23 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
|
||||||
locale::facet::_S_clone_c_locale(__c_locale& __cloc)
|
locale::facet::_S_clone_c_locale(__c_locale& __cloc)
|
||||||
{ return __duplocale(__cloc); }
|
{ return __duplocale(__cloc); }
|
||||||
|
|
||||||
|
__c_locale
|
||||||
|
locale::facet::_S_lc_ctype_c_locale(__c_locale __cloc, const char* __s)
|
||||||
|
{
|
||||||
|
__c_locale __dup = __duplocale(__cloc);
|
||||||
|
if (__dup == __c_locale(0))
|
||||||
|
__throw_runtime_error(__N("locale::facet::_S_lc_ctype_c_locale "
|
||||||
|
"duplocale error"));
|
||||||
|
__c_locale __changed = __newlocale(LC_CTYPE_MASK, __s, __dup);
|
||||||
|
if (__changed == __c_locale(0))
|
||||||
|
{
|
||||||
|
__freelocale(__dup);
|
||||||
|
__throw_runtime_error(__N("locale::facet::_S_lc_ctype_c_locale "
|
||||||
|
"newlocale error"));
|
||||||
|
}
|
||||||
|
return __changed;
|
||||||
|
}
|
||||||
|
|
||||||
_GLIBCXX_END_NAMESPACE
|
_GLIBCXX_END_NAMESPACE
|
||||||
|
|
||||||
_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
|
_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
|
||||||
|
|
|
@ -381,6 +381,9 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
|
||||||
static void
|
static void
|
||||||
_S_destroy_c_locale(__c_locale& __cloc);
|
_S_destroy_c_locale(__c_locale& __cloc);
|
||||||
|
|
||||||
|
static __c_locale
|
||||||
|
_S_lc_ctype_c_locale(__c_locale __cloc, const char* __s);
|
||||||
|
|
||||||
// Returns data from the underlying "C" library data for the
|
// Returns data from the underlying "C" library data for the
|
||||||
// classic locale.
|
// classic locale.
|
||||||
static __c_locale
|
static __c_locale
|
||||||
|
|
|
@ -180,6 +180,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
|
||||||
// see if the given name is valid.
|
// see if the given name is valid.
|
||||||
__c_locale __cloc;
|
__c_locale __cloc;
|
||||||
locale::facet::_S_create_c_locale(__cloc, __s);
|
locale::facet::_S_create_c_locale(__cloc, __s);
|
||||||
|
__c_locale __clocm = __cloc;
|
||||||
|
|
||||||
__try
|
__try
|
||||||
{
|
{
|
||||||
|
@ -194,6 +195,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
|
||||||
_M_names[__k] = 0;
|
_M_names[__k] = 0;
|
||||||
|
|
||||||
// Name the categories.
|
// Name the categories.
|
||||||
|
const char* __smon = __s;
|
||||||
const size_t __len = std::strlen(__s);
|
const size_t __len = std::strlen(__s);
|
||||||
if (!std::memchr(__s, ';', __len))
|
if (!std::memchr(__s, ';', __len))
|
||||||
{
|
{
|
||||||
|
@ -203,6 +205,9 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const char* __end = __s;
|
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)
|
for (size_t __i = 0; __i < _S_categories_size; ++__i)
|
||||||
{
|
{
|
||||||
const char* __beg = std::strchr(__end + 1, '=') + 1;
|
const char* __beg = std::strchr(__end + 1, '=') + 1;
|
||||||
|
@ -212,6 +217,24 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
|
||||||
_M_names[__i] = new char[__end - __beg + 1];
|
_M_names[__i] = new char[__end - __beg + 1];
|
||||||
std::memcpy(_M_names[__i], __beg, __end - __beg);
|
std::memcpy(_M_names[__i], __beg, __end - __beg);
|
||||||
_M_names[__i][__end - __beg] = '\0';
|
_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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (std::strcmp(_M_names[__ci], _M_names[__mi]))
|
||||||
|
{
|
||||||
|
__smon = _M_names[__mi];
|
||||||
|
__clocm = locale::facet::_S_lc_ctype_c_locale(__cloc,
|
||||||
|
__smon);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -222,8 +245,8 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
|
||||||
_M_init_facet(new num_get<char>);
|
_M_init_facet(new num_get<char>);
|
||||||
_M_init_facet(new num_put<char>);
|
_M_init_facet(new num_put<char>);
|
||||||
_M_init_facet(new std::collate<char>(__cloc));
|
_M_init_facet(new std::collate<char>(__cloc));
|
||||||
_M_init_facet(new moneypunct<char, false>(__cloc, __s));
|
_M_init_facet(new moneypunct<char, false>(__cloc, 0));
|
||||||
_M_init_facet(new moneypunct<char, true>(__cloc, __s));
|
_M_init_facet(new moneypunct<char, true>(__cloc, 0));
|
||||||
_M_init_facet(new money_get<char>);
|
_M_init_facet(new money_get<char>);
|
||||||
_M_init_facet(new money_put<char>);
|
_M_init_facet(new money_put<char>);
|
||||||
_M_init_facet(new __timepunct<char>(__cloc, __s));
|
_M_init_facet(new __timepunct<char>(__cloc, __s));
|
||||||
|
@ -238,8 +261,8 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
|
||||||
_M_init_facet(new num_get<wchar_t>);
|
_M_init_facet(new num_get<wchar_t>);
|
||||||
_M_init_facet(new num_put<wchar_t>);
|
_M_init_facet(new num_put<wchar_t>);
|
||||||
_M_init_facet(new std::collate<wchar_t>(__cloc));
|
_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, false>(__clocm, __smon));
|
||||||
_M_init_facet(new moneypunct<wchar_t, true>(__cloc, __s));
|
_M_init_facet(new moneypunct<wchar_t, true>(__clocm, __smon));
|
||||||
_M_init_facet(new money_get<wchar_t>);
|
_M_init_facet(new money_get<wchar_t>);
|
||||||
_M_init_facet(new money_put<wchar_t>);
|
_M_init_facet(new money_put<wchar_t>);
|
||||||
_M_init_facet(new __timepunct<wchar_t>(__cloc, __s));
|
_M_init_facet(new __timepunct<wchar_t>(__cloc, __s));
|
||||||
|
@ -248,10 +271,14 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
|
||||||
_M_init_facet(new std::messages<wchar_t>(__cloc, __s));
|
_M_init_facet(new std::messages<wchar_t>(__cloc, __s));
|
||||||
#endif
|
#endif
|
||||||
locale::facet::_S_destroy_c_locale(__cloc);
|
locale::facet::_S_destroy_c_locale(__cloc);
|
||||||
|
if (__clocm != __cloc)
|
||||||
|
locale::facet::_S_destroy_c_locale(__clocm);
|
||||||
}
|
}
|
||||||
__catch(...)
|
__catch(...)
|
||||||
{
|
{
|
||||||
locale::facet::_S_destroy_c_locale(__cloc);
|
locale::facet::_S_destroy_c_locale(__cloc);
|
||||||
|
if (__clocm != __cloc)
|
||||||
|
locale::facet::_S_destroy_c_locale(__clocm);
|
||||||
this->~_Impl();
|
this->~_Impl();
|
||||||
__throw_exception_again;
|
__throw_exception_again;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,60 @@
|
||||||
|
// { dg-require-namedlocale "" }
|
||||||
|
|
||||||
|
// Copyright (C) 2009 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 3, 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 COPYING3. If not see
|
||||||
|
// <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
// 22.1.1.2 locale constructors and destructors [lib.locale.cons]
|
||||||
|
|
||||||
|
#include <locale>
|
||||||
|
#include <testsuite_hooks.h>
|
||||||
|
|
||||||
|
// libstdc++/40184
|
||||||
|
void test01()
|
||||||
|
{
|
||||||
|
#ifdef _GLIBCXX_USE_WCHAR_T
|
||||||
|
using namespace std;
|
||||||
|
bool test __attribute__((unused)) = true;
|
||||||
|
|
||||||
|
locale locf(locale("C"), "ja_JP.eucjp", locale::monetary);
|
||||||
|
|
||||||
|
const moneypunct<wchar_t, false>& mpf =
|
||||||
|
use_facet<moneypunct<wchar_t, false> >(locf);
|
||||||
|
|
||||||
|
locale locf_copy(locf.name().c_str());
|
||||||
|
const moneypunct<wchar_t, false>& mpf_copy =
|
||||||
|
use_facet<moneypunct<wchar_t, false> >(locf_copy);
|
||||||
|
|
||||||
|
VERIFY( mpf.curr_symbol() == mpf_copy.curr_symbol() );
|
||||||
|
|
||||||
|
locale loct(locale("C"), "ja_JP.eucjp", locale::monetary);
|
||||||
|
|
||||||
|
const moneypunct<wchar_t, true>& mpt =
|
||||||
|
use_facet<moneypunct<wchar_t, true> >(loct);
|
||||||
|
|
||||||
|
locale loct_copy(loct.name().c_str());
|
||||||
|
const moneypunct<wchar_t, true>& mpt_copy =
|
||||||
|
use_facet<moneypunct<wchar_t, true> >(loct_copy);
|
||||||
|
|
||||||
|
VERIFY( mpt.curr_symbol() == mpt_copy.curr_symbol() );
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
test01();
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Reference in New Issue