re PR libstdc++/13171 (Bugs in basic_filebuf::imbue)

2003-11-26  Paolo Carlini  <pcarlini@suse.de>
	    Petur Runolfsson  <peturr02@ru.is>

	PR libstdc++/13171
	* include/bits/fstream.tcc (imbue): Relax the conditions under
	which the function succeeds: allow for two consecutive calls with
	the same name; state dependent encodings are ok even after open
	if at the beginning of the file; don't check seekoff return value
	(pipes, cin, cout, etc...)
	* testsuite/27_io/basic_filebuf/imbue/char/13171-1.cc: New.
	* testsuite/27_io/basic_filebuf/imbue/char/13171-2.cc: New.
	* testsuite/27_io/basic_filebuf/imbue/char/13171-3.cc: New.
	* testsuite/27_io/basic_filebuf/imbue/char/13171-4.cc: New.
	* testsuite/27_io/basic_filebuf/imbue/char/2.cc: Tweak comment.
	* testsuite/27_io/basic_filebuf/imbue/char/3.cc: Likewise.
	* testsuite/27_io/basic_filebuf/imbue/wchar_t/2.cc: Tweak comment.
	* testsuite/27_io/basic_filebuf/imbue/wchar_t/3.cc: Likewise.

	* testsuite/27_io/basic_filebuf/imbue/wchar_t/12868.cc: More
	correctly use the UTF-8 locale appearing in the PR.

Co-Authored-By: Petur Runolfsson <peturr02@ru.is>

From-SVN: r73954
This commit is contained in:
Paolo Carlini 2003-11-26 15:56:40 +00:00 committed by Paolo Carlini
parent 6796826ca4
commit c03d83d499
11 changed files with 260 additions and 28 deletions

View File

@ -1,3 +1,24 @@
2003-11-26 Paolo Carlini <pcarlini@suse.de>
Petur Runolfsson <peturr02@ru.is>
PR libstdc++/13171
* include/bits/fstream.tcc (imbue): Relax the conditions under
which the function succeeds: allow for two consecutive calls with
the same name; state dependent encodings are ok even after open
if at the beginning of the file; don't check seekoff return value
(pipes, cin, cout, etc...)
* testsuite/27_io/basic_filebuf/imbue/char/13171-1.cc: New.
* testsuite/27_io/basic_filebuf/imbue/char/13171-2.cc: New.
* testsuite/27_io/basic_filebuf/imbue/char/13171-3.cc: New.
* testsuite/27_io/basic_filebuf/imbue/char/13171-4.cc: New.
* testsuite/27_io/basic_filebuf/imbue/char/2.cc: Tweak comment.
* testsuite/27_io/basic_filebuf/imbue/char/3.cc: Likewise.
* testsuite/27_io/basic_filebuf/imbue/wchar_t/2.cc: Tweak comment.
* testsuite/27_io/basic_filebuf/imbue/wchar_t/3.cc: Likewise.
* testsuite/27_io/basic_filebuf/imbue/wchar_t/12868.cc: More
correctly use the UTF-8 locale appearing in the PR.
2003-11-26 Paolo Carlini <pcarlini@suse.de> 2003-11-26 Paolo Carlini <pcarlini@suse.de>
* include/bits/locale_facets.h * include/bits/locale_facets.h

View File

@ -744,27 +744,22 @@ namespace std
basic_filebuf<_CharT, _Traits>:: basic_filebuf<_CharT, _Traits>::
imbue(const locale& __loc) imbue(const locale& __loc)
{ {
if (this->getloc() != __loc) bool __testfail = false;
if (this->is_open())
{ {
bool __testfail = false; const pos_type __ret = this->seekoff(0, ios_base::cur,
if (this->is_open()) this->_M_mode);
{ const bool __teststate = __check_facet(_M_codecvt).encoding() == -1;
const bool __testseek = __testfail = __teststate && __ret != pos_type(off_type(0));
this->seekoff(0, ios_base::cur, this->_M_mode) == }
pos_type(off_type(-1));
const bool __teststate =
__check_facet(_M_codecvt).encoding() == -1;
__testfail = __testseek || __teststate; if (!__testfail)
} {
if (__builtin_expect(has_facet<__codecvt_type>(__loc), true))
if (!__testfail) _M_codecvt = &use_facet<__codecvt_type>(__loc);
{ else
if (__builtin_expect(has_facet<__codecvt_type>(__loc), true)) _M_codecvt = 0;
_M_codecvt = &use_facet<__codecvt_type>(__loc);
else
_M_codecvt = 0;
}
} }
} }

View File

@ -0,0 +1,45 @@
// Copyright (C) 2003 Free Software Foundation, Inc.
//
// 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.
// 27.8.1.4 Overridden virtual functions
#include <fstream>
#include <locale>
#include <testsuite_hooks.h>
// libstdc++/13171
void test01()
{
bool test __attribute__((unused)) = true;
using namespace std;
filebuf fb;
fb.pubimbue(__gnu_test::try_named_locale("en_US"));
fb.pubimbue(__gnu_test::try_named_locale("en_US"));
fb.open("tmp_13171-1", ios_base::out);
fb.sputc('F');
fb.pubsync();
fb.close();
}
int main()
{
test01();
}

View File

@ -0,0 +1,63 @@
// Copyright (C) 2003 Free Software Foundation, Inc.
//
// 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.
// 27.8.1.4 Overridden virtual functions
#include <fstream>
#include <locale>
#include <cassert>
#include <sys/types.h>
#include <sys/stat.h>
#include <testsuite_hooks.h>
// libstdc++/13171
void test01()
{
bool test __attribute__((unused)) = true;
using namespace std;
const char* name = "tmp_fifo_13171-2";
unlink(name);
mkfifo(name, S_IRWXU);
int child = fork();
if (child == 0)
{
filebuf fb;
fb.open(name, ios_base::out);
fb.sputc('S');
fb.close();
return;
}
filebuf fb;
fb.pubimbue(__gnu_test::try_named_locale("fr_FR"));
fb.open(name, ios_base::in);
assert(fb.is_open());
fb.pubimbue(__gnu_test::try_named_locale("en_US"));
filebuf::int_type c = fb.sgetc();
assert(c == 'S');
fb.close();
}
int main()
{
test01();
}

View File

@ -0,0 +1,56 @@
// Copyright (C) 2003 Free Software Foundation, Inc.
//
// 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.
// 27.8.1.4 Overridden virtual functions
#include <iostream>
#include <locale>
#include <testsuite_hooks.h>
// libstdc++/13171
void test01()
{
bool test __attribute__((unused)) = true;
using namespace std;
locale::global(__gnu_test::try_named_locale("fr_FR"));
ios_base::sync_with_stdio(false);
locale::global(locale("en_US"));
cin.imbue(locale("en_US"));
cout.imbue(locale("en_US"));
cerr.imbue(locale("en_US"));
clog.imbue(locale("de_DE"));
wcin.imbue(locale("en_US"));
wcout.imbue(locale("en_US"));
wcerr.imbue(locale("en_US"));
wclog.imbue(locale("de_DE"));
cout << 'f' << endl;
cerr << 'r' << endl;
clog << 'A' << endl;
wcout << L's' << endl;
wcerr << L'i' << endl;
wclog << L'L' << endl;
}
int main()
{
test01();
}

View File

@ -0,0 +1,54 @@
// Copyright (C) 2003 Free Software Foundation, Inc.
//
// 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.
// 27.8.1.4 Overridden virtual functions
#include <fstream>
#include <locale>
#include <testsuite_hooks.h>
class Cvt : public std::codecvt<char, char, std::mbstate_t>
{
protected:
int do_encoding() const throw()
{ return -1; }
bool do_always_noconv() const throw()
{ return false; }
};
// libstdc++/13171
int test01()
{
bool test __attribute__((unused)) = true;
using namespace std;
filebuf fb;
fb.pubimbue(locale(__gnu_test::try_named_locale("en_US"),
new Cvt));
fb.open("tmp_13171-4", ios_base::out);
fb.pubimbue(__gnu_test::try_named_locale("fr_FR"));
fb.sputc('N');
fb.pubsync();
fb.close();
}
int main()
{
test01();
}

View File

@ -41,9 +41,7 @@ void test02()
pos_type p = ob.pubseekoff(2, ios_base::beg, ios_base::in); pos_type p = ob.pubseekoff(2, ios_base::beg, ios_base::in);
VERIFY( p != bad); VERIFY( p != bad);
// "if file is not positioned at its beginning" imbue fails // According to 27.5.2.2.1, loc == getloc() after pubimbue(loc).
// but, according to 27.5.2.2.1, p1, still loc == getloc()
// after pubimbue(loc).
locale loc_de = __gnu_test::try_named_locale("de_DE"); locale loc_de = __gnu_test::try_named_locale("de_DE");
locale ret = ob.pubimbue(loc_de); locale ret = ob.pubimbue(loc_de);
VERIFY( ob.getloc() == loc_de ); VERIFY( ob.getloc() == loc_de );

View File

@ -42,7 +42,8 @@ void test03()
ob.pubimbue(loc_s); ob.pubimbue(loc_s);
VERIFY( ob.getloc() == loc_s ); VERIFY( ob.getloc() == loc_s );
// 2 "if encoding of current locale is state dependent" fails... // 2 "if encoding of current locale is state dependent" and
// not at the beginning of the file fails...
locale loc_c = locale::classic(); locale loc_c = locale::classic();
locale ret = ob.pubimbue(loc_s); locale ret = ob.pubimbue(loc_s);
VERIFY( ob.getloc() == loc_s ); VERIFY( ob.getloc() == loc_s );

View File

@ -30,7 +30,7 @@ void test01()
using namespace std; using namespace std;
bool test __attribute__((unused)) = true; bool test __attribute__((unused)) = true;
locale loc_is(__gnu_test::try_named_locale("is_IS")); locale loc_is(__gnu_test::try_named_locale("is_IS.UTF-8"));
{ {
wofstream out("tmp_12868"); wofstream out("tmp_12868");

View File

@ -41,9 +41,7 @@ void test02()
pos_type p = ob.pubseekoff(2, ios_base::beg, ios_base::in); pos_type p = ob.pubseekoff(2, ios_base::beg, ios_base::in);
VERIFY( p != bad); VERIFY( p != bad);
// "if file is not positioned at its beginning" imbue fails // According to 27.5.2.2.1, p1, loc == getloc() after pubimbue(loc).
// but, according to 27.5.2.2.1, p1, still loc == getloc()
// after pubimbue(loc).
locale loc_de = __gnu_test::try_named_locale("de_DE"); locale loc_de = __gnu_test::try_named_locale("de_DE");
locale ret = ob.pubimbue(loc_de); locale ret = ob.pubimbue(loc_de);
VERIFY( ob.getloc() == loc_de ); VERIFY( ob.getloc() == loc_de );

View File

@ -42,7 +42,8 @@ void test03()
ob.pubimbue(loc_s); ob.pubimbue(loc_s);
VERIFY( ob.getloc() == loc_s ); VERIFY( ob.getloc() == loc_s );
// 2 "if encoding of current locale is state dependent" fails... // 2 "if encoding of current locale is state dependent" and
// not at the beginning of the file fails...
locale loc_c = locale::classic(); locale loc_c = locale::classic();
locale ret = ob.pubimbue(loc_s); locale ret = ob.pubimbue(loc_s);
VERIFY( ob.getloc() == loc_s ); VERIFY( ob.getloc() == loc_s );