+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
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;
}
}
--- /dev/null
+// 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();
+}
--- /dev/null
+// 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();
+}
--- /dev/null
+// 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();
+}
--- /dev/null
+// 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();
+}
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 );
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 );
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");
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 );
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 );