diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 6e7c3533185..87782611e6e 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,15 @@ +2005-09-30 Paolo Carlini + + PR libstdc++/23953 + * include/bits/locale_facets.tcc (__numpunct_cache<>::_M_cache, + __moneypunct_cache<>::_M_cache): Check that grouping()[0] > 0. + (__verify_grouping): Do the last check only if __grouping[__min] > 0. + (__add_grouping<>): End recursion if *__gbeg <= 0. + * testsuite/22_locale/num_get/get/char/23953.cc: New. + * testsuite/22_locale/num_get/get/wchar_t/23953.cc: Likewise. + * testsuite/22_locale/num_put/put/char/23953.cc: Likewise. + * testsuite/22_locale/num_put/put/wchar_t/23953.cc: Likewise. + 2005-09-29 Chris Jefferson PR libstdc++/23978 diff --git a/libstdc++-v3/include/bits/locale_facets.tcc b/libstdc++-v3/include/bits/locale_facets.tcc index e78f64a9187..eb4a3527c5c 100644 --- a/libstdc++-v3/include/bits/locale_facets.tcc +++ b/libstdc++-v3/include/bits/locale_facets.tcc @@ -193,7 +193,8 @@ namespace std char* __grouping = new char[_M_grouping_size]; __np.grouping().copy(__grouping, _M_grouping_size); _M_grouping = __grouping; - _M_use_grouping = _M_grouping_size && __np.grouping()[0] != 0; + _M_use_grouping = (_M_grouping_size + && static_cast(__np.grouping()[0]) > 0); _M_truename_size = __np.truename().size(); _CharT* __truename = new _CharT[_M_truename_size]; @@ -228,7 +229,8 @@ namespace std char* __grouping = new char[_M_grouping_size]; __mp.grouping().copy(__grouping, _M_grouping_size); _M_grouping = __grouping; - _M_use_grouping = _M_grouping_size && __mp.grouping()[0] != 0; + _M_use_grouping = (_M_grouping_size + && static_cast(__mp.grouping()[0]) > 0); _M_decimal_point = __mp.decimal_point(); _M_thousands_sep = __mp.thousands_sep(); @@ -2471,9 +2473,11 @@ namespace std __test = __grouping_tmp[__i] == __grouping[__j]; for (; __i && __test; --__i) __test = __grouping_tmp[__i] == __grouping[__min]; - // ... but the last parsed grouping can be <= numpunct - // grouping. - __test &= __grouping_tmp[0] <= __grouping[__min]; + // ... but the first parsed grouping can be <= numpunct + // grouping (only do the check if the numpunct char is > 0 + // because <= 0 means any size is ok). + if (static_cast(__grouping[__min]) > 0) + __test &= __grouping_tmp[0] <= __grouping[__min]; return __test; } @@ -2483,7 +2487,8 @@ namespace std const char* __gbeg, size_t __gsize, const _CharT* __first, const _CharT* __last) { - if (__last - __first > *__gbeg) + if (__last - __first > *__gbeg + && static_cast(*__gbeg) > 0) { const bool __bump = __gsize != 1; __s = std::__add_grouping(__s, __sep, __gbeg + __bump, diff --git a/libstdc++-v3/testsuite/22_locale/num_get/get/char/23953.cc b/libstdc++-v3/testsuite/22_locale/num_get/get/char/23953.cc new file mode 100644 index 00000000000..70f339045c0 --- /dev/null +++ b/libstdc++-v3/testsuite/22_locale/num_get/get/char/23953.cc @@ -0,0 +1,83 @@ +// 2005-09-30 Paolo Carlini + +// Copyright (C) 2005 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +// USA. + +// 22.2.2.1.1 num_get members + +#include +#include +#include + +using namespace std; + +struct Punct1: numpunct +{ string do_grouping() const { return string(1, char(-1)); } }; + +struct Punct2: numpunct +{ string do_grouping() const { return string("\002") + char(-1); } }; + +struct Punct3: numpunct +{ string do_grouping() const { return string("\001\002") + char(-1); } }; + +// libstdc++/23953 +void test01() +{ + bool test __attribute__((unused)) = true; + typedef istreambuf_iterator iterator_type; + + istringstream iss1, iss2, iss3; + iss1.imbue(locale(iss1.getloc(), new Punct1)); + iss2.imbue(locale(iss2.getloc(), new Punct2)); + iss3.imbue(locale(iss3.getloc(), new Punct3)); + const num_get& ng1 = use_facet >(iss1.getloc()); + const num_get& ng2 = use_facet >(iss2.getloc()); + const num_get& ng3 = use_facet >(iss3.getloc()); + + ios_base::iostate err = ios_base::goodbit; + iterator_type end; + long l = 0l; + long l1 = 12345l; + long l2 = 12345678l; + double d = 0.0; + double d1 = 1234567.0; + + iss1.str("12345"); + err = ios_base::goodbit; + end = ng1.get(iss1.rdbuf(), 0, iss1, err, l); + VERIFY( err == ios_base::eofbit ); + VERIFY( l == l1 ); + + iss2.str("123456,78"); + err = ios_base::goodbit; + end = ng2.get(iss2.rdbuf(), 0, iss2, err, l); + VERIFY( err == ios_base::eofbit ); + VERIFY( l == l2 ); + + iss3.str("1234,56,7.0"); + err = ios_base::goodbit; + end = ng3.get(iss3.rdbuf(), 0, iss3, err, d); + VERIFY( err == ios_base::eofbit ); + VERIFY( d == d1 ); +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/22_locale/num_get/get/wchar_t/23953.cc b/libstdc++-v3/testsuite/22_locale/num_get/get/wchar_t/23953.cc new file mode 100644 index 00000000000..efc9038e71a --- /dev/null +++ b/libstdc++-v3/testsuite/22_locale/num_get/get/wchar_t/23953.cc @@ -0,0 +1,83 @@ +// 2005-09-30 Paolo Carlini + +// Copyright (C) 2005 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +// USA. + +// 22.2.2.1.1 num_get members + +#include +#include +#include + +using namespace std; + +struct Punct1: numpunct +{ string do_grouping() const { return string(1, char(-1)); } }; + +struct Punct2: numpunct +{ string do_grouping() const { return string("\002") + char(-1); } }; + +struct Punct3: numpunct +{ string do_grouping() const { return string("\001\002") + char(-1); } }; + +// libstdc++/23953 +void test01() +{ + bool test __attribute__((unused)) = true; + typedef istreambuf_iterator iterator_type; + + wistringstream iss1, iss2, iss3; + iss1.imbue(locale(iss1.getloc(), new Punct1)); + iss2.imbue(locale(iss2.getloc(), new Punct2)); + iss3.imbue(locale(iss3.getloc(), new Punct3)); + const num_get& ng1 = use_facet >(iss1.getloc()); + const num_get& ng2 = use_facet >(iss2.getloc()); + const num_get& ng3 = use_facet >(iss3.getloc()); + + ios_base::iostate err = ios_base::goodbit; + iterator_type end; + long l = 0l; + long l1 = 12345l; + long l2 = 12345678l; + double d = 0.0; + double d1 = 1234567.0; + + iss1.str(L"12345"); + err = ios_base::goodbit; + end = ng1.get(iss1.rdbuf(), 0, iss1, err, l); + VERIFY( err == ios_base::eofbit ); + VERIFY( l == l1 ); + + iss2.str(L"123456,78"); + err = ios_base::goodbit; + end = ng2.get(iss2.rdbuf(), 0, iss2, err, l); + VERIFY( err == ios_base::eofbit ); + VERIFY( l == l2 ); + + iss3.str(L"1234,56,7.0"); + err = ios_base::goodbit; + end = ng3.get(iss3.rdbuf(), 0, iss3, err, d); + VERIFY( err == ios_base::eofbit ); + VERIFY( d == d1 ); +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/22_locale/num_put/put/char/23953.cc b/libstdc++-v3/testsuite/22_locale/num_put/put/char/23953.cc new file mode 100644 index 00000000000..030b1cb87d3 --- /dev/null +++ b/libstdc++-v3/testsuite/22_locale/num_put/put/char/23953.cc @@ -0,0 +1,76 @@ +// 2005-09-30 Paolo Carlini + +// Copyright (C) 2005 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +// USA. + +// 22.2.2.2.1 num_put members + +#include +#include +#include + +using namespace std; + +struct Punct1: numpunct +{ string do_grouping() const { return string(1, char(-1)); } }; + +struct Punct2: numpunct +{ string do_grouping() const { return string("\002") + char(-1); } }; + +struct Punct3: numpunct +{ string do_grouping() const { return string("\001\002") + char(-1); } }; + +// libstdc++/23953 +void test01() +{ + bool test __attribute__((unused)) = true; + + ostringstream oss1, oss2, oss3; + string result1, result2, result3; + + oss1.imbue(locale(oss1.getloc(), new Punct1)); + oss2.imbue(locale(oss2.getloc(), new Punct2)); + oss3.imbue(locale(oss3.getloc(), new Punct3)); + const num_put& ng1 = use_facet >(oss1.getloc()); + const num_put& ng2 = use_facet >(oss2.getloc()); + const num_put& ng3 = use_facet >(oss3.getloc()); + + long l1 = 12345l; + long l2 = 12345678l; + double d1 = 1234567.0; + + ng1.put(oss1.rdbuf(), oss1, '+', l1); + result1 = oss1.str(); + VERIFY( result1 == "12345" ); + + ng2.put(oss2.rdbuf(), oss2, '+', l2); + result2 = oss2.str(); + VERIFY( result2 == "123456,78" ); + + oss3.precision(1); + oss3.setf(ios_base::fixed, ios_base::floatfield); + ng3.put(oss3.rdbuf(), oss3, '+', d1); + result3 = oss3.str(); + VERIFY( result3 == "1234,56,7.0" ); +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/22_locale/num_put/put/wchar_t/23953.cc b/libstdc++-v3/testsuite/22_locale/num_put/put/wchar_t/23953.cc new file mode 100644 index 00000000000..a947d55876b --- /dev/null +++ b/libstdc++-v3/testsuite/22_locale/num_put/put/wchar_t/23953.cc @@ -0,0 +1,76 @@ +// 2005-09-30 Paolo Carlini + +// Copyright (C) 2005 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +// USA. + +// 22.2.2.2.1 num_put members + +#include +#include +#include + +using namespace std; + +struct Punct1: numpunct +{ string do_grouping() const { return string(1, char(-1)); } }; + +struct Punct2: numpunct +{ string do_grouping() const { return string("\002") + char(-1); } }; + +struct Punct3: numpunct +{ string do_grouping() const { return string("\001\002") + char(-1); } }; + +// libstdc++/23953 +void test01() +{ + bool test __attribute__((unused)) = true; + + wostringstream oss1, oss2, oss3; + wstring result1, result2, result3; + + oss1.imbue(locale(oss1.getloc(), new Punct1)); + oss2.imbue(locale(oss2.getloc(), new Punct2)); + oss3.imbue(locale(oss3.getloc(), new Punct3)); + const num_put& ng1 = use_facet >(oss1.getloc()); + const num_put& ng2 = use_facet >(oss2.getloc()); + const num_put& ng3 = use_facet >(oss3.getloc()); + + long l1 = 12345l; + long l2 = 12345678l; + double d1 = 1234567.0; + + ng1.put(oss1.rdbuf(), oss1, L'+', l1); + result1 = oss1.str(); + VERIFY( result1 == L"12345" ); + + ng2.put(oss2.rdbuf(), oss2, L'+', l2); + result2 = oss2.str(); + VERIFY( result2 == L"123456,78" ); + + oss3.precision(1); + oss3.setf(ios_base::fixed, ios_base::floatfield); + ng3.put(oss3.rdbuf(), oss3, L'+', d1); + result3 = oss3.str(); + VERIFY( result3 == L"1234,56,7.0" ); +} + +int main() +{ + test01(); + return 0; +}