re PR libstdc++/38368 (locale(const char* std_name) may create locale with broken facets)
2008-12-04 Paolo Carlini <paolo.carlini@oracle.com> PR libstdc++/38368 * config/locale/gnu/numeric_members.cc (numpunct<char>:: _M_initialize_numpunct, numpunct<wchar_t>::_M_initialize_numpunct): Fix for THOUSANDS_SEP == '\0' consistently with "C" locale. * config/locale/gnu/monetary_members.cc (moneypunct<char, true>:: _M_initialize_moneypunct, moneypunct<char, false>:: _M_initialize_moneypunct, moneypunct<wchar_t, true>:: _M_initialize_moneypunct, moneypunct<wchar_t, false>:: _M_initialize_moneypunct): Fix for __MON_DECIMAL_POINT == '\0' or __MON_THOUSANDS_SEP == '\0' consistently with "C" locale. * testsuite/22_locale/locale/cons/38368.cc: New. From-SVN: r142439
This commit is contained in:
parent
ce1b649802
commit
1d9aba8105
@ -1,3 +1,17 @@
|
||||
2008-12-04 Paolo Carlini <paolo.carlini@oracle.com>
|
||||
|
||||
PR libstdc++/38368
|
||||
* config/locale/gnu/numeric_members.cc (numpunct<char>::
|
||||
_M_initialize_numpunct, numpunct<wchar_t>::_M_initialize_numpunct):
|
||||
Fix for THOUSANDS_SEP == '\0' consistently with "C" locale.
|
||||
* config/locale/gnu/monetary_members.cc (moneypunct<char, true>::
|
||||
_M_initialize_moneypunct, moneypunct<char, false>::
|
||||
_M_initialize_moneypunct, moneypunct<wchar_t, true>::
|
||||
_M_initialize_moneypunct, moneypunct<wchar_t, false>::
|
||||
_M_initialize_moneypunct): Fix for __MON_DECIMAL_POINT == '\0' or
|
||||
__MON_THOUSANDS_SEP == '\0' consistently with "C" locale.
|
||||
* testsuite/22_locale/locale/cons/38368.cc: New.
|
||||
|
||||
2008-12-02 Paolo Carlini <paolo.carlini@oracle.com>
|
||||
|
||||
PR libstdc++/38365 (cont)
|
||||
|
@ -220,6 +220,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
|
||||
_M_data->_M_thousands_sep = ',';
|
||||
_M_data->_M_grouping = "";
|
||||
_M_data->_M_grouping_size = 0;
|
||||
_M_data->_M_use_grouping = false;
|
||||
_M_data->_M_curr_symbol = "";
|
||||
_M_data->_M_curr_symbol_size = 0;
|
||||
_M_data->_M_positive_sign = "";
|
||||
@ -240,11 +241,35 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
|
||||
__cloc));
|
||||
_M_data->_M_thousands_sep = *(__nl_langinfo_l(__MON_THOUSANDS_SEP,
|
||||
__cloc));
|
||||
_M_data->_M_grouping = __nl_langinfo_l(__MON_GROUPING, __cloc);
|
||||
_M_data->_M_grouping_size = strlen(_M_data->_M_grouping);
|
||||
_M_data->_M_positive_sign = __nl_langinfo_l(__POSITIVE_SIGN, __cloc);
|
||||
_M_data->_M_positive_sign_size = strlen(_M_data->_M_positive_sign);
|
||||
|
||||
// Check for NULL, which implies no grouping.
|
||||
if (_M_data->_M_thousands_sep == '\0')
|
||||
{
|
||||
// Like in "C" locale.
|
||||
_M_data->_M_grouping = "";
|
||||
_M_data->_M_grouping_size = 0;
|
||||
_M_data->_M_use_grouping = false;
|
||||
_M_data->_M_thousands_sep = ',';
|
||||
}
|
||||
else
|
||||
{
|
||||
_M_data->_M_grouping = __nl_langinfo_l(__MON_GROUPING, __cloc);
|
||||
_M_data->_M_grouping_size = strlen(_M_data->_M_grouping);
|
||||
}
|
||||
|
||||
// Check for NULL, which implies no fractional digits.
|
||||
if (_M_data->_M_decimal_point == '\0')
|
||||
{
|
||||
// Like in "C" locale.
|
||||
_M_data->_M_frac_digits = 0;
|
||||
_M_data->_M_decimal_point = '.';
|
||||
}
|
||||
else
|
||||
_M_data->_M_frac_digits = *(__nl_langinfo_l(__INT_FRAC_DIGITS,
|
||||
__cloc));
|
||||
|
||||
char __nposn = *(__nl_langinfo_l(__INT_N_SIGN_POSN, __cloc));
|
||||
if (!__nposn)
|
||||
_M_data->_M_negative_sign = "()";
|
||||
@ -256,8 +281,6 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
|
||||
// _Intl == true
|
||||
_M_data->_M_curr_symbol = __nl_langinfo_l(__INT_CURR_SYMBOL, __cloc);
|
||||
_M_data->_M_curr_symbol_size = strlen(_M_data->_M_curr_symbol);
|
||||
_M_data->_M_frac_digits = *(__nl_langinfo_l(__INT_FRAC_DIGITS,
|
||||
__cloc));
|
||||
char __pprecedes = *(__nl_langinfo_l(__INT_P_CS_PRECEDES, __cloc));
|
||||
char __pspace = *(__nl_langinfo_l(__INT_P_SEP_BY_SPACE, __cloc));
|
||||
char __pposn = *(__nl_langinfo_l(__INT_P_SIGN_POSN, __cloc));
|
||||
@ -285,6 +308,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
|
||||
_M_data->_M_thousands_sep = ',';
|
||||
_M_data->_M_grouping = "";
|
||||
_M_data->_M_grouping_size = 0;
|
||||
_M_data->_M_use_grouping = false;
|
||||
_M_data->_M_curr_symbol = "";
|
||||
_M_data->_M_curr_symbol_size = 0;
|
||||
_M_data->_M_positive_sign = "";
|
||||
@ -305,11 +329,35 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
|
||||
__cloc));
|
||||
_M_data->_M_thousands_sep = *(__nl_langinfo_l(__MON_THOUSANDS_SEP,
|
||||
__cloc));
|
||||
_M_data->_M_grouping = __nl_langinfo_l(__MON_GROUPING, __cloc);
|
||||
_M_data->_M_grouping_size = strlen(_M_data->_M_grouping);
|
||||
_M_data->_M_positive_sign = __nl_langinfo_l(__POSITIVE_SIGN, __cloc);
|
||||
_M_data->_M_positive_sign_size = strlen(_M_data->_M_positive_sign);
|
||||
|
||||
// Check for NULL, which implies no grouping.
|
||||
if (_M_data->_M_thousands_sep == '\0')
|
||||
{
|
||||
// Like in "C" locale.
|
||||
_M_data->_M_grouping = "";
|
||||
_M_data->_M_grouping_size = 0;
|
||||
_M_data->_M_use_grouping = false;
|
||||
_M_data->_M_thousands_sep = ',';
|
||||
}
|
||||
else
|
||||
{
|
||||
_M_data->_M_grouping = __nl_langinfo_l(__MON_GROUPING, __cloc);
|
||||
_M_data->_M_grouping_size = strlen(_M_data->_M_grouping);
|
||||
}
|
||||
|
||||
// Check for NULL, which implies no fractional digits.
|
||||
if (_M_data->_M_decimal_point == '\0')
|
||||
{
|
||||
// Like in "C" locale.
|
||||
_M_data->_M_frac_digits = 0;
|
||||
_M_data->_M_decimal_point = '.';
|
||||
}
|
||||
else
|
||||
_M_data->_M_frac_digits = *(__nl_langinfo_l(__FRAC_DIGITS,
|
||||
__cloc));
|
||||
|
||||
char __nposn = *(__nl_langinfo_l(__N_SIGN_POSN, __cloc));
|
||||
if (!__nposn)
|
||||
_M_data->_M_negative_sign = "()";
|
||||
@ -321,7 +369,6 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
|
||||
// _Intl == false
|
||||
_M_data->_M_curr_symbol = __nl_langinfo_l(__CURRENCY_SYMBOL, __cloc);
|
||||
_M_data->_M_curr_symbol_size = strlen(_M_data->_M_curr_symbol);
|
||||
_M_data->_M_frac_digits = *(__nl_langinfo_l(__FRAC_DIGITS, __cloc));
|
||||
char __pprecedes = *(__nl_langinfo_l(__P_CS_PRECEDES, __cloc));
|
||||
char __pspace = *(__nl_langinfo_l(__P_SEP_BY_SPACE, __cloc));
|
||||
char __pposn = *(__nl_langinfo_l(__P_SIGN_POSN, __cloc));
|
||||
@ -362,6 +409,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
|
||||
_M_data->_M_thousands_sep = L',';
|
||||
_M_data->_M_grouping = "";
|
||||
_M_data->_M_grouping_size = 0;
|
||||
_M_data->_M_use_grouping = false;
|
||||
_M_data->_M_curr_symbol = L"";
|
||||
_M_data->_M_curr_symbol_size = 0;
|
||||
_M_data->_M_positive_sign = L"";
|
||||
@ -397,8 +445,32 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
|
||||
|
||||
__u.__s = __nl_langinfo_l(_NL_MONETARY_THOUSANDS_SEP_WC, __cloc);
|
||||
_M_data->_M_thousands_sep = __u.__w;
|
||||
|
||||
// Check for NULL, which implies no grouping.
|
||||
if (_M_data->_M_thousands_sep == L'\0')
|
||||
{
|
||||
// Like in "C" locale.
|
||||
_M_data->_M_grouping = "";
|
||||
_M_data->_M_grouping_size = 0;
|
||||
_M_data->_M_use_grouping = false;
|
||||
_M_data->_M_thousands_sep = L',';
|
||||
}
|
||||
else
|
||||
{
|
||||
_M_data->_M_grouping = __nl_langinfo_l(__MON_GROUPING, __cloc);
|
||||
_M_data->_M_grouping_size = strlen(_M_data->_M_grouping);
|
||||
}
|
||||
|
||||
// Check for NULL, which implies no fractional digits.
|
||||
if (_M_data->_M_decimal_point == L'\0')
|
||||
{
|
||||
// Like in "C" locale.
|
||||
_M_data->_M_frac_digits = 0;
|
||||
_M_data->_M_decimal_point = L'.';
|
||||
}
|
||||
else
|
||||
_M_data->_M_frac_digits = *(__nl_langinfo_l(__INT_FRAC_DIGITS,
|
||||
__cloc));
|
||||
|
||||
const char* __cpossign = __nl_langinfo_l(__POSITIVE_SIGN, __cloc);
|
||||
const char* __cnegsign = __nl_langinfo_l(__NEGATIVE_SIGN, __cloc);
|
||||
@ -467,8 +539,6 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
|
||||
__throw_exception_again;
|
||||
}
|
||||
|
||||
_M_data->_M_frac_digits = *(__nl_langinfo_l(__INT_FRAC_DIGITS,
|
||||
__cloc));
|
||||
char __pprecedes = *(__nl_langinfo_l(__INT_P_CS_PRECEDES, __cloc));
|
||||
char __pspace = *(__nl_langinfo_l(__INT_P_SEP_BY_SPACE, __cloc));
|
||||
char __pposn = *(__nl_langinfo_l(__INT_P_SIGN_POSN, __cloc));
|
||||
@ -507,6 +577,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
|
||||
_M_data->_M_thousands_sep = L',';
|
||||
_M_data->_M_grouping = "";
|
||||
_M_data->_M_grouping_size = 0;
|
||||
_M_data->_M_use_grouping = false;
|
||||
_M_data->_M_curr_symbol = L"";
|
||||
_M_data->_M_curr_symbol_size = 0;
|
||||
_M_data->_M_positive_sign = L"";
|
||||
@ -542,8 +613,32 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
|
||||
|
||||
__u.__s = __nl_langinfo_l(_NL_MONETARY_THOUSANDS_SEP_WC, __cloc);
|
||||
_M_data->_M_thousands_sep = __u.__w;
|
||||
|
||||
// Check for NULL, which implies no grouping.
|
||||
if (_M_data->_M_thousands_sep == L'\0')
|
||||
{
|
||||
// Like in "C" locale.
|
||||
_M_data->_M_grouping = "";
|
||||
_M_data->_M_grouping_size = 0;
|
||||
_M_data->_M_use_grouping = false;
|
||||
_M_data->_M_thousands_sep = L',';
|
||||
}
|
||||
else
|
||||
{
|
||||
_M_data->_M_grouping = __nl_langinfo_l(__MON_GROUPING, __cloc);
|
||||
_M_data->_M_grouping_size = strlen(_M_data->_M_grouping);
|
||||
}
|
||||
|
||||
// Check for NULL, which implies no fractional digits.
|
||||
if (_M_data->_M_decimal_point == L'\0')
|
||||
{
|
||||
// Like in "C" locale.
|
||||
_M_data->_M_frac_digits = 0;
|
||||
_M_data->_M_decimal_point = L'.';
|
||||
}
|
||||
else
|
||||
_M_data->_M_frac_digits = *(__nl_langinfo_l(__FRAC_DIGITS,
|
||||
__cloc));
|
||||
|
||||
const char* __cpossign = __nl_langinfo_l(__POSITIVE_SIGN, __cloc);
|
||||
const char* __cnegsign = __nl_langinfo_l(__NEGATIVE_SIGN, __cloc);
|
||||
@ -613,7 +708,6 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
|
||||
__throw_exception_again;
|
||||
}
|
||||
|
||||
_M_data->_M_frac_digits = *(__nl_langinfo_l(__FRAC_DIGITS, __cloc));
|
||||
char __pprecedes = *(__nl_langinfo_l(__P_CS_PRECEDES, __cloc));
|
||||
char __pspace = *(__nl_langinfo_l(__P_SEP_BY_SPACE, __cloc));
|
||||
char __pposn = *(__nl_langinfo_l(__P_SIGN_POSN, __cloc));
|
||||
|
@ -1,6 +1,7 @@
|
||||
// std::numpunct implementation details, GNU version -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
|
||||
// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
|
||||
// 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
|
||||
@ -71,11 +72,19 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
|
||||
|
||||
// Check for NULL, which implies no grouping.
|
||||
if (_M_data->_M_thousands_sep == '\0')
|
||||
{
|
||||
// Like in "C" locale.
|
||||
_M_data->_M_grouping = "";
|
||||
_M_data->_M_grouping_size = 0;
|
||||
_M_data->_M_use_grouping = false;
|
||||
_M_data->_M_thousands_sep = ',';
|
||||
}
|
||||
else
|
||||
{
|
||||
_M_data->_M_grouping = __nl_langinfo_l(GROUPING, __cloc);
|
||||
_M_data->_M_grouping_size = strlen(_M_data->_M_grouping);
|
||||
}
|
||||
}
|
||||
|
||||
// NB: There is no way to extact this info from posix locales.
|
||||
// _M_truename = __nl_langinfo_l(YESSTR, __cloc);
|
||||
@ -128,12 +137,21 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
|
||||
__u.__s = __nl_langinfo_l(_NL_NUMERIC_THOUSANDS_SEP_WC, __cloc);
|
||||
_M_data->_M_thousands_sep = __u.__w;
|
||||
|
||||
// Check for NULL, which implies no grouping.
|
||||
if (_M_data->_M_thousands_sep == L'\0')
|
||||
{
|
||||
// Like in "C" locale.
|
||||
_M_data->_M_grouping = "";
|
||||
_M_data->_M_grouping_size = 0;
|
||||
_M_data->_M_use_grouping = false;
|
||||
_M_data->_M_thousands_sep = L',';
|
||||
}
|
||||
else
|
||||
{
|
||||
_M_data->_M_grouping = __nl_langinfo_l(GROUPING, __cloc);
|
||||
_M_data->_M_grouping_size = strlen(_M_data->_M_grouping);
|
||||
}
|
||||
}
|
||||
|
||||
// NB: There is no way to extact this info from posix locales.
|
||||
// _M_truename = __nl_langinfo_l(YESSTR, __cloc);
|
||||
|
54
libstdc++-v3/testsuite/22_locale/locale/cons/38368.cc
Normal file
54
libstdc++-v3/testsuite/22_locale/locale/cons/38368.cc
Normal file
@ -0,0 +1,54 @@
|
||||
// { dg-require-namedlocale "" }
|
||||
|
||||
// Copyright (C) 2008 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++/38368
|
||||
void test01()
|
||||
{
|
||||
using namespace std;
|
||||
bool test __attribute__((unused)) = true;
|
||||
|
||||
locale loc(locale("C"), "en_US", locale::collate);
|
||||
locale loc_copy(loc.name().c_str());
|
||||
|
||||
const moneypunct<char, true>& mpunt =
|
||||
use_facet<moneypunct<char, true> >(loc_copy);
|
||||
VERIFY( mpunt.decimal_point() == '.' );
|
||||
VERIFY( mpunt.thousands_sep() == ',' );
|
||||
|
||||
const moneypunct<char, false>& mpunf =
|
||||
use_facet<moneypunct<char, false> >(loc_copy);
|
||||
VERIFY( mpunf.decimal_point() == '.' );
|
||||
VERIFY( mpunf.thousands_sep() == ',' );
|
||||
|
||||
const numpunct<char>& npun = use_facet<numpunct<char> >(loc_copy);
|
||||
VERIFY( npun.decimal_point() == '.' );
|
||||
VERIFY( npun.thousands_sep() == ',' );
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user