+2003-02-06 Paolo Carlini <pcarlini@unitus.it>
+
+ PR libstdc++/9548
+ Implement resolution of DR 231 (Ready)
+ * include/bits/locale_facets.h (__num_base::_S_format_float):
+ Change declaration: return void, remove __prec parameter.
+ * src/locale.cc (__num_base::_S_format_float): Implement
+ resolution of DR 231.
+ * include/bits/locale_facets.tcc (num_put::_M_convert_float):
+ Tweak uses. Check for negative precision.
+ * testsuite/22_locale/num_put/put/char/6.cc: Add
+ * testsuite/22_locale/num_put/put/wchar_t/6.cc: Likewise.
+
2003-02-06 Peter Soetens <peter.soetens@mech.kuleuven.ac.be>
* config/io/basic_file_libio.h: Fixups.
// num_put
// Construct and return valid scanf format for floating point types.
- static bool
- _S_format_float(const ios_base& __io, char* __fptr, char __mod,
- streamsize __prec);
+ static void
+ _S_format_float(const ios_base& __io, char* __fptr, char __mod);
// Construct and return valid scanf format for integer types.
static void
if (__prec > static_cast<streamsize>(__max_digits))
__prec = static_cast<streamsize>(__max_digits);
+ else if (__prec < static_cast<streamsize>(0))
+ // Default precision.
+ __prec = static_cast<streamsize>(6);
// Long enough for the max format spec.
char __fbuf[16];
int __cs_size = __max_digits * 3;
char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
- const bool __fp = _S_format_float(__io, __fbuf, __mod, __prec);
- if (__fp)
- __len = __convert_from_v(__cs, __cs_size, __fbuf, __v,
- _S_c_locale, __prec);
- else
- __len = __convert_from_v(__cs, __cs_size, __fbuf, __v, _S_c_locale);
+ _S_format_float(__io, __fbuf, __mod);
+ __len = __convert_from_v(__cs, __cs_size, __fbuf, __v,
+ _S_c_locale, __prec);
// If the buffer was not large enough, try again with the correct size.
if (__len >= __cs_size)
{
__cs_size = __len + 1;
__cs = static_cast<char*>(__builtin_alloca(__cs_size));
- if (__fp)
- __len = __convert_from_v(__cs, __cs_size, __fbuf, __v,
- _S_c_locale, __prec);
- else
- __len = __convert_from_v(__cs, __cs_size, __fbuf, __v,
- _S_c_locale);
+ __len = __convert_from_v(__cs, __cs_size, __fbuf, __v,
+ _S_c_locale, __prec);
}
#else
// Consider the possibility of long ios_base::fixed outputs
: __max_digits * 3;
char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
- if (_S_format_float(__io, __fbuf, __mod, __prec))
- __len = __convert_from_v(__cs, 0, __fbuf, __v, _S_c_locale, __prec);
- else
- __len = __convert_from_v(__cs, 0, __fbuf, __v, _S_c_locale);
+ _S_format_float(__io, __fbuf, __mod);
+ __len = __convert_from_v(__cs, 0, __fbuf, __v, _S_c_locale, __prec);
#endif
return _M_widen_float(__s, __io, __fill, __cs, __len);
}
const char __num_base::_S_atoms[] = "0123456789eEabcdfABCDF";
- bool
- __num_base::_S_format_float(const ios_base& __io, char* __fptr, char __mod,
- streamsize __prec)
+ // _GLIBCPP_RESOLVE_LIB_DEFECTS
+ // According to the resolution of DR 231, about 22.2.2.2.2, p11,
+ // "str.precision() is specified in the conversion specification".
+ void
+ __num_base::_S_format_float(const ios_base& __io, char* __fptr, char __mod)
{
- bool __incl_prec = false;
ios_base::fmtflags __flags = __io.flags();
*__fptr++ = '%';
// [22.2.2.2.2] Table 60
*__fptr++ = '+';
if (__flags & ios_base::showpoint)
*__fptr++ = '#';
- // As per [22.2.2.2.2.11]
- if (__flags & ios_base::fixed || __prec > 0)
- {
- *__fptr++ = '.';
- *__fptr++ = '*';
- __incl_prec = true;
- }
+
+ // As per DR 231: _always_, not only when
+ // __flags & ios_base::fixed || __prec > 0
+ *__fptr++ = '.';
+ *__fptr++ = '*';
+
if (__mod)
*__fptr++ = __mod;
ios_base::fmtflags __fltfield = __flags & ios_base::floatfield;
else
*__fptr++ = (__flags & ios_base::uppercase) ? 'G' : 'g';
*__fptr = '\0';
- return __incl_prec;
}
void
--- /dev/null
+// 2003-02-05 Paolo Carlini <pcarlini@unitus.it>
+
+// 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.2.1 num_put members
+
+#include <locale>
+#include <sstream>
+#include <testsuite_hooks.h>
+
+// libstdc++/9548 and DR 231
+void test01()
+{
+ using namespace std;
+ bool test = true;
+
+ ostringstream oss1, oss2;
+ const num_put<char>& np1 = use_facet<num_put<char> >(oss1.getloc());
+ const num_put<char>& np2 = use_facet<num_put<char> >(oss2.getloc());
+
+ string result1, result2;
+
+ oss1.precision(-1);
+ oss1.setf(ios_base::fixed, ios_base::floatfield);
+ np1.put(oss1.rdbuf(), oss1, '+', 30.5);
+ result1 = oss1.str();
+ VERIFY( result1 == "30.500000" );
+
+ oss2.precision(0);
+ oss2.setf(ios_base::scientific, ios_base::floatfield);
+ np2.put(oss2.rdbuf(), oss2, '+', 1.0);
+ result2 = oss2.str();
+ VERIFY( result2 == "1e+00" );
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
--- /dev/null
+// 2003-02-05 Paolo Carlini <pcarlini@unitus.it>
+
+// 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.2.1 num_put members
+
+#include <locale>
+#include <sstream>
+#include <testsuite_hooks.h>
+
+// libstdc++/9548 and DR 231
+void test01()
+{
+ using namespace std;
+ bool test = true;
+
+ wostringstream woss1, woss2;
+ const num_put<wchar_t>& np1 = use_facet<num_put<wchar_t> >(woss1.getloc());
+ const num_put<wchar_t>& np2 = use_facet<num_put<wchar_t> >(woss2.getloc());
+
+ wstring result1, result2;
+
+ woss1.precision(-1);
+ woss1.setf(ios_base::fixed, ios_base::floatfield);
+ np1.put(woss1.rdbuf(), woss1, '+', 30.5);
+ result1 = woss1.str();
+ VERIFY( result1 == L"30.500000" );
+
+ woss2.precision(0);
+ woss2.setf(ios_base::scientific, ios_base::floatfield);
+ np2.put(woss2.rdbuf(), woss2, '+', 1.0);
+ result2 = woss2.str();
+ VERIFY( result2 == L"1e+00" );
+}
+
+int main()
+{
+ test01();
+ return 0;
+}