[multiple changes]

2001-12-05  Benjamin Kosnik  <bkoz@redhat.com>

	DR/282
	* include/bits/locale_facets.tcc (num_put::_M_widen_float): Add
	grouping to floating point types.
	* testsuite/27_io/ostream_inserter_arith.cc (test02): Add test.

2001-12-04  Paolo Carlini <pcarlini@unitus.it>

        libstdc++/4402
        * testsuite/27_io/ostream_inserter_arith.cc (test02): add testcase
	from the PR.
        * include/bits/locale_facets.tcc (num_put::_M_convert_float):
        Deal properly with long ios_base::fixed floats.
        (num_put::_M_widen_float): use
	__len in __builtin_alloca call.

From-SVN: r47696
This commit is contained in:
Benjamin Kosnik 2001-12-05 22:07:36 +00:00
parent 0df47f6610
commit 0228de0c4f
3 changed files with 96 additions and 10 deletions

View File

@ -1,3 +1,20 @@
2001-12-05 Benjamin Kosnik <bkoz@redhat.com>
DR/282
* include/bits/locale_facets.tcc (num_put::_M_widen_float): Add
grouping to floating point types.
* testsuite/27_io/ostream_inserter_arith.cc (test02): Add test.
2001-12-04 Paolo Carlini <pcarlini@unitus.it>
libstdc++/4402
* testsuite/27_io/ostream_inserter_arith.cc (test02): add testcase
from the PR.
* include/bits/locale_facets.tcc (num_put::_M_convert_float):
Deal properly with long ios_base::fixed floats.
(num_put::_M_widen_float): use
__len in __builtin_alloca call.
2001-12-04 Benjamin Kosnik <bkoz@redhat.com>
* src/Makefile.am (sources): Add ext-inst.cc.

View File

@ -711,15 +711,23 @@ namespace std
_M_convert_float(_OutIter __s, ios_base& __io, _CharT __fill, char __mod,
_ValueT __v) const
{
const streamsize __max_prec = numeric_limits<_ValueT>::digits10;
const int __max_digits = numeric_limits<_ValueT>::digits10;
streamsize __prec = __io.precision();
// Protect against sprintf() buffer overflows.
if (__prec > __max_prec)
__prec = __max_prec;
if (__prec > static_cast<streamsize>(__max_digits))
__prec = static_cast<streamsize>(__max_digits);
// Long enough for the max format spec.
char __fbuf[16];
char __cs[64];
// Consider the possibility of long ios_base::fixed outputs
const bool __fixed = __io.flags() & ios_base::fixed;
const int __max_exp = numeric_limits<_ValueT>::max_exponent10;
// XXX Why + 4? Why * 4? What's going on? Who's on first?
const int __cs_size = __fixed ? __max_exp + __max_digits + 4
: __max_digits * 4;
char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
int __len;
// [22.2.2.2.2] Stage 1, numeric conversion to character.
if (_S_format_float(__io, __fbuf, __mod, __prec))
@ -757,14 +765,47 @@ namespace std
// numpunct.decimal_point() values for '.' and adding grouping.
const locale __loc = __io.getloc();
const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
_CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * 64));
_CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
* __len));
// Grouping can add (almost) as many separators as the number of
// digits, but no more.
_CharT* __ws2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
* __len * 2));
__ctype.widen(__cs, __cs + __len, __ws);
const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
// Replace decimal point.
const _CharT* __p;
const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
if (__p = char_traits<_CharT>::find(__ws, __len, __ctype.widen('.')))
__ws[__p - __ws] = __np.decimal_point();
#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
//282. What types does numpunct grouping refer to?
// Add grouping, if necessary.
const string __grouping = __np.grouping();
ios_base::fmtflags __basefield = __io.flags() & ios_base::basefield;
if (__grouping.size())
{
_CharT* __p2;
int __declen = __p ? __p - __ws : __len;
__p2 = __add_grouping(__ws2, __np.thousands_sep(),
__grouping.c_str(),
__grouping.c_str() + __grouping.size(),
__ws, __ws + __declen);
int __newlen = __p2 - __ws2;
// Tack on decimal part.
if (__p)
{
char_traits<_CharT>::copy(__p2, __p, __len - __declen);
__newlen += __len - __declen;
}
// Switch strings, establish correct new length.
__ws = __ws2;
__len = __newlen;
}
#endif
return _M_insert(__s, __io, __fill, __ws, __len);
}
@ -778,13 +819,17 @@ namespace std
// numpunct.decimal_point() values for '.' and adding grouping.
const locale __loc = __io.getloc();
const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc);
_CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * 64));
_CharT* __ws2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * 64));
_CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
* __len));
// Grouping can add (almost) as many separators as the number of
// digits, but no more.
_CharT* __ws2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
* __len * 2));
__ctype.widen(__cs, __cs + __len, __ws);
// Add grouping, if necessary.
const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
string __grouping = __np.grouping();
const string __grouping = __np.grouping();
ios_base::fmtflags __basefield = __io.flags() & ios_base::basefield;
bool __dec = __basefield != ios_base::oct
&& __basefield != ios_base::hex;
@ -810,8 +855,9 @@ namespace std
int __len) const
{
// [22.2.2.2.2] Stage 3.
_CharT* __ws2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * 64));
streamsize __w = __io.width();
_CharT* __ws2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
* __w));
if (__w > static_cast<streamsize>(__len))
{
__pad(__io, __fill, __ws2, __ws, __w, __len, true);

View File

@ -272,6 +272,29 @@ test02()
#endif
VERIFY(os && os.str() == largebuf);
// Make sure we can output a long float in fixed format
// without seg-faulting (libstdc++/4402)
double val2 = 3.5e230;
ostringstream os2;
os2.precision(3);
os2.setf(ios::fixed);
os2 << val2;
sprintf(largebuf, "%.*f", 3, val2);
#ifdef TEST_NUMPUT_VERBOSE
cout << "expect: " << largebuf << endl;
cout << "result: " << os2.str() << endl;
#endif
VERIFY(os2 && os2.str() == largebuf);
// Check it can be done in a locale with grouping on.
locale loc2("de_DE");
os2.imbue(loc2);
os2 << fixed << setprecision(3) << val2 << endl;
os2 << endl;
os2 << fixed << setprecision(1) << val2 << endl;
return 0;
}