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

2003-12-31  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 thousands_sep, then for decimal_point and
	finally for digits.
	(num_get::_M_extract_float): After the decimal_point or
	'e'/'E', decimal_point and thousands_sep just break out the
	parsing loop.
	* testsuite/22_locale/num_get/get/char/11.cc: Add tests.
	* testsuite/22_locale/num_get/get/wchar_t/11.cc: Likewise.

From-SVN: r75259
This commit is contained in:
Paolo Carlini 2003-12-31 08:28:10 +00:00 committed by Paolo Carlini
parent f5cb6ca267
commit 4f0c9c8a87
4 changed files with 159 additions and 61 deletions

View File

@ -1,3 +1,15 @@
2003-12-31 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 thousands_sep, then for decimal_point and
finally for digits.
(num_get::_M_extract_float): After the decimal_point or
'e'/'E', decimal_point and thousands_sep just break out the
parsing loop.
* testsuite/22_locale/num_get/get/char/11.cc: Add tests.
* testsuite/22_locale/num_get/get/wchar_t/11.cc: Likewise.
2003-12-30 Paolo Carlini <pcarlini@suse.de>
PR libstdc++/13369

View File

@ -212,39 +212,47 @@ namespace std
const char_type* __p;
while (__beg != __end)
{
// According to 22.2.2.1.2, p8-9, first look for decimal_point
// and thousands_sep.
// According to 22.2.2.1.2, p8-9, first look for thousands_sep
// and decimal_point.
const char_type __c = *__beg;
if (__traits_type::eq(__c, __lc->_M_decimal_point)
&& !__found_dec && !__found_sci)
if (__lc->_M_use_grouping
&& __traits_type::eq(__c, __lc->_M_thousands_sep))
{
// According to the standard, if no grouping chars are seen,
// no grouping check is applied. Therefore __found_grouping
// must be adjusted only if __dec comes after some __sep.
if (__found_grouping.size())
__found_grouping += static_cast<char>(__sep_pos);
__xtrc += '.';
__found_dec = true;
++__beg;
}
else if (__lc->_M_use_grouping
&& __traits_type::eq(__c, __lc->_M_thousands_sep)
&& !__found_dec && !__found_sci)
{
// 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;
++__beg;
}
else
if (!__found_dec && !__found_sci)
{
__err |= ios_base::failbit;
break;
// 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;
++__beg;
}
else
{
__err |= ios_base::failbit;
break;
}
}
else
break;
}
else if (__traits_type::eq(__c, __lc->_M_decimal_point))
{
if (!__found_dec && !__found_sci)
{
// If no grouping chars are seen, no grouping check
// is applied. Therefore __found_grouping is adjusted
// only if decimal_point comes after some thousands_sep.
if (__found_grouping.size())
__found_grouping += static_cast<char>(__sep_pos);
__xtrc += '.';
__found_dec = true;
++__beg;
}
else
break;
}
else if (__p = __traits_type::find(__lit + _S_izero, 10, __c))
{
__xtrc += _S_atoms_in[__p - __lit];
@ -385,13 +393,11 @@ namespace std
const _ValueT __min = numeric_limits<_ValueT>::min() / __base;
for (; __beg != __end; ++__beg)
{
// According to 22.2.2.1.2, p8-9, first look for decimal_point
// and thousands_sep.
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))
// According to 22.2.2.1.2, p8-9, first look for thousands_sep
// and decimal_point.
const char_type __c = *__beg;
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.
@ -406,6 +412,8 @@ namespace std
break;
}
}
else if (__traits_type::eq(__c, __lc->_M_decimal_point))
break;
else if (__p = __traits_type::find(__lit_zero, __len, __c))
{
int __digit = __p - __lit_zero;
@ -432,11 +440,9 @@ namespace std
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
&& __traits_type::eq(__c, __lc->_M_thousands_sep))
const char_type __c = *__beg;
if (__lc->_M_use_grouping
&& __traits_type::eq(__c, __lc->_M_thousands_sep))
{
if (__sep_pos)
{
@ -448,7 +454,9 @@ namespace std
__err |= ios_base::failbit;
break;
}
}
}
else if (__traits_type::eq(__c, __lc->_M_decimal_point))
break;
else if (__p = __traits_type::find(__lit_zero, __len, __c))
{
int __digit = __p - __lit_zero;

View File

@ -22,13 +22,20 @@
#include <sstream>
#include <testsuite_hooks.h>
struct Punct: std::numpunct<char>
struct Punct1: std::numpunct<char>
{
std::string do_grouping() const { return "\1"; }
char do_thousands_sep() const { return '2'; }
char do_decimal_point() const { return '4'; }
};
struct Punct2: std::numpunct<char>
{
std::string do_grouping() const { return "\1"; }
char do_thousands_sep() const { return '2'; }
char do_decimal_point() const { return '2'; }
};
// http://gcc.gnu.org/ml/libstdc++/2003-12/msg00201.html
void test01()
{
@ -37,30 +44,62 @@ void test01()
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());
istringstream iss1, iss2;
iss1.imbue(locale(iss1.getloc(), static_cast<numpunct<char>*>(new Punct1)));
iss2.imbue(locale(iss2.getloc(), static_cast<numpunct<char>*>(new Punct2)));
const num_get<char>& ng1 = use_facet<num_get<char> >(iss1.getloc());
const num_get<char>& ng2 = use_facet<num_get<char> >(iss2.getloc());
ios_base::iostate err = ios_base::goodbit;
iterator_type end;
double d = 0.0;
double d1 = 13.0;
double d2 = 1.0;
double d3 = 30.0;
long l = 0l;
long l1 = 13l;
long l2 = 10l;
iss.str("1234");
iss1.str("1234");
err = ios_base::goodbit;
end = ng.get(iss.rdbuf(), 0, iss, err, d);
end = ng1.get(iss1.rdbuf(), 0, iss1, err, d);
VERIFY( err == ios_base::eofbit );
VERIFY( d == d1 );
iss.str("1234");
iss.clear();
iss1.str("142");
iss1.clear();
err = ios_base::goodbit;
end = ng.get(iss.rdbuf(), 0, iss, err, l);
end = ng1.get(iss1.rdbuf(), 0, iss1, err, d);
VERIFY( err == ios_base::goodbit );
VERIFY( d == d2 );
iss1.str("3e14");
iss1.clear();
err = ios_base::goodbit;
end = ng1.get(iss1.rdbuf(), 0, iss1, err, d);
VERIFY( err == ios_base::goodbit );
VERIFY( d == d3 );
iss1.str("1234");
iss1.clear();
err = ios_base::goodbit;
end = ng1.get(iss1.rdbuf(), 0, iss1, err, l);
VERIFY( err == ios_base::goodbit );
VERIFY( l == l1 );
}
iss2.str("123");
err = ios_base::goodbit;
end = ng2.get(iss2.rdbuf(), 0, iss2, err, d);
VERIFY( err == ios_base::eofbit );
VERIFY( d == d1 );
iss2.str("120");
iss2.clear();
err = ios_base::goodbit;
end = ng2.get(iss2.rdbuf(), 0, iss2, err, l);
VERIFY( err == ios_base::eofbit );
VERIFY( l == l2 );
}
int main()
{

View File

@ -22,13 +22,20 @@
#include <sstream>
#include <testsuite_hooks.h>
struct Punct: std::numpunct<wchar_t>
struct Punct1: 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'; }
};
struct Punct2: 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'2'; }
};
// http://gcc.gnu.org/ml/libstdc++/2003-12/msg00201.html
void test01()
{
@ -37,30 +44,62 @@ void test01()
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());
wistringstream iss1, iss2;
iss1.imbue(locale(iss1.getloc(), static_cast<numpunct<wchar_t>*>(new Punct1)));
iss2.imbue(locale(iss2.getloc(), static_cast<numpunct<wchar_t>*>(new Punct2)));
const num_get<wchar_t>& ng1 = use_facet<num_get<wchar_t> >(iss1.getloc());
const num_get<wchar_t>& ng2 = use_facet<num_get<wchar_t> >(iss2.getloc());
ios_base::iostate err = ios_base::goodbit;
iterator_type end;
double d = 0.0;
double d1 = 13.0;
double d2 = 1.0;
double d3 = 30.0;
long l = 0l;
long l1 = 13l;
long l2 = 10l;
iss.str(L"1234");
iss1.str(L"1234");
err = ios_base::goodbit;
end = ng.get(iss.rdbuf(), 0, iss, err, d);
end = ng1.get(iss1.rdbuf(), 0, iss1, err, d);
VERIFY( err == ios_base::eofbit );
VERIFY( d == d1 );
iss.str(L"1234");
iss.clear();
iss1.str(L"142");
iss1.clear();
err = ios_base::goodbit;
end = ng.get(iss.rdbuf(), 0, iss, err, l);
end = ng1.get(iss1.rdbuf(), 0, iss1, err, d);
VERIFY( err == ios_base::goodbit );
VERIFY( d == d2 );
iss1.str(L"3e14");
iss1.clear();
err = ios_base::goodbit;
end = ng1.get(iss1.rdbuf(), 0, iss1, err, d);
VERIFY( err == ios_base::goodbit );
VERIFY( d == d3 );
iss1.str(L"1234");
iss1.clear();
err = ios_base::goodbit;
end = ng1.get(iss1.rdbuf(), 0, iss1, err, l);
VERIFY( err == ios_base::goodbit );
VERIFY( l == l1 );
}
iss2.str(L"123");
err = ios_base::goodbit;
end = ng2.get(iss2.rdbuf(), 0, iss2, err, d);
VERIFY( err == ios_base::eofbit );
VERIFY( d == d1 );
iss2.str(L"120");
iss2.clear();
err = ios_base::goodbit;
end = ng2.get(iss2.rdbuf(), 0, iss2, err, l);
VERIFY( err == ios_base::eofbit );
VERIFY( l == l2 );
}
int main()
{