re PR libstdc++/37958 (num_get<>::do_get(bool) sets eofbit flag incorrectly when boolalpha == true)

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.

From-SVN: r141498
This commit is contained in:
Paolo Carlini 2008-10-31 16:47:48 +00:00 committed by Paolo Carlini
parent d3d0b9e07f
commit 894e47e76e
4 changed files with 261 additions and 17 deletions

View File

@ -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

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}