aboutsummaryrefslogtreecommitdiff
path: root/libstdc++-v3
diff options
context:
space:
mode:
Diffstat (limited to 'libstdc++-v3')
-rw-r--r--libstdc++-v3/ChangeLog8
-rw-r--r--libstdc++-v3/include/bits/locale_facets.tcc52
-rw-r--r--libstdc++-v3/testsuite/22_locale/num_get/get/char/37958.cc109
-rw-r--r--libstdc++-v3/testsuite/22_locale/num_get/get/wchar_t/37958.cc109
4 files changed, 261 insertions, 17 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 4230bc6..8499395 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,11 @@
+2008-10-31 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR libstdc++/37958
+ * include/bits/locale_facets.tcc (num_get<>::do_get(iter_type,
+ iter_type, ios_base&, ios_base::iostate&, bool&): Fix.
+ * testsuite/22_locale/num_get/get/char/37958.cc: New.
+ * testsuite/22_locale/num_get/get/wchar_t/37958.cc: Likewise.
+
2008-10-27 Paolo Carlini <paolo.carlini@oracle.com>
PR libstdc++/37919
diff --git a/libstdc++-v3/include/bits/locale_facets.tcc b/libstdc++-v3/include/bits/locale_facets.tcc
index 130aa91..1052e03 100644
--- a/libstdc++-v3/include/bits/locale_facets.tcc
+++ b/libstdc++-v3/include/bits/locale_facets.tcc
@@ -599,55 +599,73 @@ _GLIBCXX_BEGIN_LDBL_NAMESPACE
else
{
// Parse bool values as alphanumeric.
- typedef __numpunct_cache<_CharT> __cache_type;
+ typedef __numpunct_cache<_CharT> __cache_type;
__use_cache<__cache_type> __uc;
const locale& __loc = __io._M_getloc();
const __cache_type* __lc = __uc(__loc);
- bool __testf = true;
- bool __testt = true;
+ bool __testf = false;
+ bool __donef = false;
+ bool __testt = false;
+ bool __donet = false;
size_t __n;
bool __testeof = __beg == __end;
for (__n = 0; !__testeof; ++__n)
{
const char_type __c = *__beg;
- if (__testf)
- {
+ if (!__donef)
+ {
if (__n < __lc->_M_falsename_size)
- __testf = __c == __lc->_M_falsename[__n];
+ {
+ __testf = __c == __lc->_M_falsename[__n];
+ if (!__testf)
+ __donef = true;
+ }
else
- break;
+ __donef = true;
}
- if (__testt)
- {
+ if (!__donet)
+ {
if (__n < __lc->_M_truename_size)
- __testt = __c == __lc->_M_truename[__n];
+ {
+ __testt = __c == __lc->_M_truename[__n];
+ if (!__testt)
+ __donet = true;
+ }
else
- break;
+ __donet = true;
}
- if (!__testf && !__testt)
+ if (__donef && __donet)
break;
if (++__beg == __end)
__testeof = true;
}
if (__testf && __n == __lc->_M_falsename_size)
- __v = false;
+ {
+ __v = false;
+ if (__testt && __n == __lc->_M_truename_size)
+ __err = ios_base::failbit;
+ else
+ __err = __donet ? ios_base::goodbit : ios_base::eofbit;
+ }
else if (__testt && __n == __lc->_M_truename_size)
- __v = true;
+ {
+ __v = true;
+ __err = __donef ? ios_base::goodbit : ios_base::eofbit;
+ }
else
{
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 23. Num_get overflow result.
__v = false;
__err = ios_base::failbit;
+ if (__testeof && __n)
+ __err |= ios_base::eofbit;
}
-
- if (__testeof)
- __err |= ios_base::eofbit;
}
return __beg;
}
diff --git a/libstdc++-v3/testsuite/22_locale/num_get/get/char/37958.cc b/libstdc++-v3/testsuite/22_locale/num_get/get/char/37958.cc
new file mode 100644
index 0000000..6e93170
--- /dev/null
+++ b/libstdc++-v3/testsuite/22_locale/num_get/get/char/37958.cc
@@ -0,0 +1,109 @@
+// 2008-10-31 Paolo Carlini <paolo.carlini@oracle.com>
+
+// Copyright (C) 2008 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 <locale>
+#include <sstream>
+#include <testsuite_hooks.h>
+
+struct Punct1: std::numpunct<char>
+{
+ std::string do_truename() const { return "a"; }
+ std::string do_falsename() const { return "abb"; }
+};
+
+struct Punct2: std::numpunct<char>
+{
+ std::string do_truename() const { return "1"; }
+ std::string do_falsename() const { return "0"; }
+};
+
+struct Punct3: std::numpunct<char>
+{
+ std::string do_truename() const { return ""; }
+ std::string do_falsename() const { return ""; }
+};
+
+// libstdc++/37958
+void test01()
+{
+ using namespace std;
+ typedef istreambuf_iterator<char> iterator_type;
+
+ bool test __attribute__((unused)) = true;
+
+ 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<char>& ng1 = use_facet<num_get<char> >(iss1.getloc());
+ const num_get<char>& ng2 = use_facet<num_get<char> >(iss2.getloc());
+ const num_get<char>& ng3 = use_facet<num_get<char> >(iss3.getloc());
+
+ ios_base::iostate err = ios_base::goodbit;
+ iterator_type end;
+ bool b1 = false;
+ bool b2 = false;
+ bool b3 = true;
+
+ iss1.str("a");
+ iss1.setf(ios_base::boolalpha);
+ err = ios_base::goodbit;
+ end = ng1.get(iss1.rdbuf(), 0, iss1, err, b1);
+ VERIFY( err == ios_base::eofbit );
+ VERIFY( b1 == true );
+
+ iss1.str("abb");
+ iss1.clear();
+ err = ios_base::goodbit;
+ end = ng1.get(iss1.rdbuf(), 0, iss1, err, b1);
+ VERIFY( err == ios_base::goodbit );
+ VERIFY( b1 == false );
+
+ iss1.str("abc");
+ iss1.clear();
+ err = ios_base::goodbit;
+ end = ng1.get(iss1.rdbuf(), 0, iss1, err, b1);
+ VERIFY( err == ios_base::failbit );
+ VERIFY( b1 == false );
+ VERIFY( *end == 'c' );
+
+ iss2.str("1");
+ iss2.setf(ios_base::boolalpha);
+ err = ios_base::goodbit;
+ end = ng2.get(iss2.rdbuf(), 0, iss2, err, b2);
+ VERIFY( err == ios_base::goodbit );
+ VERIFY( b2 == true );
+
+ iss3.str("blah");
+ iss3.setf(ios_base::boolalpha);
+ err = ios_base::goodbit;
+ end = ng3.get(iss3.rdbuf(), 0, iss3, err, b3);
+ VERIFY( err == ios_base::failbit );
+ VERIFY( b3 == false );
+ VERIFY( *end == 'b' );
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/22_locale/num_get/get/wchar_t/37958.cc b/libstdc++-v3/testsuite/22_locale/num_get/get/wchar_t/37958.cc
new file mode 100644
index 0000000..a9ce6df
--- /dev/null
+++ b/libstdc++-v3/testsuite/22_locale/num_get/get/wchar_t/37958.cc
@@ -0,0 +1,109 @@
+// 2008-10-31 Paolo Carlini <paolo.carlini@oracle.com>
+
+// Copyright (C) 2008 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 <locale>
+#include <sstream>
+#include <testsuite_hooks.h>
+
+struct Punct1: std::numpunct<wchar_t>
+{
+ std::wstring do_truename() const { return L"a"; }
+ std::wstring do_falsename() const { return L"abb"; }
+};
+
+struct Punct2: std::numpunct<wchar_t>
+{
+ std::wstring do_truename() const { return L"1"; }
+ std::wstring do_falsename() const { return L"0"; }
+};
+
+struct Punct3: std::numpunct<wchar_t>
+{
+ std::wstring do_truename() const { return L""; }
+ std::wstring do_falsename() const { return L""; }
+};
+
+// libstdc++/37958
+void test01()
+{
+ using namespace std;
+ typedef istreambuf_iterator<wchar_t> iterator_type;
+
+ bool test __attribute__((unused)) = true;
+
+ 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<wchar_t>& ng1 = use_facet<num_get<wchar_t> >(iss1.getloc());
+ const num_get<wchar_t>& ng2 = use_facet<num_get<wchar_t> >(iss2.getloc());
+ const num_get<wchar_t>& ng3 = use_facet<num_get<wchar_t> >(iss3.getloc());
+
+ ios_base::iostate err = ios_base::goodbit;
+ iterator_type end;
+ bool b1 = false;
+ bool b2 = false;
+ bool b3 = true;
+
+ iss1.str(L"a");
+ iss1.setf(ios_base::boolalpha);
+ err = ios_base::goodbit;
+ end = ng1.get(iss1.rdbuf(), 0, iss1, err, b1);
+ VERIFY( err == ios_base::eofbit );
+ VERIFY( b1 == true );
+
+ iss1.str(L"abb");
+ iss1.clear();
+ err = ios_base::goodbit;
+ end = ng1.get(iss1.rdbuf(), 0, iss1, err, b1);
+ VERIFY( err == ios_base::goodbit );
+ VERIFY( b1 == false );
+
+ iss1.str(L"abc");
+ iss1.clear();
+ err = ios_base::goodbit;
+ end = ng1.get(iss1.rdbuf(), 0, iss1, err, b1);
+ VERIFY( err == ios_base::failbit );
+ VERIFY( b1 == false );
+ VERIFY( *end == L'c' );
+
+ iss2.str(L"1");
+ iss2.setf(ios_base::boolalpha);
+ err = ios_base::goodbit;
+ end = ng2.get(iss2.rdbuf(), 0, iss2, err, b2);
+ VERIFY( err == ios_base::goodbit );
+ VERIFY( b2 == true );
+
+ iss3.str(L"blah");
+ iss3.setf(ios_base::boolalpha);
+ err = ios_base::goodbit;
+ end = ng3.get(iss3.rdbuf(), 0, iss3, err, b3);
+ VERIFY( err == ios_base::failbit );
+ VERIFY( b3 == false );
+ VERIFY( *end == L'b' );
+}
+
+int main()
+{
+ test01();
+ return 0;
+}