mirror of git://gcc.gnu.org/git/gcc.git
[multiple changes]
2001-12-06 Benjamin Kosnik <bkoz@redhat.com> libstdc++/3720 * include/bits/locale_facets.tcc (num_put): Clean. (num_get::_M_extract_float): Change argument to string. (num_get::do_get(float)): Fixup. (num_get::do_get(double)): Same. (num_get::do_get(long double)): Same. (num_get::_M_extract_int): Add maximum length parameter, __max. (num_get::_M_extract_float): Correct zeros, use string. * include/bits/locale_facets.h (num_get::_M_extract_float): Change declaration here. * src/locale.cc (__num_base::_S_atoms): Remove x, X. * testsuite/27_io/istream_extractor_arith.cc (test13): Add. 2001-12-06 Philip Martin <pmartin@uklinux.net> * testsuite/27_io/istream_extractor_arith.cc (test12): Add tests for excess input digits. From-SVN: r47743
This commit is contained in:
parent
a2b1e91459
commit
823b4f7daa
|
|
@ -1,3 +1,23 @@
|
||||||
|
2001-12-06 Benjamin Kosnik <bkoz@redhat.com>
|
||||||
|
|
||||||
|
libstdc++/3720
|
||||||
|
* include/bits/locale_facets.tcc (num_put): Clean.
|
||||||
|
(num_get::_M_extract_float): Change argument to string.
|
||||||
|
(num_get::do_get(float)): Fixup.
|
||||||
|
(num_get::do_get(double)): Same.
|
||||||
|
(num_get::do_get(long double)): Same.
|
||||||
|
(num_get::_M_extract_int): Add maximum length parameter, __max.
|
||||||
|
(num_get::_M_extract_float): Correct zeros, use string.
|
||||||
|
* include/bits/locale_facets.h (num_get::_M_extract_float): Change
|
||||||
|
declaration here.
|
||||||
|
* src/locale.cc (__num_base::_S_atoms): Remove x, X.
|
||||||
|
* testsuite/27_io/istream_extractor_arith.cc (test13): Add.
|
||||||
|
|
||||||
|
2001-12-06 Philip Martin <pmartin@uklinux.net>
|
||||||
|
|
||||||
|
* testsuite/27_io/istream_extractor_arith.cc (test12): Add
|
||||||
|
tests for excess input digits.
|
||||||
|
|
||||||
2001-12-06 Phil Edwards <pme@gcc.gnu.org>
|
2001-12-06 Phil Edwards <pme@gcc.gnu.org>
|
||||||
|
|
||||||
* include/bits/std_bitset.h: Use GLIBCPP in multiple-inclusion guard.
|
* include/bits/std_bitset.h: Use GLIBCPP in multiple-inclusion guard.
|
||||||
|
|
@ -42,7 +62,7 @@
|
||||||
2001-12-04 Paolo Carlini <pcarlini@unitus.it>
|
2001-12-04 Paolo Carlini <pcarlini@unitus.it>
|
||||||
|
|
||||||
libstdc++/4402
|
libstdc++/4402
|
||||||
* testsuite/27_io/ostream_inserter_arith.cc (test02): add testcase
|
* testsuite/27_io/ostream_inserter_arith.cc (test02): Add testcase
|
||||||
from the PR.
|
from the PR.
|
||||||
* include/bits/locale_facets.tcc (num_put::_M_convert_float):
|
* include/bits/locale_facets.tcc (num_put::_M_convert_float):
|
||||||
Deal properly with long ios_base::fixed floats.
|
Deal properly with long ios_base::fixed floats.
|
||||||
|
|
|
||||||
|
|
@ -420,7 +420,7 @@ namespace std
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// String literal of acceptable (narrow) input, for num_get.
|
// String literal of acceptable (narrow) input, for num_get.
|
||||||
// "0123456789eEabcdfxABCDFX"
|
// "0123456789eEabcdfABCDF"
|
||||||
static const char _S_atoms[];
|
static const char _S_atoms[];
|
||||||
|
|
||||||
enum
|
enum
|
||||||
|
|
@ -428,7 +428,7 @@ namespace std
|
||||||
_M_zero,
|
_M_zero,
|
||||||
_M_e = _M_zero + 10,
|
_M_e = _M_zero + 10,
|
||||||
_M_E = _M_zero + 11,
|
_M_E = _M_zero + 11,
|
||||||
_M_size = 23 + 1
|
_M_size = 21 + 1
|
||||||
};
|
};
|
||||||
|
|
||||||
// Construct and return valid scanf format for floating point types.
|
// Construct and return valid scanf format for floating point types.
|
||||||
|
|
@ -634,11 +634,11 @@ namespace std
|
||||||
|
|
||||||
void
|
void
|
||||||
_M_extract_float(iter_type, iter_type, ios_base&, ios_base::iostate&,
|
_M_extract_float(iter_type, iter_type, ios_base&, ios_base::iostate&,
|
||||||
char* __xtrc) const;
|
string& __xtrc) const;
|
||||||
|
|
||||||
void
|
void
|
||||||
_M_extract_int(iter_type, iter_type, ios_base&, ios_base::iostate&,
|
_M_extract_int(iter_type, iter_type, ios_base&, ios_base::iostate&,
|
||||||
char* __xtrc, int& __base) const;
|
char* __xtrc, int __max, int& __base) const;
|
||||||
|
|
||||||
virtual iter_type
|
virtual iter_type
|
||||||
do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, bool&) const;
|
do_get(iter_type, iter_type, ios_base&, ios_base::iostate&, bool&) const;
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,7 @@
|
||||||
#include <bits/std_cerrno.h>
|
#include <bits/std_cerrno.h>
|
||||||
#include <bits/std_clocale.h> // For localeconv
|
#include <bits/std_clocale.h> // For localeconv
|
||||||
#include <bits/std_cstdlib.h> // For strof, strtold
|
#include <bits/std_cstdlib.h> // For strof, strtold
|
||||||
|
#include <bits/std_cmath.h> // For ceil
|
||||||
#include <bits/std_limits.h> // For numeric_limits
|
#include <bits/std_limits.h> // For numeric_limits
|
||||||
#include <bits/std_memory.h> // For auto_ptr
|
#include <bits/std_memory.h> // For auto_ptr
|
||||||
#include <bits/streambuf_iterator.h> // For streambuf_iterators
|
#include <bits/streambuf_iterator.h> // For streambuf_iterators
|
||||||
|
|
@ -90,20 +91,21 @@ namespace std
|
||||||
void
|
void
|
||||||
num_get<_CharT, _InIter>::
|
num_get<_CharT, _InIter>::
|
||||||
_M_extract_float(_InIter __beg, _InIter __end, ios_base& __io,
|
_M_extract_float(_InIter __beg, _InIter __end, ios_base& __io,
|
||||||
ios_base::iostate& __err, char* __xtrc) const
|
ios_base::iostate& __err, string& __xtrc) const
|
||||||
{
|
{
|
||||||
const locale __loc = __io.getloc();
|
const locale __loc = __io.getloc();
|
||||||
const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
|
const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
|
||||||
const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
|
const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
|
||||||
int __pos = 0;
|
|
||||||
char_type __c = *__beg;
|
|
||||||
|
|
||||||
// Check first for sign.
|
// Check first for sign.
|
||||||
const char_type __plus = __ctype.widen('+');
|
const char_type __plus = __ctype.widen('+');
|
||||||
const char_type __minus = __ctype.widen('-');
|
const char_type __minus = __ctype.widen('-');
|
||||||
|
int __pos = 0;
|
||||||
|
char_type __c = *__beg;
|
||||||
if ((__c == __plus || __c == __minus) && __beg != __end)
|
if ((__c == __plus || __c == __minus) && __beg != __end)
|
||||||
{
|
{
|
||||||
__xtrc[__pos++] = __ctype.narrow(__c, char());
|
__xtrc += __ctype.narrow(__c, char());
|
||||||
|
++__pos;
|
||||||
__c = *(++__beg);
|
__c = *(++__beg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -116,7 +118,10 @@ namespace std
|
||||||
__found_zero = true;
|
__found_zero = true;
|
||||||
}
|
}
|
||||||
if (__found_zero)
|
if (__found_zero)
|
||||||
__xtrc[__pos++] = _S_atoms[_M_zero];
|
{
|
||||||
|
__xtrc += _S_atoms[_M_zero];
|
||||||
|
++__pos;
|
||||||
|
}
|
||||||
|
|
||||||
// Only need acceptable digits for floating point numbers.
|
// Only need acceptable digits for floating point numbers.
|
||||||
const size_t __len = _M_E - _M_zero + 1;
|
const size_t __len = _M_E - _M_zero + 1;
|
||||||
|
|
@ -142,7 +147,8 @@ namespace std
|
||||||
if (__p && __c)
|
if (__p && __c)
|
||||||
{
|
{
|
||||||
// Try first for acceptable digit; record it if found.
|
// Try first for acceptable digit; record it if found.
|
||||||
__xtrc[__pos++] = _S_atoms[__p - __watoms];
|
++__pos;
|
||||||
|
__xtrc += _S_atoms[__p - __watoms];
|
||||||
++__sep_pos;
|
++__sep_pos;
|
||||||
__c = *(++__beg);
|
__c = *(++__beg);
|
||||||
}
|
}
|
||||||
|
|
@ -165,7 +171,8 @@ namespace std
|
||||||
else if (__c == __dec && !__found_dec)
|
else if (__c == __dec && !__found_dec)
|
||||||
{
|
{
|
||||||
__found_grouping += static_cast<char>(__sep_pos);
|
__found_grouping += static_cast<char>(__sep_pos);
|
||||||
__xtrc[__pos++] = '.';
|
++__pos;
|
||||||
|
__xtrc += '.';
|
||||||
__c = *(++__beg);
|
__c = *(++__beg);
|
||||||
__found_dec = true;
|
__found_dec = true;
|
||||||
}
|
}
|
||||||
|
|
@ -173,13 +180,15 @@ namespace std
|
||||||
&& !__found_sci && __pos)
|
&& !__found_sci && __pos)
|
||||||
{
|
{
|
||||||
// Scientific notation.
|
// Scientific notation.
|
||||||
__xtrc[__pos++] = __ctype.narrow(__c, char());
|
++__pos;
|
||||||
|
__xtrc += __ctype.narrow(__c, char());
|
||||||
__c = *(++__beg);
|
__c = *(++__beg);
|
||||||
|
|
||||||
// Remove optional plus or minus sign, if they exist.
|
// Remove optional plus or minus sign, if they exist.
|
||||||
if (__c == __plus || __c == __minus)
|
if (__c == __plus || __c == __minus)
|
||||||
{
|
{
|
||||||
__xtrc[__pos++] = __ctype.narrow(__c, char());
|
++__pos;
|
||||||
|
__xtrc += __ctype.narrow(__c, char());
|
||||||
__c = *(++__beg);
|
__c = *(++__beg);
|
||||||
}
|
}
|
||||||
__found_sci = true;
|
__found_sci = true;
|
||||||
|
|
@ -196,19 +205,12 @@ namespace std
|
||||||
// Add the ending grouping if a decimal wasn't found.
|
// Add the ending grouping if a decimal wasn't found.
|
||||||
if (!__found_dec)
|
if (!__found_dec)
|
||||||
__found_grouping += static_cast<char>(__sep_pos);
|
__found_grouping += static_cast<char>(__sep_pos);
|
||||||
|
|
||||||
if (!__verify_grouping(__grouping, __found_grouping))
|
if (!__verify_grouping(__grouping, __found_grouping))
|
||||||
{
|
__err |= ios_base::failbit;
|
||||||
__err |= ios_base::failbit;
|
|
||||||
__xtrc[__pos] = '\0';
|
|
||||||
if (__beg == __end)
|
|
||||||
__err |= ios_base::eofbit;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finish up
|
// Finish up
|
||||||
__xtrc[__pos] = char_type();
|
__xtrc += char();
|
||||||
if (__beg == __end)
|
if (__beg == __end)
|
||||||
__err |= ios_base::eofbit;
|
__err |= ios_base::eofbit;
|
||||||
}
|
}
|
||||||
|
|
@ -217,9 +219,15 @@ namespace std
|
||||||
void
|
void
|
||||||
num_get<_CharT, _InIter>::
|
num_get<_CharT, _InIter>::
|
||||||
_M_extract_int(_InIter __beg, _InIter __end, ios_base& __io,
|
_M_extract_int(_InIter __beg, _InIter __end, ios_base& __io,
|
||||||
ios_base::iostate& __err, char* __xtrc, int& __base) const
|
ios_base::iostate& __err, char* __xtrc, int __max,
|
||||||
|
int& __base) const
|
||||||
{
|
{
|
||||||
|
const locale __loc = __io.getloc();
|
||||||
|
const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
|
||||||
|
const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
|
||||||
|
|
||||||
// Stage 1: determine a conversion specifier.
|
// Stage 1: determine a conversion specifier.
|
||||||
|
// NB: Iff __basefield == 0, this can change based on contents.
|
||||||
ios_base::fmtflags __basefield = __io.flags() & ios_base::basefield;
|
ios_base::fmtflags __basefield = __io.flags() & ios_base::basefield;
|
||||||
if (__basefield == ios_base::oct)
|
if (__basefield == ios_base::oct)
|
||||||
__base = 8;
|
__base = 8;
|
||||||
|
|
@ -228,13 +236,9 @@ namespace std
|
||||||
else
|
else
|
||||||
__base = 10;
|
__base = 10;
|
||||||
|
|
||||||
const locale __loc = __io.getloc();
|
// Check first for sign.
|
||||||
const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
|
|
||||||
const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
|
|
||||||
int __pos = 0;
|
int __pos = 0;
|
||||||
char_type __c = *__beg;
|
char_type __c = *__beg;
|
||||||
|
|
||||||
// Check first for sign.
|
|
||||||
if ((__c == __ctype.widen('+') || __c == __ctype.widen('-'))
|
if ((__c == __ctype.widen('+') || __c == __ctype.widen('-'))
|
||||||
&& __beg != __end)
|
&& __beg != __end)
|
||||||
{
|
{
|
||||||
|
|
@ -242,24 +246,45 @@ namespace std
|
||||||
__c = *(++__beg);
|
__c = *(++__beg);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Next, strip leading zeros
|
// Next, strip leading zeros and check required digits for base formats.
|
||||||
const char_type __zero = __ctype.widen(_S_atoms[_M_zero]);
|
const char_type __zero = __ctype.widen(_S_atoms[_M_zero]);
|
||||||
bool __found_zero = false;
|
const char_type __x = __ctype.widen('x');
|
||||||
while (__base == 10 && __c == __zero && __beg != __end)
|
const char_type __X = __ctype.widen('X');
|
||||||
|
if (__base == 10)
|
||||||
{
|
{
|
||||||
__c = *(++__beg);
|
bool __found_zero = false;
|
||||||
__found_zero = true;
|
while (__c == __zero && __beg != __end)
|
||||||
}
|
|
||||||
if (__found_zero)
|
|
||||||
{
|
|
||||||
__xtrc[__pos++] = _S_atoms[_M_zero];
|
|
||||||
if (__basefield == 0)
|
|
||||||
{
|
{
|
||||||
// Depending on what is discovered, the base may change.
|
__c = *(++__beg);
|
||||||
if (__c == __ctype.widen('x') || __c == __ctype.widen('X'))
|
__found_zero = true;
|
||||||
__base = 16;
|
}
|
||||||
else
|
if (__found_zero)
|
||||||
__base = 8;
|
{
|
||||||
|
__xtrc[__pos++] = _S_atoms[_M_zero];
|
||||||
|
if (__basefield == 0)
|
||||||
|
{
|
||||||
|
if ((__c == __x || __c == __X) && __beg != __end)
|
||||||
|
{
|
||||||
|
__xtrc[__pos++] = __ctype.narrow(__c, char());
|
||||||
|
__c = *(++__beg);
|
||||||
|
__base = 16;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
__base = 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (__base == 16)
|
||||||
|
{
|
||||||
|
if (__c == __zero && __beg != __end)
|
||||||
|
{
|
||||||
|
__xtrc[__pos++] = _S_atoms[_M_zero];
|
||||||
|
__c = *(++__beg);
|
||||||
|
if ((__c == __x || __c == __X) && __beg != __end)
|
||||||
|
{
|
||||||
|
__xtrc[__pos++] = __ctype.narrow(__c, char());
|
||||||
|
__c = *(++__beg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -271,14 +296,26 @@ namespace std
|
||||||
else
|
else
|
||||||
__len = __base;
|
__len = __base;
|
||||||
|
|
||||||
char_type __watoms[_M_size];
|
// Figure out the maximum number of digits that can be extracted
|
||||||
|
// for the given type, using the determined base.
|
||||||
|
int __max_digits;
|
||||||
|
if (__base != 10)
|
||||||
|
__max_digits = static_cast<int>(ceil(__max * log(10.0)
|
||||||
|
/log(static_cast<double>(__base))));
|
||||||
|
else
|
||||||
|
__max_digits = __max;
|
||||||
|
// Add in what's already been extracted.
|
||||||
|
__max_digits += __pos;
|
||||||
|
|
||||||
|
// Extract.
|
||||||
|
char_type __watoms[_M_size];
|
||||||
__ctype.widen(_S_atoms, _S_atoms + __len, __watoms);
|
__ctype.widen(_S_atoms, _S_atoms + __len, __watoms);
|
||||||
string __found_grouping;
|
string __found_grouping;
|
||||||
const string __grouping = __np.grouping();
|
const string __grouping = __np.grouping();
|
||||||
bool __check_grouping = __grouping.size() && __base == 10;
|
bool __check_grouping = __grouping.size() && __base == 10;
|
||||||
int __sep_pos = 0;
|
int __sep_pos = 0;
|
||||||
const char_type __sep = __np.thousands_sep();
|
const char_type __sep = __np.thousands_sep();
|
||||||
while (__beg != __end)
|
while (__beg != __end && __pos <= __max_digits)
|
||||||
{
|
{
|
||||||
typedef char_traits<_CharT> __traits_type;
|
typedef char_traits<_CharT> __traits_type;
|
||||||
const char_type* __p = __traits_type::find(__watoms, __len, __c);
|
const char_type* __p = __traits_type::find(__watoms, __len, __c);
|
||||||
|
|
@ -312,25 +349,22 @@ namespace std
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If one more than the maximum number of digits is extracted.
|
||||||
|
if (__pos > __max_digits)
|
||||||
|
__err |= ios_base::failbit;
|
||||||
|
|
||||||
// Digit grouping is checked. If grouping and found_grouping don't
|
// Digit grouping is checked. If grouping and found_grouping don't
|
||||||
// match, then get very very upset, and set failbit.
|
// match, then get very very upset, and set failbit.
|
||||||
if (__check_grouping && __found_grouping.size())
|
if (__check_grouping && __found_grouping.size())
|
||||||
{
|
{
|
||||||
// Add the ending grouping
|
// Add the ending grouping.
|
||||||
__found_grouping += static_cast<char>(__sep_pos);
|
__found_grouping += static_cast<char>(__sep_pos);
|
||||||
|
|
||||||
if (!__verify_grouping(__grouping, __found_grouping))
|
if (!__verify_grouping(__grouping, __found_grouping))
|
||||||
{
|
__err |= ios_base::failbit;
|
||||||
__err |= ios_base::failbit;
|
|
||||||
__xtrc[__pos] = '\0';
|
|
||||||
if (__beg == __end)
|
|
||||||
__err |= ios_base::eofbit;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finish up
|
// Finish up
|
||||||
__xtrc[__pos] = char_type();
|
__xtrc[__pos] = char();
|
||||||
if (__beg == __end)
|
if (__beg == __end)
|
||||||
__err |= ios_base::eofbit;
|
__err |= ios_base::eofbit;
|
||||||
}
|
}
|
||||||
|
|
@ -351,10 +385,11 @@ namespace std
|
||||||
|
|
||||||
// Stage 1: extract and determine the conversion specifier.
|
// Stage 1: extract and determine the conversion specifier.
|
||||||
// Assuming leading zeros eliminated, thus the size of 32 for
|
// Assuming leading zeros eliminated, thus the size of 32 for
|
||||||
// integral types.
|
// integral types
|
||||||
char __xtrc[32] = {'\0'};
|
char __xtrc[32];
|
||||||
int __base;
|
int __base;
|
||||||
_M_extract_int(__beg, __end, __io, __err, __xtrc, __base);
|
_M_extract_int(__beg, __end, __io, __err, __xtrc,
|
||||||
|
numeric_limits<bool>::digits10, __base);
|
||||||
|
|
||||||
// Stage 2: convert and store results.
|
// Stage 2: convert and store results.
|
||||||
char* __sanity;
|
char* __sanity;
|
||||||
|
|
@ -416,9 +451,10 @@ namespace std
|
||||||
// Stage 1: extract and determine the conversion specifier.
|
// Stage 1: extract and determine the conversion specifier.
|
||||||
// Assuming leading zeros eliminated, thus the size of 32 for
|
// Assuming leading zeros eliminated, thus the size of 32 for
|
||||||
// integral types.
|
// integral types.
|
||||||
char __xtrc[32]= {'\0'};
|
char __xtrc[32];
|
||||||
int __base;
|
int __base;
|
||||||
_M_extract_int(__beg, __end, __io, __err, __xtrc, __base);
|
_M_extract_int(__beg, __end, __io, __err, __xtrc,
|
||||||
|
numeric_limits<long>::digits10, __base);
|
||||||
|
|
||||||
// Stage 2: convert and store results.
|
// Stage 2: convert and store results.
|
||||||
char* __sanity;
|
char* __sanity;
|
||||||
|
|
@ -441,9 +477,10 @@ namespace std
|
||||||
// Stage 1: extract and determine the conversion specifier.
|
// Stage 1: extract and determine the conversion specifier.
|
||||||
// Assuming leading zeros eliminated, thus the size of 32 for
|
// Assuming leading zeros eliminated, thus the size of 32 for
|
||||||
// integral types.
|
// integral types.
|
||||||
char __xtrc[32]= {'\0'};
|
char __xtrc[32];
|
||||||
int __base;
|
int __base;
|
||||||
_M_extract_int(__beg, __end, __io, __err, __xtrc, __base);
|
_M_extract_int(__beg, __end, __io, __err, __xtrc,
|
||||||
|
numeric_limits<unsigned short>::digits10, __base);
|
||||||
|
|
||||||
// Stage 2: convert and store results.
|
// Stage 2: convert and store results.
|
||||||
char* __sanity;
|
char* __sanity;
|
||||||
|
|
@ -467,9 +504,10 @@ namespace std
|
||||||
// Stage 1: extract and determine the conversion specifier.
|
// Stage 1: extract and determine the conversion specifier.
|
||||||
// Assuming leading zeros eliminated, thus the size of 32 for
|
// Assuming leading zeros eliminated, thus the size of 32 for
|
||||||
// integral types.
|
// integral types.
|
||||||
char __xtrc[32]= {'\0'};
|
char __xtrc[32];
|
||||||
int __base;
|
int __base;
|
||||||
_M_extract_int(__beg, __end, __io, __err, __xtrc, __base);
|
_M_extract_int(__beg, __end, __io, __err, __xtrc,
|
||||||
|
numeric_limits<unsigned int>::digits10, __base);
|
||||||
|
|
||||||
// Stage 2: convert and store results.
|
// Stage 2: convert and store results.
|
||||||
char* __sanity;
|
char* __sanity;
|
||||||
|
|
@ -493,9 +531,10 @@ namespace std
|
||||||
// Stage 1: extract and determine the conversion specifier.
|
// Stage 1: extract and determine the conversion specifier.
|
||||||
// Assuming leading zeros eliminated, thus the size of 32 for
|
// Assuming leading zeros eliminated, thus the size of 32 for
|
||||||
// integral types.
|
// integral types.
|
||||||
char __xtrc[32] = {'\0'};
|
char __xtrc[32];
|
||||||
int __base;
|
int __base;
|
||||||
_M_extract_int(__beg, __end, __io, __err, __xtrc, __base);
|
_M_extract_int(__beg, __end, __io, __err, __xtrc,
|
||||||
|
numeric_limits<unsigned long>::digits10, __base);
|
||||||
|
|
||||||
// Stage 2: convert and store results.
|
// Stage 2: convert and store results.
|
||||||
char* __sanity;
|
char* __sanity;
|
||||||
|
|
@ -519,9 +558,10 @@ namespace std
|
||||||
// Stage 1: extract and determine the conversion specifier.
|
// Stage 1: extract and determine the conversion specifier.
|
||||||
// Assuming leading zeros eliminated, thus the size of 32 for
|
// Assuming leading zeros eliminated, thus the size of 32 for
|
||||||
// integral types.
|
// integral types.
|
||||||
char __xtrc[32]= {'\0'};
|
char __xtrc[32];
|
||||||
int __base;
|
int __base;
|
||||||
_M_extract_int(__beg, __end, __io, __err, __xtrc, __base);
|
_M_extract_int(__beg, __end, __io, __err, __xtrc,
|
||||||
|
numeric_limits<long long>::digits10, __base);
|
||||||
|
|
||||||
// Stage 2: convert and store results.
|
// Stage 2: convert and store results.
|
||||||
char* __sanity;
|
char* __sanity;
|
||||||
|
|
@ -544,9 +584,10 @@ namespace std
|
||||||
// Stage 1: extract and determine the conversion specifier.
|
// Stage 1: extract and determine the conversion specifier.
|
||||||
// Assuming leading zeros eliminated, thus the size of 32 for
|
// Assuming leading zeros eliminated, thus the size of 32 for
|
||||||
// integral types.
|
// integral types.
|
||||||
char __xtrc[32]= {'\0'};
|
char __xtrc[32];
|
||||||
int __base;
|
int __base;
|
||||||
_M_extract_int(__beg, __end, __io, __err, __xtrc, __base);
|
_M_extract_int(__beg, __end, __io, __err, __xtrc,
|
||||||
|
numeric_limits<unsigned long long>::digits10, __base);
|
||||||
|
|
||||||
// Stage 2: convert and store results.
|
// Stage 2: convert and store results.
|
||||||
char* __sanity;
|
char* __sanity;
|
||||||
|
|
@ -568,21 +609,20 @@ namespace std
|
||||||
ios_base::iostate& __err, float& __v) const
|
ios_base::iostate& __err, float& __v) const
|
||||||
{
|
{
|
||||||
// Stage 1: extract and determine the conversion specifier.
|
// Stage 1: extract and determine the conversion specifier.
|
||||||
// Assuming leading zeros eliminated, thus the size of 256 for
|
string __xtrc;
|
||||||
// floating-point types.
|
__xtrc.reserve(32);
|
||||||
char __xtrc[32]= {'\0'};
|
|
||||||
_M_extract_float(__beg, __end, __io, __err, __xtrc);
|
_M_extract_float(__beg, __end, __io, __err, __xtrc);
|
||||||
|
|
||||||
// Stage 2: convert and store results.
|
// Stage 2: convert and store results.
|
||||||
char* __sanity;
|
char* __sanity;
|
||||||
errno = 0;
|
errno = 0;
|
||||||
#ifdef _GLIBCPP_USE_C99
|
#ifdef _GLIBCPP_USE_C99
|
||||||
float __f = strtof(__xtrc, &__sanity);
|
float __f = strtof(__xtrc.c_str(), &__sanity);
|
||||||
#else
|
#else
|
||||||
float __f = static_cast<float>(strtod(__xtrc, &__sanity));
|
float __f = static_cast<float>(strtod(__xtrc.c_str(), &__sanity));
|
||||||
#endif
|
#endif
|
||||||
if (!(__err & ios_base::failbit)
|
if (!(__err & ios_base::failbit)
|
||||||
&& __sanity != __xtrc && *__sanity == '\0' && errno == 0)
|
&& __sanity != __xtrc.c_str() && *__sanity == '\0' && errno == 0)
|
||||||
__v = __f;
|
__v = __f;
|
||||||
else
|
else
|
||||||
__err |= ios_base::failbit;
|
__err |= ios_base::failbit;
|
||||||
|
|
@ -596,17 +636,16 @@ namespace std
|
||||||
ios_base::iostate& __err, double& __v) const
|
ios_base::iostate& __err, double& __v) const
|
||||||
{
|
{
|
||||||
// Stage 1: extract and determine the conversion specifier.
|
// Stage 1: extract and determine the conversion specifier.
|
||||||
// Assuming leading zeros eliminated, thus the size of 256 for
|
string __xtrc;
|
||||||
// floating-point types.
|
__xtrc.reserve(32);
|
||||||
char __xtrc[32]= {'\0'};
|
|
||||||
_M_extract_float(__beg, __end, __io, __err, __xtrc);
|
_M_extract_float(__beg, __end, __io, __err, __xtrc);
|
||||||
|
|
||||||
// Stage 2: convert and store results.
|
// Stage 2: convert and store results.
|
||||||
char* __sanity;
|
char* __sanity;
|
||||||
errno = 0;
|
errno = 0;
|
||||||
double __d = strtod(__xtrc, &__sanity);
|
double __d = strtod(__xtrc.c_str(), &__sanity);
|
||||||
if (!(__err & ios_base::failbit)
|
if (!(__err & ios_base::failbit)
|
||||||
&& __sanity != __xtrc && *__sanity == '\0' && errno == 0)
|
&& __sanity != __xtrc.c_str() && *__sanity == '\0' && errno == 0)
|
||||||
__v = __d;
|
__v = __d;
|
||||||
else
|
else
|
||||||
__err |= ios_base::failbit;
|
__err |= ios_base::failbit;
|
||||||
|
|
@ -620,18 +659,17 @@ namespace std
|
||||||
ios_base::iostate& __err, long double& __v) const
|
ios_base::iostate& __err, long double& __v) const
|
||||||
{
|
{
|
||||||
// Stage 1: extract and determine the conversion specifier.
|
// Stage 1: extract and determine the conversion specifier.
|
||||||
// Assuming leading zeros eliminated, thus the size of 256 for
|
string __xtrc;
|
||||||
// floating-point types.
|
__xtrc.reserve(32);
|
||||||
char __xtrc[32]= {'\0'};
|
|
||||||
_M_extract_float(__beg, __end, __io, __err, __xtrc);
|
_M_extract_float(__beg, __end, __io, __err, __xtrc);
|
||||||
|
|
||||||
#if defined(_GLIBCPP_USE_C99) && !defined(__hpux)
|
#if defined(_GLIBCPP_USE_C99) && !defined(__hpux)
|
||||||
// Stage 2: convert and store results.
|
// Stage 2: convert and store results.
|
||||||
char* __sanity;
|
char* __sanity;
|
||||||
errno = 0;
|
errno = 0;
|
||||||
long double __ld = strtold(__xtrc, &__sanity);
|
long double __ld = strtold(__xtrc.c_str(), &__sanity);
|
||||||
if (!(__err & ios_base::failbit)
|
if (!(__err & ios_base::failbit)
|
||||||
&& __sanity != __xtrc && *__sanity == '\0' && errno == 0)
|
&& __sanity != __xtrc.c_str() && *__sanity == '\0' && errno == 0)
|
||||||
__v = __ld;
|
__v = __ld;
|
||||||
#else
|
#else
|
||||||
// Stage 2: determine a conversion specifier.
|
// Stage 2: determine a conversion specifier.
|
||||||
|
|
@ -649,7 +687,7 @@ namespace std
|
||||||
// Stage 3: store results.
|
// Stage 3: store results.
|
||||||
typedef typename char_traits<_CharT>::int_type int_type;
|
typedef typename char_traits<_CharT>::int_type int_type;
|
||||||
long double __ld;
|
long double __ld;
|
||||||
int __p = sscanf(__xtrc, __conv, &__ld);
|
int __p = sscanf(__xtrc.c_str(), __conv, &__ld);
|
||||||
if (!(__err & ios_base::failbit) && __p
|
if (!(__err & ios_base::failbit) && __p
|
||||||
&& static_cast<int_type>(__p) != char_traits<_CharT>::eof())
|
&& static_cast<int_type>(__p) != char_traits<_CharT>::eof())
|
||||||
__v = __ld;
|
__v = __ld;
|
||||||
|
|
@ -675,9 +713,10 @@ namespace std
|
||||||
// Stage 1: extract and determine the conversion specifier.
|
// Stage 1: extract and determine the conversion specifier.
|
||||||
// Assuming leading zeros eliminated, thus the size of 32 for
|
// Assuming leading zeros eliminated, thus the size of 32 for
|
||||||
// integral types.
|
// integral types.
|
||||||
char __xtrc[32]= {'\0'};
|
char __xtrc[32];
|
||||||
int __base;
|
int __base;
|
||||||
_M_extract_int(__beg, __end, __io, __err, __xtrc, __base);
|
_M_extract_int(__beg, __end, __io, __err, __xtrc,
|
||||||
|
numeric_limits<unsigned long>::digits10, __base);
|
||||||
|
|
||||||
// Stage 2: convert and store results.
|
// Stage 2: convert and store results.
|
||||||
char* __sanity;
|
char* __sanity;
|
||||||
|
|
|
||||||
|
|
@ -74,7 +74,7 @@ namespace std
|
||||||
// Definitions for static const data members of locale::id
|
// Definitions for static const data members of locale::id
|
||||||
size_t locale::id::_S_highwater; // init'd to 0 by linker
|
size_t locale::id::_S_highwater; // init'd to 0 by linker
|
||||||
|
|
||||||
const char __num_base::_S_atoms[] = "0123456789eEabcdfxABCDFX";
|
const char __num_base::_S_atoms[] = "0123456789eEabcdfABCDF";
|
||||||
|
|
||||||
// Definitions for static const data members of locale::_Impl
|
// Definitions for static const data members of locale::_Impl
|
||||||
const locale::id* const
|
const locale::id* const
|
||||||
|
|
|
||||||
|
|
@ -513,6 +513,83 @@ bool test11()
|
||||||
return test;
|
return test;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// libstdc++/3720
|
||||||
|
// excess input should not cause a core dump
|
||||||
|
template<typename T>
|
||||||
|
bool test12_aux(bool integer_type)
|
||||||
|
{
|
||||||
|
bool test = true;
|
||||||
|
|
||||||
|
int digits_overflow;
|
||||||
|
if (integer_type)
|
||||||
|
// This many digits will overflow integer types in base 10.
|
||||||
|
digits_overflow = std::numeric_limits<T>::digits10 + 1;
|
||||||
|
else
|
||||||
|
// This might do it, unsure.
|
||||||
|
digits_overflow = std::numeric_limits<T>::max_exponent10 + 1;
|
||||||
|
|
||||||
|
std::string st;
|
||||||
|
std::string part = "1234567890123456789012345678901234567890";
|
||||||
|
for (int i = 0; i < digits_overflow / part.size() + 1; ++i)
|
||||||
|
st += part;
|
||||||
|
std::stringbuf sb(st);
|
||||||
|
std::istream is(&sb);
|
||||||
|
T t;
|
||||||
|
is >> t;
|
||||||
|
VERIFY(is.fail());
|
||||||
|
return test;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool test12()
|
||||||
|
{
|
||||||
|
bool test = true;
|
||||||
|
VERIFY(test12_aux<short>(true));
|
||||||
|
VERIFY(test12_aux<int>(true));
|
||||||
|
VERIFY(test12_aux<long>(true));
|
||||||
|
VERIFY(test12_aux<float>(false));
|
||||||
|
VERIFY(test12_aux<double>(false));
|
||||||
|
VERIFY(test12_aux<long double>(false));
|
||||||
|
return test;
|
||||||
|
}
|
||||||
|
|
||||||
|
// libstdc++/3720 part two
|
||||||
|
void test13()
|
||||||
|
{
|
||||||
|
using namespace std;
|
||||||
|
bool test = true;
|
||||||
|
const char* l1 = "12345678901234567890123456789012345678901234567890123456";
|
||||||
|
const char* l2 = "1.2345678901234567890123456789012345678901234567890123456"
|
||||||
|
" "
|
||||||
|
"1246.9";
|
||||||
|
|
||||||
|
// 1
|
||||||
|
// used to core.
|
||||||
|
double d;
|
||||||
|
istringstream iss1(l2);
|
||||||
|
iss1 >> d;
|
||||||
|
iss1 >> d;
|
||||||
|
VERIFY (d > 1246 && d < 1247);
|
||||||
|
|
||||||
|
// 2
|
||||||
|
// quick test for failbit on maximum length extraction.
|
||||||
|
int i;
|
||||||
|
int max_digits = numeric_limits<int>::digits10;
|
||||||
|
string digits;
|
||||||
|
for (int j = 0; j < max_digits; ++j)
|
||||||
|
digits += '1';
|
||||||
|
istringstream iss2(digits);
|
||||||
|
iss2 >> i;
|
||||||
|
VERIFY( iss2.good() );
|
||||||
|
|
||||||
|
digits += '1';
|
||||||
|
i = 0;
|
||||||
|
iss2.str(digits);
|
||||||
|
iss2.clear();
|
||||||
|
iss2 >> i;
|
||||||
|
VERIFY( i == 0 );
|
||||||
|
VERIFY( iss2.fail() );
|
||||||
|
}
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
test01();
|
test01();
|
||||||
|
|
@ -526,6 +603,7 @@ int main()
|
||||||
test10();
|
test10();
|
||||||
|
|
||||||
test11();
|
test11();
|
||||||
|
test12();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue