re PR libstdc++/13171 (Bugs in basic_filebuf::imbue)
authorPaolo Carlini <pcarlini@suse.de>
Wed, 26 Nov 2003 15:56:40 +0000 (15:56 +0000)
committerPaolo Carlini <paolo@gcc.gnu.org>
Wed, 26 Nov 2003 15:56:40 +0000 (15:56 +0000)
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

libstdc++-v3/ChangeLog
libstdc++-v3/include/bits/fstream.tcc
libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/char/13171-1.cc [new file with mode: 0644]
libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/char/13171-2.cc [new file with mode: 0644]
libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/char/13171-3.cc [new file with mode: 0644]
libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/char/13171-4.cc [new file with mode: 0644]
libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/char/2.cc
libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/char/3.cc
libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/wchar_t/12868.cc
libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/wchar_t/2.cc
libstdc++-v3/testsuite/27_io/basic_filebuf/imbue/wchar_t/3.cc

index 9e502e7b04dd1f0810f46782ec702390ddb66d98..f94f6b8a57f887d84013103d08dc546b504c5e2d 100644 (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>
 
        * include/bits/locale_facets.h
index 0e1e36d3e4c6a9673f5ef138d9c3fd8c34df8e9a..aee725ebbf8d70be0a79ce7f8e5efabd3e0a23b0 100644 (file)
@@ -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())
-           {
-             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;
+      bool __testfail = false;
 
-             __testfail = __testseek || __teststate;
-           }
+      if (this->is_open())
+       {
+         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));
+       }
 
-         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 (file)
index 0000000..672394a
--- /dev/null
@@ -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();
+}
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 (file)
index 0000000..65190ad
--- /dev/null
@@ -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();
+}
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 (file)
index 0000000..b96009e
--- /dev/null
@@ -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();
+}
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 (file)
index 0000000..497a35f
--- /dev/null
@@ -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();
+}
index 422ec85c0b614ccffe2d89853c9920a05d09e8e5..14842bc6fc70113ce3ee7c5a1bdb27d566747ee4 100644 (file)
@@ -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 );
index 0cd5d0f27fd36eb24022209fc80743df49a076a4..868ea59cea9c47da4c18ee33a5fb47a6e6c553c9 100644 (file)
@@ -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 );
index 8e4484b1472320e80ea60a4d8330ad17db16a7c9..67fccda2099208606ba70d0082fd0ef7bb81f5db 100644 (file)
@@ -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");
index 0879de899a820fbe9bbabf24574b21e6ea012580..1def258c7d639cf4c8e22f9dd1d9697daefbe990 100644 (file)
@@ -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 );
index 067e48784b25a25b92d1622326e4ca30a94b221a..5825f63fb23ffabc891e6ae9726a4330b0fcf916 100644 (file)
@@ -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 );