diff options
author | Jonathan Wakely <jwakely@redhat.com> | 2015-03-04 17:19:55 +0000 |
---|---|---|
committer | Jonathan Wakely <redi@gcc.gnu.org> | 2015-03-04 17:19:55 +0000 |
commit | b6584a72ac8d305731e1771a05c117dc11a3d553 (patch) | |
tree | 51d24fd829c29cb8633b241a2c12b9fdd9596f15 /libstdc++-v3/testsuite/22_locale | |
parent | d50a26f2bad59ba73c52694190aac02e90423bbd (diff) | |
download | gcc-b6584a72ac8d305731e1771a05c117dc11a3d553.zip gcc-b6584a72ac8d305731e1771a05c117dc11a3d553.tar.gz gcc-b6584a72ac8d305731e1771a05c117dc11a3d553.tar.bz2 |
re PR libstdc++/64797 (22_locale/conversions/string/2.cc FAILs)
PR libstdc++/64797
* include/bits/locale_conv.h (wstring_convert::_M_conv): Handle
incomplete multibyte sequences correctly.
* include/std/codecvt (codecvt_utf8, codecvt_utf16,
codecvt_utf8_utf16): Limit _Maxcode to maximum Unicode code point.
* src/c++11/codecvt.cc (invalid_mb_sequence, incomplete_mb_character):
Define constants.
(is_high_surrogate, is_low_surrogate, surrogate_pair_to_code_point):
Define convenience functions.
(read_utf8_code_point): Return relevant constant to distinguish
incomplete characters from invalid sequences.
(read_utf16_code_point): Likewise. Check for invalid sequences.
(ucs4_in, utf16_in): Use incomplete_mb_character constant.
(utf16_out): Check for invalid sequences.
(utf16_span): Fix condition.
(ucs2_out): Use is_high_surrogate.
(ucs2_in): Use incomplete_mb_character constant and fix condition.
* testsuite/22_locale/codecvt/char16_t.cc: Fix whitespace.
* testsuite/22_locale/conversions/buffer/1.cc: New.
* testsuite/22_locale/conversions/string/2.cc: Use char16_t and
char32_t instead of wchar_t.
* testsuite/22_locale/conversions/string/3.cc: New.
From-SVN: r221189
Diffstat (limited to 'libstdc++-v3/testsuite/22_locale')
4 files changed, 166 insertions, 10 deletions
diff --git a/libstdc++-v3/testsuite/22_locale/codecvt/char16_t.cc b/libstdc++-v3/testsuite/22_locale/codecvt/char16_t.cc index 9271eca..a21a838 100644 --- a/libstdc++-v3/testsuite/22_locale/codecvt/char16_t.cc +++ b/libstdc++-v3/testsuite/22_locale/codecvt/char16_t.cc @@ -79,8 +79,7 @@ test01() codecvt_c16::state_type state01; state01 = {}; - codecvt_base::result res = cvt->out(state01, u16dat, u16dat_end, -from_next, + codecvt_base::result res = cvt->out(state01, u16dat, u16dat_end, from_next, buffer, buffer_end, to_next); VERIFY(res == codecvt_base::ok); diff --git a/libstdc++-v3/testsuite/22_locale/conversions/buffer/1.cc b/libstdc++-v3/testsuite/22_locale/conversions/buffer/1.cc new file mode 100644 index 0000000..f008f5a --- /dev/null +++ b/libstdc++-v3/testsuite/22_locale/conversions/buffer/1.cc @@ -0,0 +1,78 @@ +// { dg-options "-std=gnu++11" } + +// Copyright (C) 2012 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 3, 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 COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +// 22.3.3.2.3 Buffer conversions + +#include <locale> +#include <sstream> +#include <testsuite_hooks.h> + +template<typename Elem> +struct cvt : std::codecvt<Elem, char, std::mbstate_t> { }; + +template<typename Elem> +using buf_conv = std::wbuffer_convert<cvt<Elem>, Elem>; + +using std::string; +using std::stringstream; +using std::wstring; +using std::wstringstream; + +void test01() +{ + buf_conv<wchar_t> buf; + std::stringbuf sbuf; + VERIFY( buf.rdbuf() == nullptr ); + VERIFY( buf.rdbuf(&sbuf) == nullptr ); + VERIFY( buf.rdbuf() == &sbuf ); + VERIFY( buf.rdbuf(nullptr) == &sbuf ); +} + +void test02() +{ + std::stringbuf sbuf; + buf_conv<char> buf(&sbuf); // noconv + + stringstream ss; + ss.std::ios::rdbuf(&buf); + string input = "King for a day..."; + ss << input << std::flush; + string output = sbuf.str(); + VERIFY( input == output ); +} + +void test03() +{ + std::stringbuf sbuf; + buf_conv<wchar_t> buf(&sbuf); + + wstringstream ss; + ss.std::wios::rdbuf(&buf); + wstring input = L"Fool for a lifetime"; + ss << input << std::flush; + string output = sbuf.str(); + VERIFY( output == "Fool for a lifetime" ); +} + +int main() +{ + test01(); + test02(); + test03(); +} diff --git a/libstdc++-v3/testsuite/22_locale/conversions/string/2.cc b/libstdc++-v3/testsuite/22_locale/conversions/string/2.cc index 94eb75f..07d2b52 100644 --- a/libstdc++-v3/testsuite/22_locale/conversions/string/2.cc +++ b/libstdc++-v3/testsuite/22_locale/conversions/string/2.cc @@ -30,26 +30,43 @@ template<typename Elem> using str_conv = std::wstring_convert<cvt<Elem>, Elem>; using std::string; -using std::wstring; +using std::u16string; +using std::u32string; // test conversion errors, with and without error strings void test01() { - typedef str_conv<wchar_t> sc; + typedef str_conv<char16_t> sc; const sc::byte_string berr = "invalid wide string"; - const sc::wide_string werr = L"invalid byte string"; + const sc::wide_string werr = u"invalid byte string"; sc c(berr, werr); string input = "Stop"; + input += char(0xFF); + u16string woutput = c.from_bytes(input); + VERIFY( werr == woutput ); + u16string winput = u"Stop"; + winput += char16_t(0xDC00); + string output = c.to_bytes(winput); + VERIFY( berr == output ); +} + +void test02() +{ + typedef str_conv<char32_t> sc; + + const sc::byte_string berr = "invalid wide string"; + const sc::wide_string werr = U"invalid byte string"; + + sc c(berr, werr); + string input = "Halt"; input += char(0xff); - input += char(0xff); - wstring woutput = c.from_bytes(input); + u32string woutput = c.from_bytes(input); VERIFY( werr == woutput ); - wstring winput = L"Stop"; - winput += wchar_t(0xff); - winput += wchar_t(0xff); + u32string winput = U"Halt"; + winput += char32_t(-1); string output = c.to_bytes(winput); VERIFY( berr == output ); } @@ -57,4 +74,5 @@ void test01() int main() { test01(); + test02(); } diff --git a/libstdc++-v3/testsuite/22_locale/conversions/string/3.cc b/libstdc++-v3/testsuite/22_locale/conversions/string/3.cc new file mode 100644 index 0000000..7c4ac20 --- /dev/null +++ b/libstdc++-v3/testsuite/22_locale/conversions/string/3.cc @@ -0,0 +1,61 @@ +// { dg-options "-std=gnu++11" } + +// Copyright (C) 2012 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 3, 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 COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +// 22.3.3.2.2 String conversions + +#include <locale> +#include <string> +#include <testsuite_hooks.h> + +template<typename Elem> +struct cvt : std::codecvt<Elem, char, std::mbstate_t> { }; + +template<typename Elem> +using str_conv = std::wstring_convert<cvt<Elem>, Elem>; + +using std::string; +using std::u32string; + +// test construction with state, for partial conversions + +void test01() +{ + typedef str_conv<char32_t> wsc; + + wsc c; + string input = u8"\u00a3 shillings pence"; + u32string woutput = c.from_bytes(input.substr(0, 1)); + auto partial_state = c.state(); + auto partial_count = c.converted(); + + auto woutput2 = c.from_bytes("state reset on next conversion"); + VERIFY( woutput2 == U"state reset on next conversion" ); + + wsc c2(new cvt<char32_t>, partial_state); + woutput += c2.from_bytes(input.substr(partial_count)); + VERIFY( U"\u00a3 shillings pence" == woutput ); + + string roundtrip = c2.to_bytes(woutput); + VERIFY( input == roundtrip ); +} + +int main() +{ + test01(); +} |