Commit cc16f8b9 by Paolo Carlini Committed by Paolo Carlini

locale_facets.tcc (num_get::_M_extract_int, [...]): According to 22.2.2.1.2,…

locale_facets.tcc (num_get::_M_extract_int, [...]): According to 22.2.2.1.2, p8-9, first look for decimal_point and thousands_sep.

2003-12-19  Paolo Carlini  <pcarlini@suse.de>

	* include/bits/locale_facets.tcc (num_get::_M_extract_int,
	num_get::_M_extract_float): According to 22.2.2.1.2, p8-9,
	first look for decimal_point and thousands_sep.
	* testsuite/22_locale/num_get/get/char/11.cc: New.
	* testsuite/22_locale/num_get/get/wchar_t/11.cc: Likewise.

From-SVN: r74841
parent 9175d628
2003-12-19 Paolo Carlini <pcarlini@suse.de> 2003-12-19 Paolo Carlini <pcarlini@suse.de>
* include/bits/locale_facets.tcc (num_get::_M_extract_int,
num_get::_M_extract_float): According to 22.2.2.1.2, p8-9,
first look for decimal_point and thousands_sep.
* testsuite/22_locale/num_get/get/char/11.cc: New.
* testsuite/22_locale/num_get/get/wchar_t/11.cc: Likewise.
2003-12-19 Paolo Carlini <pcarlini@suse.de>
* include/bits/locale_facets.tcc (num_get::_M_extract_float): * include/bits/locale_facets.tcc (num_get::_M_extract_float):
When __found_sci becomes true stop eating thousands separators When __found_sci becomes true stop eating thousands separators
and the decimal radix separator. and the decimal radix separator.
......
...@@ -169,18 +169,22 @@ namespace std ...@@ -169,18 +169,22 @@ namespace std
string __found_grouping; string __found_grouping;
int __sep_pos = 0; int __sep_pos = 0;
bool __e; bool __e;
const char_type* __p;
while (__beg != __end) while (__beg != __end)
{ {
// Only look in digits. // According to 22.2.2.1.2, p8-9, first look for decimal_point
// and thousands_sep.
const char_type __c = *__beg; const char_type __c = *__beg;
const char_type* __p = __traits_type::find(__lit + _S_izero, 10, if (__traits_type::eq(__c, __lc->_M_decimal_point)
__c); && !__found_dec && !__found_sci)
if (__p)
{ {
// Try first for acceptable digit; record it if found. // According to the standard, if no grouping chars are seen,
__xtrc += _S_atoms_in[__p - __lit]; // no grouping check is applied. Therefore __found_grouping
__found_mantissa = true; // must be adjusted only if __dec comes after some __sep.
++__sep_pos; if (__found_grouping.size())
__found_grouping += static_cast<char>(__sep_pos);
__xtrc += '.';
__found_dec = true;
++__beg; ++__beg;
} }
else if (__lc->_M_use_grouping else if (__lc->_M_use_grouping
...@@ -201,16 +205,11 @@ namespace std ...@@ -201,16 +205,11 @@ namespace std
break; break;
} }
} }
else if (__traits_type::eq(__c, __lc->_M_decimal_point) else if (__p = __traits_type::find(__lit + _S_izero, 10, __c))
&& !__found_dec && !__found_sci)
{ {
// According to the standard, if no grouping chars are seen, __xtrc += _S_atoms_in[__p - __lit];
// no grouping check is applied. Therefore __found_grouping __found_mantissa = true;
// must be adjusted only if __dec comes after some __sep. ++__sep_pos;
if (__found_grouping.size())
__found_grouping += static_cast<char>(__sep_pos);
__xtrc += '.';
__found_dec = true;
++__beg; ++__beg;
} }
else if ((__e = __traits_type::eq(__c, __lit[_S_ie]) else if ((__e = __traits_type::eq(__c, __lit[_S_ie])
...@@ -337,14 +336,34 @@ namespace std ...@@ -337,14 +336,34 @@ namespace std
bool __overflow = false; bool __overflow = false;
_ValueT __result = 0; _ValueT __result = 0;
const char_type* __lit_zero = __lit + _S_izero; const char_type* __lit_zero = __lit + _S_izero;
const char_type* __p;
if (__negative) if (__negative)
{ {
const _ValueT __min = numeric_limits<_ValueT>::min() / __base; const _ValueT __min = numeric_limits<_ValueT>::min() / __base;
for (; __beg != __end; ++__beg) for (; __beg != __end; ++__beg)
{ {
const char_type* __p = __traits_type::find(__lit_zero, // According to 22.2.2.1.2, p8-9, first look for decimal_point
__len, *__beg); // and thousands_sep.
if (__p) const char_type __c = *__beg;
if (__traits_type::eq(__c, __lc->_M_decimal_point))
break;
else if (__lc->_M_use_grouping
&& __traits_type::eq(__c, __lc->_M_thousands_sep))
{
// NB: Thousands separator at the beginning of a string
// is a no-no, as is two consecutive thousands separators.
if (__sep_pos)
{
__found_grouping += static_cast<char>(__sep_pos);
__sep_pos = 0;
}
else
{
__err |= ios_base::failbit;
break;
}
}
else if (__p = __traits_type::find(__lit_zero, __len, __c))
{ {
int __digit = __p - __lit_zero; int __digit = __p - __lit_zero;
if (__digit > 15) if (__digit > 15)
...@@ -360,11 +379,22 @@ namespace std ...@@ -360,11 +379,22 @@ namespace std
__found_num = true; __found_num = true;
} }
} }
else
// Not a valid input item.
break;
}
}
else
{
const _ValueT __max = numeric_limits<_ValueT>::max() / __base;
for (; __beg != __end; ++__beg)
{
const char_type __c = *__beg;
if (__traits_type::eq(__c, __lc->_M_decimal_point))
break;
else if (__lc->_M_use_grouping else if (__lc->_M_use_grouping
&& __traits_type::eq(*__beg, __lc->_M_thousands_sep)) && __traits_type::eq(__c, __lc->_M_thousands_sep))
{ {
// NB: Thousands separator at the beginning of a string
// is a no-no, as is two consecutive thousands separators.
if (__sep_pos) if (__sep_pos)
{ {
__found_grouping += static_cast<char>(__sep_pos); __found_grouping += static_cast<char>(__sep_pos);
...@@ -376,19 +406,7 @@ namespace std ...@@ -376,19 +406,7 @@ namespace std
break; break;
} }
} }
else else if (__p = __traits_type::find(__lit_zero, __len, __c))
// Not a valid input item.
break;
}
}
else
{
const _ValueT __max = numeric_limits<_ValueT>::max() / __base;
for (; __beg != __end; ++__beg)
{
const char_type* __p = __traits_type::find(__lit_zero,
__len, *__beg);
if (__p)
{ {
int __digit = __p - __lit_zero; int __digit = __p - __lit_zero;
if (__digit > 15) if (__digit > 15)
...@@ -404,20 +422,6 @@ namespace std ...@@ -404,20 +422,6 @@ namespace std
__found_num = true; __found_num = true;
} }
} }
else if (__lc->_M_use_grouping
&& __traits_type::eq(*__beg, __lc->_M_thousands_sep))
{
if (__sep_pos)
{
__found_grouping += static_cast<char>(__sep_pos);
__sep_pos = 0;
}
else
{
__err |= ios_base::failbit;
break;
}
}
else else
break; break;
} }
......
// Copyright (C) 2003 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 22.2.2.1.1 num_get members
#include <locale>
#include <sstream>
#include <testsuite_hooks.h>
struct Punct: std::numpunct<char>
{
std::string do_grouping() const { return "\1"; }
char do_thousands_sep() const { return '2'; }
char do_decimal_point() const { return '4'; }
};
void test01()
{
using namespace std;
typedef istreambuf_iterator<char> iterator_type;
bool test __attribute__((unused)) = true;
istringstream iss;
iss.imbue(locale(iss.getloc(), static_cast<numpunct<char>*>(new Punct)));
const num_get<char>& ng = use_facet<num_get<char> >(iss.getloc());
ios_base::iostate err = ios_base::goodbit;
iterator_type end;
double d = 0.0;
double d1 = 13.0;
long l = 0l;
long l1 = 13l;
iss.str("1234");
err = ios_base::goodbit;
end = ng.get(iss.rdbuf(), 0, iss, err, d);
VERIFY( err == ios_base::eofbit );
VERIFY( d == d1 );
iss.str("1234");
iss.clear();
err = ios_base::goodbit;
end = ng.get(iss.rdbuf(), 0, iss, err, l);
VERIFY( err == ios_base::goodbit );
VERIFY( l == l1 );
}
int main()
{
test01();
return 0;
}
// Copyright (C) 2003 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 22.2.2.1.1 num_get members
#include <locale>
#include <sstream>
#include <testsuite_hooks.h>
struct Punct: std::numpunct<wchar_t>
{
std::string do_grouping() const { return "\1"; }
wchar_t do_thousands_sep() const { return L'2'; }
wchar_t do_decimal_point() const { return L'4'; }
};
void test01()
{
using namespace std;
typedef istreambuf_iterator<wchar_t> iterator_type;
bool test __attribute__((unused)) = true;
wistringstream iss;
iss.imbue(locale(iss.getloc(), static_cast<numpunct<wchar_t>*>(new Punct)));
const num_get<wchar_t>& ng = use_facet<num_get<wchar_t> >(iss.getloc());
ios_base::iostate err = ios_base::goodbit;
iterator_type end;
double d = 0.0;
double d1 = 13.0;
long l = 0l;
long l1 = 13l;
iss.str(L"1234");
err = ios_base::goodbit;
end = ng.get(iss.rdbuf(), 0, iss, err, d);
VERIFY( err == ios_base::eofbit );
VERIFY( d == d1 );
iss.str(L"1234");
iss.clear();
err = ios_base::goodbit;
end = ng.get(iss.rdbuf(), 0, iss, err, l);
VERIFY( err == ios_base::goodbit );
VERIFY( l == l1 );
}
int main()
{
test01();
return 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment