This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
Re: [RFC] Doubts about digit grouping corner cases
- From: Paolo Carlini <pcarlini at suse dot de>
- To: Paolo Carlini <pcarlini at suse dot de>
- Cc: libstdc++ <libstdc++ at gcc dot gnu dot org>, Nathan Myers <ncm at cantrip dot org>
- Date: Sat, 03 Jan 2004 20:49:03 +0100
- Subject: Re: [RFC] Doubts about digit grouping corner cases
- References: <3FF6ABD1.6040504@suse.de>
Paolo Carlini wrote:
It seems to me that we could deal easily - and in a strictly conforming
way - with __sep_pos == 0 in __verify_grouping, thus simplifying the
Stage2 parsing loop.
For concreteness, the below is what I have in mind (+ the corresponding
tweaks to a few testcases and a consistent change to money_get::do_get,
which also uses __verify_grouping).
Paolo.
/////////////
diff -urN libstdc++-v3-orig/include/bits/locale_facets.tcc libstdc++-v3/include/bits/locale_facets.tcc
--- libstdc++-v3-orig/include/bits/locale_facets.tcc 2003-12-31 09:28:08.000000000 +0100
+++ libstdc++-v3/include/bits/locale_facets.tcc 2004-01-03 18:49:56.000000000 +0100
@@ -209,6 +209,7 @@
string __found_grouping;
int __sep_pos = 0;
bool __e;
+ const char_type* __lit_zero = __lit + _S_izero;
const char_type* __p;
while (__beg != __end)
{
@@ -220,19 +221,9 @@
{
if (!__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
- {
- __err |= ios_base::failbit;
- break;
- }
+ __found_grouping += static_cast<char>(__sep_pos);
+ __sep_pos = 0;
+ ++__beg;
}
else
break;
@@ -253,7 +244,7 @@
else
break;
}
- else if (__p = __traits_type::find(__lit + _S_izero, 10, __c))
+ else if (__p = __traits_type::find(__lit_zero, 10, __c))
{
__xtrc += _S_atoms_in[__p - __lit];
__found_mantissa = true;
@@ -399,18 +390,8 @@
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;
- }
+ __found_grouping += static_cast<char>(__sep_pos);
+ __sep_pos = 0;
}
else if (__traits_type::eq(__c, __lc->_M_decimal_point))
break;
@@ -444,16 +425,8 @@
if (__lc->_M_use_grouping
&& __traits_type::eq(__c, __lc->_M_thousands_sep))
{
- if (__sep_pos)
- {
- __found_grouping += static_cast<char>(__sep_pos);
- __sep_pos = 0;
- }
- else
- {
- __err |= ios_base::failbit;
- break;
- }
+ __found_grouping += static_cast<char>(__sep_pos);
+ __sep_pos = 0;
}
else if (__traits_type::eq(__c, __lc->_M_decimal_point))
break;
@@ -1245,23 +1218,21 @@
}
else if (__c == __d && !__testdecfound)
{
- __grouping_tmp += static_cast<char>(__sep_pos);
+ if (__grouping_tmp.size())
+ __grouping_tmp += static_cast<char>(__sep_pos);
__sep_pos = 0;
__testdecfound = true;
}
- else if (__c == __sep)
+ else if (__grouping.size() && __c == __sep)
{
- if (__grouping.size())
+ if (!__testdecfound)
{
// Mark position for later analysis.
__grouping_tmp += static_cast<char>(__sep_pos);
__sep_pos = 0;
}
else
- {
- __testvalid = false;
- break;
- }
+ break;
}
else
break;
@@ -2286,7 +2257,8 @@
__test = __grouping_tmp[__i] == __grouping[__min];
// ... but the last parsed grouping can be <= numpunct
// grouping.
- __test &= __grouping_tmp[0] <= __grouping[__min];
+ __test &= __grouping_tmp[0]
+ && __grouping_tmp[0] <= __grouping[__min];
return __test;
}
diff -urN libstdc++-v3-orig/testsuite/22_locale/num_get/get/char/12.cc libstdc++-v3/testsuite/22_locale/num_get/get/char/12.cc
--- libstdc++-v3-orig/testsuite/22_locale/num_get/get/char/12.cc 2003-12-22 12:00:42.000000000 +0100
+++ libstdc++-v3/testsuite/22_locale/num_get/get/char/12.cc 2004-01-03 19:17:09.000000000 +0100
@@ -66,8 +66,7 @@
iss1.str("+3");
err = ios_base::goodbit;
end = ng1.get(iss1.rdbuf(), 0, iss1, err, l);
- VERIFY( err == ios_base::failbit );
- VERIFY( *end == '+' );
+ VERIFY( err == (ios_base::failbit | ios_base::eofbit) );
iss1.str("0x1");
iss1.clear();
@@ -97,8 +96,7 @@
iss1.clear();
err = ios_base::goodbit;
end = ng1.get(iss1.rdbuf(), 0, iss1, err, d);
- VERIFY( err == ios_base::failbit );
- VERIFY( *end == '+' );
+ VERIFY( err == (ios_base::failbit | ios_base::eofbit) );
iss1.str("x4");
iss1.clear();
@@ -126,8 +124,7 @@
iss2.unsetf(ios::basefield);
err = ios_base::goodbit;
end = ng2.get(iss2.rdbuf(), 0, iss2, err, l);
- VERIFY( err == ios_base::failbit );
- VERIFY( *end == 'X' );
+ VERIFY( err == (ios_base::failbit | ios_base::eofbit) );
iss2.str("000778");
iss2.clear();
@@ -141,8 +138,7 @@
iss2.clear();
err = ios_base::goodbit;
end = ng2.get(iss2.rdbuf(), 0, iss2, err, d);
- VERIFY( err == ios_base::failbit );
- VERIFY( *end == 'X' );
+ VERIFY( err == (ios_base::failbit | ios_base::eofbit) );
iss2.str("-1");
iss2.clear();
diff -urN libstdc++-v3-orig/testsuite/22_locale/num_get/get/wchar_t/12.cc libstdc++-v3/testsuite/22_locale/num_get/get/wchar_t/12.cc
--- libstdc++-v3-orig/testsuite/22_locale/num_get/get/wchar_t/12.cc 2003-12-22 12:00:42.000000000 +0100
+++ libstdc++-v3/testsuite/22_locale/num_get/get/wchar_t/12.cc 2004-01-03 19:28:44.000000000 +0100
@@ -66,8 +66,7 @@
iss1.str(L"+3");
err = ios_base::goodbit;
end = ng1.get(iss1.rdbuf(), 0, iss1, err, l);
- VERIFY( err == ios_base::failbit );
- VERIFY( *end == L'+' );
+ VERIFY( err == (ios_base::failbit | ios_base::eofbit) );
iss1.str(L"0x1");
iss1.clear();
@@ -97,8 +96,7 @@
iss1.clear();
err = ios_base::goodbit;
end = ng1.get(iss1.rdbuf(), 0, iss1, err, d);
- VERIFY( err == ios_base::failbit );
- VERIFY( *end == L'+' );
+ VERIFY( err == (ios_base::failbit | ios_base::eofbit) );
iss1.str(L"x4");
iss1.clear();
@@ -126,8 +124,7 @@
iss2.unsetf(ios::basefield);
err = ios_base::goodbit;
end = ng2.get(iss2.rdbuf(), 0, iss2, err, l);
- VERIFY( err == ios_base::failbit );
- VERIFY( *end == L'X' );
+ VERIFY( err == (ios_base::failbit | ios_base::eofbit) );
iss2.str(L"000778");
iss2.clear();
@@ -141,8 +138,7 @@
iss2.clear();
err = ios_base::goodbit;
end = ng2.get(iss2.rdbuf(), 0, iss2, err, d);
- VERIFY( err == ios_base::failbit );
- VERIFY( *end == L'X' );
+ VERIFY( err == (ios_base::failbit | ios_base::eofbit) );
iss2.str(L"-1");
iss2.clear();
diff -urN libstdc++-v3-orig/testsuite/27_io/basic_istream/extractors_arithmetic/char/07.cc libstdc++-v3/testsuite/27_io/basic_istream/extractors_arithmetic/char/07.cc
--- libstdc++-v3-orig/testsuite/27_io/basic_istream/extractors_arithmetic/char/07.cc 2003-09-23 22:03:06.000000000 +0200
+++ libstdc++-v3/testsuite/27_io/basic_istream/extractors_arithmetic/char/07.cc 2004-01-03 18:03:16.000000000 +0100
@@ -20,9 +20,7 @@
// 27.6.1.2.2 arithmetic extractors
-#include <cstdio> // for printf
#include <istream>
-#include <ostream>
#include <sstream>
#include <locale>
#include <testsuite_hooks.h>
@@ -100,20 +98,11 @@
VERIFY( h4 == 0 );
VERIFY( static_cast<bool>(is.rdstate() & std::ios_base::failbit) );
is.clear();
- is >> c;
- VERIFY( c == ',' );
- VERIFY( is.good() );
- is.ignore(3);
is >> f1;
VERIFY( f1 == 0.0 );
VERIFY( static_cast<bool>(is.rdstate() & std::ios_base::failbit) );
is.clear();
- is >> c;
- VERIFY( c == ',' );
- is >> c;
- VERIFY( c == '4' );
- VERIFY( is.good() );
is >> f1;
VERIFY( f1 == 0.25 );
@@ -137,9 +126,6 @@
VERIFY( h3 == 0 );
VERIFY( static_cast<bool>(is.rdstate() & std::ios_base::failbit) );
is.clear();
- is >> c;
- VERIFY( c == ',' ); // second one
- VERIFY( is.good() );
is >> h2;
VERIFY( h2 == 0 );