aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPetur Runolfsson <peturr02@ru.is>2003-03-07 17:24:47 +0000
committerBenjamin Kosnik <bkoz@gcc.gnu.org>2003-03-07 17:24:47 +0000
commit5040d6912ccf32e1b3baed1e0a2d9dd475bbf853 (patch)
tree3638203253ada01c3aff257220d05fc1709d6cbb
parentdfa7f440a0707790955bb04b0cb3096d9a647798 (diff)
downloadgcc-5040d6912ccf32e1b3baed1e0a2d9dd475bbf853.zip
gcc-5040d6912ccf32e1b3baed1e0a2d9dd475bbf853.tar.gz
gcc-5040d6912ccf32e1b3baed1e0a2d9dd475bbf853.tar.bz2
re PR libstdc++/9817 (collate::compare doesn't handle nul characters.)
2003-03-07 Petur Runolfsson <peturr02@ru.is> PR libstdc++/9817 * include/bits/locale_facets.tcc (collate::do_compare, collate::do_transform): Handle nul characters in input. * testsuite/22_locale/collate/compare/char/3.cc: New test. * testsuite/22_locale/collate/compare/wchar_t/3.cc: New test. * testsuite/22_locale/collate/transform/char/3.cc: New test. * testsuite/22_locale/collate/transform/wchar_t/3.cc: New test. From-SVN: r63946
-rw-r--r--libstdc++-v3/ChangeLog11
-rw-r--r--libstdc++-v3/include/bits/locale_facets.tcc74
-rw-r--r--libstdc++-v3/testsuite/22_locale/collate/compare/char/3.cc90
-rw-r--r--libstdc++-v3/testsuite/22_locale/collate/compare/wchar_t/3.cc90
-rw-r--r--libstdc++-v3/testsuite/22_locale/collate/transform/char/3.cc93
-rw-r--r--libstdc++-v3/testsuite/22_locale/collate/transform/wchar_t/3.cc93
6 files changed, 440 insertions, 11 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 2162fc8..763b573 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,14 @@
+2003-03-07 Petur Runolfsson <peturr02@ru.is>
+
+ PR libstdc++/9817
+ * include/bits/locale_facets.tcc
+ (collate::do_compare, collate::do_transform):
+ Handle nul characters in input.
+ * testsuite/22_locale/collate/compare/char/3.cc: New test.
+ * testsuite/22_locale/collate/compare/wchar_t/3.cc: New test.
+ * testsuite/22_locale/collate/transform/char/3.cc: New test.
+ * testsuite/22_locale/collate/transform/wchar_t/3.cc: New test.
+
2003-03-07 Jerry Quinn <jlquinn@optonline.net>
* include/bits/streambuf_iterator.h (_M_put): Set _M_failed if
diff --git a/libstdc++-v3/include/bits/locale_facets.tcc b/libstdc++-v3/include/bits/locale_facets.tcc
index cb6dccd..b5b1f5c2 100644
--- a/libstdc++-v3/include/bits/locale_facets.tcc
+++ b/libstdc++-v3/include/bits/locale_facets.tcc
@@ -2038,9 +2038,37 @@ namespace std
do_compare(const _CharT* __lo1, const _CharT* __hi1,
const _CharT* __lo2, const _CharT* __hi2) const
{
+ // strcoll assumes zero-terminated strings so we make a copy
+ // and then put a zero at the end.
const string_type __one(__lo1, __hi1);
const string_type __two(__lo2, __hi2);
- return _M_compare(__one.c_str(), __two.c_str());
+
+ const _CharT* __p = __one.c_str();
+ const _CharT* __pend = __one.c_str() + __one.length();
+ const _CharT* __q = __two.c_str();
+ const _CharT* __qend = __two.c_str() + __two.length();
+
+ // strcoll stops when it sees a nul character so we break
+ // the strings into zero-terminated substrings and pass those
+ // to strcoll.
+ for (;;)
+ {
+ int __res = _M_compare(__p, __q);
+ if (__res)
+ return __res;
+
+ __p += char_traits<_CharT>::length(__p);
+ __q += char_traits<_CharT>::length(__q);
+ if (__p == __pend && __q == __qend)
+ return 0;
+ else if (__p == __pend)
+ return -1;
+ else if (__q == __qend)
+ return 1;
+
+ __p++;
+ __q++;
+ }
}
template<typename _CharT>
@@ -2048,19 +2076,43 @@ namespace std
collate<_CharT>::
do_transform(const _CharT* __lo, const _CharT* __hi) const
{
+ // strxfrm assumes zero-terminated strings so we make a copy
+ string_type __str(__lo, __hi);
+
+ const _CharT* __p = __str.c_str();
+ const _CharT* __pend = __str.c_str() + __str.length();
+
size_t __len = (__hi - __lo) * 2;
- // First try a buffer perhaps big enough.
- _CharT* __c =
- static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __len));
- size_t __res = _M_transform(__c, __lo, __len);
- // If the buffer was not large enough, try again with the correct size.
- if (__res >= __len)
+
+ string_type __ret;
+
+ // strxfrm stops when it sees a nul character so we break
+ // the string into zero-terminated substrings and pass those
+ // to strxfrm.
+ for (;;)
{
- __c = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
- * (__res + 1)));
- _M_transform(__c, __lo, __res + 1);
+ // First try a buffer perhaps big enough.
+ _CharT* __c =
+ static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __len));
+ size_t __res = _M_transform(__c, __p, __len);
+ // If the buffer was not large enough, try again with the
+ // correct size.
+ if (__res >= __len)
+ {
+ __len = __res + 1;
+ __c = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
+ * __len));
+ __res = _M_transform(__c, __p, __res + 1);
+ }
+
+ __ret.append(__c, __res);
+ __p += char_traits<_CharT>::length(__p);
+ if (__p == __pend)
+ return __ret;
+
+ __p++;
+ __ret.push_back(_CharT());
}
- return string_type(__c);
}
template<typename _CharT>
diff --git a/libstdc++-v3/testsuite/22_locale/collate/compare/char/3.cc b/libstdc++-v3/testsuite/22_locale/collate/compare/char/3.cc
new file mode 100644
index 0000000..0cce392
--- /dev/null
+++ b/libstdc++-v3/testsuite/22_locale/collate/compare/char/3.cc
@@ -0,0 +1,90 @@
+// 2003-02-24 Petur Runolfsson <peturr02@ru.is>
+
+// Copyright (C) 2003 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 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.
+
+// 22.2.4.1.1 collate members
+
+#include <locale>
+#include <testsuite_hooks.h>
+
+// Test handling of strings containing nul characters
+void test03()
+{
+ using namespace std;
+ typedef std::collate<char>::string_type string_type;
+
+ bool test = true;
+
+ // basic construction
+ locale loc_c = locale::classic();
+ locale loc_de("de_DE");
+ VERIFY( loc_c != loc_de );
+
+ // cache the collate facets
+ const collate<char>& coll_c = use_facet<collate<char> >(loc_c);
+ const collate<char>& coll_de = use_facet<collate<char> >(loc_de);
+
+ // int compare(const charT*, const charT*, const charT*, const charT*) const
+ const char* strlit1 = "a\0a\0";
+ const char* strlit2 = "a\0b\0";
+ const char* strlit3 = "a\0\xc4\0";
+ const char* strlit4 = "a\0B\0";
+ const char* strlit5 = "aa\0";
+ const char* strlit6 = "b\0a\0";
+
+ int i;
+ i = coll_c.compare(strlit1, strlit1 + 3, strlit2, strlit2 + 3);
+ VERIFY( i == -1 );
+
+ i = coll_de.compare(strlit1, strlit1 + 3, strlit2, strlit2 + 3);
+ VERIFY( i == -1 );
+
+ i = coll_c.compare(strlit3, strlit3 + 3, strlit4, strlit4 + 3);
+ VERIFY( i == 1 );
+
+ i = coll_de.compare(strlit3, strlit3 + 3, strlit4, strlit4 + 3);
+ VERIFY( i == -1 );
+
+ i = coll_c.compare(strlit1, strlit1 + 3, strlit1, strlit1 + 4);
+ VERIFY( i == -1 );
+
+ i = coll_de.compare(strlit3, strlit3 + 4, strlit3, strlit3 + 3);
+ VERIFY( i == 1 );
+
+ i = coll_c.compare(strlit1, strlit1 + 4, strlit4, strlit4 + 1);
+ VERIFY( i == 1 );
+
+ i = coll_de.compare(strlit3, strlit3 + 3, strlit3, strlit3 + 3);
+ VERIFY( i == 0 );
+
+ i = coll_c.compare(strlit1, strlit1 + 2, strlit1, strlit1 + 4);
+ VERIFY( i == -1 );
+
+ i = coll_de.compare(strlit1, strlit1 + 3, strlit5, strlit5 + 3);
+ VERIFY( i == -1 );
+
+ i = coll_c.compare(strlit6, strlit6 + 3, strlit1, strlit1 + 3);
+ VERIFY( i == 1 );
+}
+
+int main()
+{
+ test03();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/22_locale/collate/compare/wchar_t/3.cc b/libstdc++-v3/testsuite/22_locale/collate/compare/wchar_t/3.cc
new file mode 100644
index 0000000..0f9ee64
--- /dev/null
+++ b/libstdc++-v3/testsuite/22_locale/collate/compare/wchar_t/3.cc
@@ -0,0 +1,90 @@
+// 2003-02-24 Petur Runolfsson <peturr02@ru.is>
+
+// Copyright (C) 2003 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 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.
+
+// 22.2.4.1.1 collate members
+
+#include <locale>
+#include <testsuite_hooks.h>
+
+// Test handling of strings containing nul characters
+void test03()
+{
+ using namespace std;
+ typedef std::collate<wchar_t>::string_type string_type;
+
+ bool test = true;
+
+ // basic construction
+ locale loc_c = locale::classic();
+ locale loc_de("de_DE");
+ VERIFY( loc_c != loc_de );
+
+ // cache the collate facets
+ const collate<wchar_t>& coll_c = use_facet<collate<wchar_t> >(loc_c);
+ const collate<wchar_t>& coll_de = use_facet<collate<wchar_t> >(loc_de);
+
+ // int compare(const charT*, const charT*, const charT*, const charT*) const
+ const wchar_t* strlit1 = L"a\0a\0";
+ const wchar_t* strlit2 = L"a\0b\0";
+ const wchar_t* strlit3 = L"a\0\xc4\0";
+ const wchar_t* strlit4 = L"a\0B\0";
+ const wchar_t* strlit5 = L"aa\0";
+ const wchar_t* strlit6 = L"b\0a\0";
+
+ int i;
+ i = coll_c.compare(strlit1, strlit1 + 3, strlit2, strlit2 + 3);
+ VERIFY( i == -1 );
+
+ i = coll_de.compare(strlit1, strlit1 + 3, strlit2, strlit2 + 3);
+ VERIFY( i == -1 );
+
+ i = coll_c.compare(strlit3, strlit3 + 3, strlit4, strlit4 + 3);
+ VERIFY( i == 1 );
+
+ i = coll_de.compare(strlit3, strlit3 + 3, strlit4, strlit4 + 3);
+ VERIFY( i == -1 );
+
+ i = coll_c.compare(strlit1, strlit1 + 3, strlit1, strlit1 + 4);
+ VERIFY( i == -1 );
+
+ i = coll_de.compare(strlit3, strlit3 + 4, strlit3, strlit3 + 3);
+ VERIFY( i == 1 );
+
+ i = coll_c.compare(strlit1, strlit1 + 4, strlit4, strlit4 + 1);
+ VERIFY( i == 1 );
+
+ i = coll_de.compare(strlit3, strlit3 + 3, strlit3, strlit3 + 3);
+ VERIFY( i == 0 );
+
+ i = coll_c.compare(strlit1, strlit1 + 2, strlit1, strlit1 + 4);
+ VERIFY( i == -1 );
+
+ i = coll_de.compare(strlit1, strlit1 + 3, strlit5, strlit5 + 3);
+ VERIFY( i == -1 );
+
+ i = coll_c.compare(strlit6, strlit6 + 3, strlit1, strlit1 + 3);
+ VERIFY( i == 1 );
+}
+
+int main()
+{
+ test03();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/22_locale/collate/transform/char/3.cc b/libstdc++-v3/testsuite/22_locale/collate/transform/char/3.cc
new file mode 100644
index 0000000..a6255af
--- /dev/null
+++ b/libstdc++-v3/testsuite/22_locale/collate/transform/char/3.cc
@@ -0,0 +1,93 @@
+// 2003-02-24 Petur Runolfsson <peturr02@ru.is>
+
+// Copyright (C) 2003 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 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.
+
+// 22.2.4.1.1 collate members
+
+#include <locale>
+#include <testsuite_hooks.h>
+
+void test03()
+{
+ using namespace std;
+ typedef std::collate<char>::string_type string_type;
+
+ bool test = true;
+
+ // basic construction
+ locale loc_c = locale::classic();
+ locale loc_de("de_DE");
+ VERIFY( loc_c != loc_de );
+
+ // cache the collate facets
+ const collate<char>& coll_c = use_facet<collate<char> >(loc_c);
+ const collate<char>& coll_de = use_facet<collate<char> >(loc_de);
+
+ const char* strlit1 = "a\0a\0";
+ const char* strlit2 = "a\0b\0";
+ const char* strlit3 = "a\0\xc4\0";
+ const char* strlit4 = "a\0B\0";
+ const char* strlit5 = "aa\0";
+ const char* strlit6 = "b\0a\0";
+
+ int i;
+ string_type str1;
+ string_type str2;
+
+ str1 = coll_c.transform(strlit1, strlit1 + 3);
+ str2 = coll_c.transform(strlit2, strlit2 + 3);
+ i = str1.compare(str2);
+ VERIFY( i < 0 );
+
+ str1 = coll_de.transform(strlit1, strlit1 + 3);
+ str2 = coll_de.transform(strlit2, strlit2 + 3);
+ i = str1.compare(str2);
+ VERIFY( i < 0 );
+
+ str1 = coll_c.transform(strlit3, strlit3 + 3);
+ str2 = coll_c.transform(strlit4, strlit4 + 3);
+ i = str1.compare(str2);
+ VERIFY( i > 0 );
+
+ str1 = coll_de.transform(strlit3, strlit3 + 3);
+ str2 = coll_de.transform(strlit4, strlit4 + 3);
+ i = str1.compare(str2);
+ VERIFY( i < 0 );
+
+ str1 = coll_c.transform(strlit1, strlit1 + 1);
+ str2 = coll_c.transform(strlit5, strlit5 + 1);
+ i = str1.compare(str2);
+ VERIFY( i == 0 );
+
+ str1 = coll_de.transform(strlit6, strlit6 + 3);
+ str2 = coll_de.transform(strlit1, strlit1 + 3);
+ i = str1.compare(str2);
+ VERIFY( i > 0 );
+
+ str1 = coll_c.transform(strlit1, strlit1 + 3);
+ str2 = coll_c.transform(strlit5, strlit5 + 3);
+ i = str1.compare(str2);
+ VERIFY( i < 0 );
+}
+
+int main()
+{
+ test03();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/22_locale/collate/transform/wchar_t/3.cc b/libstdc++-v3/testsuite/22_locale/collate/transform/wchar_t/3.cc
new file mode 100644
index 0000000..108c0a4
--- /dev/null
+++ b/libstdc++-v3/testsuite/22_locale/collate/transform/wchar_t/3.cc
@@ -0,0 +1,93 @@
+// 2003-02-24 Petur Runolfsson <peturr02@ru.is>
+
+// Copyright (C) 2003 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 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.
+
+// 22.2.4.1.1 collate members
+
+#include <locale>
+#include <testsuite_hooks.h>
+
+void test03()
+{
+ using namespace std;
+ typedef std::collate<wchar_t>::string_type string_type;
+
+ bool test = true;
+
+ // basic construction
+ locale loc_c = locale::classic();
+ locale loc_de("de_DE");
+ VERIFY( loc_c != loc_de );
+
+ // cache the collate facets
+ const collate<wchar_t>& coll_c = use_facet<collate<wchar_t> >(loc_c);
+ const collate<wchar_t>& coll_de = use_facet<collate<wchar_t> >(loc_de);
+
+ const wchar_t* strlit1 = L"a\0a\0";
+ const wchar_t* strlit2 = L"a\0b\0";
+ const wchar_t* strlit3 = L"a\0\xc4\0";
+ const wchar_t* strlit4 = L"a\0B\0";
+ const wchar_t* strlit5 = L"aa\0";
+ const wchar_t* strlit6 = L"b\0a\0";
+
+ int i;
+ string_type str1;
+ string_type str2;
+
+ str1 = coll_c.transform(strlit1, strlit1 + 3);
+ str2 = coll_c.transform(strlit2, strlit2 + 3);
+ i = str1.compare(str2);
+ VERIFY( i < 0 );
+
+ str1 = coll_de.transform(strlit1, strlit1 + 3);
+ str2 = coll_de.transform(strlit2, strlit2 + 3);
+ i = str1.compare(str2);
+ VERIFY( i < 0 );
+
+ str1 = coll_c.transform(strlit3, strlit3 + 3);
+ str2 = coll_c.transform(strlit4, strlit4 + 3);
+ i = str1.compare(str2);
+ VERIFY( i > 0 );
+
+ str1 = coll_de.transform(strlit3, strlit3 + 3);
+ str2 = coll_de.transform(strlit4, strlit4 + 3);
+ i = str1.compare(str2);
+ VERIFY( i < 0 );
+
+ str1 = coll_c.transform(strlit1, strlit1 + 1);
+ str2 = coll_c.transform(strlit5, strlit5 + 1);
+ i = str1.compare(str2);
+ VERIFY( i == 0 );
+
+ str1 = coll_de.transform(strlit6, strlit6 + 3);
+ str2 = coll_de.transform(strlit1, strlit1 + 3);
+ i = str1.compare(str2);
+ VERIFY( i > 0 );
+
+ str1 = coll_c.transform(strlit1, strlit1 + 3);
+ str2 = coll_c.transform(strlit5, strlit5 + 3);
+ i = str1.compare(str2);
+ VERIFY( i < 0 );
+}
+
+int main()
+{
+ test03();
+ return 0;
+}