diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 9e502e7b04d..f94f6b8a57f 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,24 @@ +2003-11-26 Paolo Carlini + Petur Runolfsson + + 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 * include/bits/locale_facets.h diff --git a/libstdc++-v3/include/bits/fstream.tcc b/libstdc++-v3/include/bits/fstream.tcc index 0e1e36d3e4c..aee725ebbf8 100644 --- a/libstdc++-v3/include/bits/fstream.tcc +++ b/libstdc++-v3/include/bits/fstream.tcc @@ -744,27 +744,22 @@ namespace std basic_filebuf<_CharT, _Traits>:: imbue(const locale& __loc) { - if (this->getloc() != __loc) + bool __testfail = false; + + if (this->is_open()) { - bool __testfail = false; - if (this->is_open()) - { - const bool __testseek = - this->seekoff(0, ios_base::cur, this->_M_mode) == - pos_type(off_type(-1)); - const bool __teststate = - __check_facet(_M_codecvt).encoding() == -1; + const pos_type __ret = this->seekoff(0, ios_base::cur, + this->_M_mode); + const bool __teststate = __check_facet(_M_codecvt).encoding() == -1; + __testfail = __teststate && __ret != pos_type(off_type(0)); + } - __testfail = __testseek || __teststate; - } - - if (!__testfail) - { - if (__builtin_expect(has_facet<__codecvt_type>(__loc), true)) - _M_codecvt = &use_facet<__codecvt_type>(__loc); - else - _M_codecvt = 0; - } + if (!__testfail) + { + if (__builtin_expect(has_facet<__codecvt_type>(__loc), true)) + _M_codecvt = &use_facet<__codecvt_type>(__loc); + else + _M_codecvt = 0; } } diff --git a/libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/char/13171-1.cc b/libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/char/13171-1.cc new file mode 100644 index 00000000000..672394ac829 --- /dev/null +++ b/libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/char/13171-1.cc @@ -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 +#include +#include + +// 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(); +} diff --git a/libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/char/13171-2.cc b/libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/char/13171-2.cc new file mode 100644 index 00000000000..65190ada681 --- /dev/null +++ b/libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/char/13171-2.cc @@ -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 +#include +#include + +#include +#include + +#include + +// 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(); +} diff --git a/libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/char/13171-3.cc b/libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/char/13171-3.cc new file mode 100644 index 00000000000..b96009e5c5f --- /dev/null +++ b/libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/char/13171-3.cc @@ -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 +#include +#include + +// 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(); +} diff --git a/libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/char/13171-4.cc b/libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/char/13171-4.cc new file mode 100644 index 00000000000..497a35fea72 --- /dev/null +++ b/libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/char/13171-4.cc @@ -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 +#include +#include + +class Cvt : public std::codecvt +{ +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(); +} diff --git a/libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/char/2.cc b/libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/char/2.cc index 422ec85c0b6..14842bc6fc7 100644 --- a/libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/char/2.cc +++ b/libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/char/2.cc @@ -41,9 +41,7 @@ void test02() pos_type p = ob.pubseekoff(2, ios_base::beg, ios_base::in); VERIFY( p != bad); - // "if file is not positioned at its beginning" imbue fails - // but, according to 27.5.2.2.1, p1, still loc == getloc() - // after pubimbue(loc). + // According to 27.5.2.2.1, loc == getloc() after pubimbue(loc). locale loc_de = __gnu_test::try_named_locale("de_DE"); locale ret = ob.pubimbue(loc_de); VERIFY( ob.getloc() == loc_de ); diff --git a/libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/char/3.cc b/libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/char/3.cc index 0cd5d0f27fd..868ea59cea9 100644 --- a/libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/char/3.cc +++ b/libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/char/3.cc @@ -42,7 +42,8 @@ void test03() ob.pubimbue(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 ret = ob.pubimbue(loc_s); VERIFY( ob.getloc() == loc_s ); diff --git a/libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/wchar_t/12868.cc b/libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/wchar_t/12868.cc index 8e4484b1472..67fccda2099 100644 --- a/libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/wchar_t/12868.cc +++ b/libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/wchar_t/12868.cc @@ -30,7 +30,7 @@ void test01() using namespace std; 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"); diff --git a/libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/wchar_t/2.cc b/libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/wchar_t/2.cc index 0879de899a8..1def258c7d6 100644 --- a/libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/wchar_t/2.cc +++ b/libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/wchar_t/2.cc @@ -41,9 +41,7 @@ void test02() pos_type p = ob.pubseekoff(2, ios_base::beg, ios_base::in); VERIFY( p != bad); - // "if file is not positioned at its beginning" imbue fails - // but, according to 27.5.2.2.1, p1, still loc == getloc() - // after pubimbue(loc). + // According to 27.5.2.2.1, p1, loc == getloc() after pubimbue(loc). locale loc_de = __gnu_test::try_named_locale("de_DE"); locale ret = ob.pubimbue(loc_de); VERIFY( ob.getloc() == loc_de ); diff --git a/libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/wchar_t/3.cc b/libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/wchar_t/3.cc index 067e48784b2..5825f63fb23 100644 --- a/libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/wchar_t/3.cc +++ b/libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/wchar_t/3.cc @@ -42,7 +42,8 @@ void test03() ob.pubimbue(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 ret = ob.pubimbue(loc_s); VERIFY( ob.getloc() == loc_s );