1#include "locale_test.h"
2
3#if !defined (STLPORT) || !defined (_STLP_USE_NO_IOSTREAMS)
4#  include <locale>
5#  include <stdexcept>
6#  include <algorithm>
7#  include <vector>
8
9#  if !defined (STLPORT) || defined(_STLP_USE_NAMESPACES)
10using namespace std;
11#  endif
12
13//
14// tests implementation
15//
16void LocaleTest::collate_facet()
17{
18  {
19    CPPUNIT_ASSERT( has_facet<collate<char> >(locale::classic()) );
20    collate<char> const& col = use_facet<collate<char> >(locale::classic());
21
22    char const str1[] = "abcdef1";
23    char const str2[] = "abcdef2";
24    const size_t size1 = sizeof(str1) / sizeof(str1[0]) - 1;
25    const size_t size2 = sizeof(str2) / sizeof(str2[0]) - 1;
26
27    CPPUNIT_ASSERT( col.compare(str1, str1 + size1 - 1, str2, str2 + size2 - 1) == 0 );
28    CPPUNIT_ASSERT( col.compare(str1, str1 + size1, str2, str2 + size2) == -1 );
29
30    //Smallest string should be before largest one:
31    CPPUNIT_ASSERT( col.compare(str1, str1 + size1 - 2, str2, str2 + size2 - 1) == -1 );
32    CPPUNIT_ASSERT( col.compare(str1, str1 + size1 - 1, str2, str2 + size2 - 2) == 1 );
33  }
34
35#  if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS)
36  try {
37    locale loc("fr_FR");
38    {
39      CPPUNIT_ASSERT( has_facet<collate<char> >(loc) );
40      collate<char> const& col = use_facet<collate<char> >(loc);
41
42      char const str1[] = "abcdef1";
43      char const str2[] = "abcdef2";
44      const size_t size1 = sizeof(str1) / sizeof(str1[0]) - 1;
45      const size_t size2 = sizeof(str2) / sizeof(str2[0]) - 1;
46
47      CPPUNIT_ASSERT( col.compare(str1, str1 + size1 - 1, str2, str2 + size2 - 1) == 0 );
48      CPPUNIT_ASSERT( col.compare(str1, str1 + size1, str2, str2 + size2) == -1 );
49
50      //Smallest string should be before largest one:
51      CPPUNIT_ASSERT( col.compare(str1, str1 + size1 - 2, str2, str2 + size2 - 1) == -1 );
52      CPPUNIT_ASSERT( col.compare(str1, str1 + size1 - 1, str2, str2 + size2 - 2) == 1 );
53    }
54    {
55      CPPUNIT_ASSERT( has_facet<collate<char> >(loc) );
56      collate<char> const& col = use_facet<collate<char> >(loc);
57
58      string strs[] = {"abdd", "abçd", "abbd", "abcd"};
59
60      string transformed[4];
61      for (size_t i = 0; i < 4; ++i) {
62        transformed[i] = col.transform(strs[i].data(), strs[i].data() + strs[i].size());
63      }
64
65      sort(strs, strs + 4, loc);
66      CPPUNIT_ASSERT( strs[0] == "abbd" );
67      CPPUNIT_ASSERT( strs[1] == "abcd" );
68      CPPUNIT_ASSERT( strs[2] == "abçd" );
69      CPPUNIT_ASSERT( strs[3] == "abdd" );
70
71      sort(transformed, transformed + 4);
72
73      CPPUNIT_ASSERT( col.transform(strs[0].data(), strs[0].data() + strs[0].size()) == transformed[0] );
74      CPPUNIT_ASSERT( col.transform(strs[1].data(), strs[1].data() + strs[1].size()) == transformed[1] );
75      CPPUNIT_ASSERT( col.transform(strs[2].data(), strs[2].data() + strs[2].size()) == transformed[2] );
76      CPPUNIT_ASSERT( col.transform(strs[3].data(), strs[3].data() + strs[3].size()) == transformed[3] );
77
78      // Check empty string result in empty key.
79      CPPUNIT_ASSERT( col.transform(strs[0].data(), strs[0].data()).empty() );
80
81      // Check that only characters that matter are taken into accout to build the key.
82      CPPUNIT_ASSERT( col.transform(strs[0].data(), strs[0].data() + 2) == col.transform(strs[1].data(), strs[1].data() + 2) );
83    }
84#    if !defined (STLPORT) || !defined (_STLP_NO_WCHAR_T)
85    {
86      CPPUNIT_ASSERT( has_facet<collate<wchar_t> >(loc) );
87      collate<wchar_t> const& col = use_facet<collate<wchar_t> >(loc);
88
89      wchar_t const str1[] = L"abcdef1";
90      wchar_t const str2[] = L"abcdef2";
91      const size_t size1 = sizeof(str1) / sizeof(str1[0]) - 1;
92      const size_t size2 = sizeof(str2) / sizeof(str2[0]) - 1;
93
94      CPPUNIT_ASSERT( col.compare(str1, str1 + size1 - 1, str2, str2 + size2 - 1) == 0 );
95      CPPUNIT_ASSERT( col.compare(str1, str1 + size1, str2, str2 + size2) == -1 );
96
97      //Smallest string should be before largest one:
98      CPPUNIT_ASSERT( col.compare(str1, str1 + size1 - 2, str2, str2 + size2 - 1) == -1 );
99      CPPUNIT_ASSERT( col.compare(str1, str1 + size1 - 1, str2, str2 + size2 - 2) == 1 );
100    }
101    {
102      size_t i;
103      CPPUNIT_ASSERT( has_facet<collate<wchar_t> >(loc) );
104      collate<wchar_t> const& col = use_facet<collate<wchar_t> >(loc);
105
106      // Here we would like to use L"abçd" but it looks like all compilers
107      // do not support storage of unicode characters in exe resulting in
108      // compilation error. We avoid this test for the moment.
109      wstring strs[] = {L"abdd", L"abcd", L"abbd", L"abcd"};
110
111      wstring transformed[4];
112      for (i = 0; i < 4; ++i) {
113        transformed[i] = col.transform(strs[i].data(), strs[i].data() + strs[i].size());
114      }
115
116      sort(strs, strs + 4, loc);
117      CPPUNIT_ASSERT( strs[0] == L"abbd" );
118      CPPUNIT_ASSERT( strs[1] == L"abcd" );
119      CPPUNIT_ASSERT( strs[2] == L"abcd" );
120      CPPUNIT_ASSERT( strs[3] == L"abdd" );
121
122      sort(transformed, transformed + 4);
123
124      CPPUNIT_ASSERT( col.transform(strs[0].data(), strs[0].data() + strs[0].size()) == transformed[0] );
125      CPPUNIT_ASSERT( col.transform(strs[1].data(), strs[1].data() + strs[1].size()) == transformed[1] );
126      CPPUNIT_ASSERT( col.transform(strs[2].data(), strs[2].data() + strs[2].size()) == transformed[2] );
127      CPPUNIT_ASSERT( col.transform(strs[3].data(), strs[3].data() + strs[3].size()) == transformed[3] );
128
129      CPPUNIT_ASSERT( col.transform(strs[0].data(), strs[0].data()).empty() );
130
131      CPPUNIT_ASSERT( col.transform(strs[0].data(), strs[0].data() + 2) == col.transform(strs[1].data(), strs[1].data() + 2) );
132    }
133#    endif
134  }
135  catch (runtime_error const&) {
136    CPPUNIT_MESSAGE("No french locale to check collate facet");
137  }
138#  endif
139}
140
141void LocaleTest::collate_by_name()
142{
143  /*
144   * Check of the 22.1.1.2.7 standard point. Construction of a locale
145   * instance from a null pointer or an unknown name should result in
146   * a runtime_error exception.
147   */
148#  if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS)
149#    if defined (STLPORT) || !defined (__GNUC__)
150  try {
151    locale loc(locale::classic(), new collate_byname<char>(static_cast<char const*>(0)));
152    CPPUNIT_FAIL;
153  }
154  catch (runtime_error const& /* e */) {
155    //CPPUNIT_MESSAGE( e.what() );
156  }
157  catch (...) {
158    CPPUNIT_FAIL;
159  }
160#    endif
161
162  try {
163    locale loc(locale::classic(), new collate_byname<char>("yasli_language"));
164    CPPUNIT_FAIL;
165  }
166  catch (runtime_error const& /* e */) {
167    //CPPUNIT_MESSAGE( e.what() );
168  }
169  catch (...) {
170    CPPUNIT_FAIL;
171  }
172
173  try {
174    string veryLongFacetName("LC_COLLATE=");
175    veryLongFacetName.append(512, '?');
176    locale loc(locale::classic(), new collate_byname<char>(veryLongFacetName.c_str()));
177    CPPUNIT_FAIL;
178  }
179  catch (runtime_error const& /* e */) {
180    //CPPUNIT_MESSAGE( e.what() );
181  }
182  catch (...) {
183    CPPUNIT_FAIL;
184  }
185
186  try {
187    locale loc(locale::classic(), "C", locale::collate);
188  }
189  catch (runtime_error const& e) {
190    CPPUNIT_MESSAGE( e.what() );
191    CPPUNIT_FAIL;
192  }
193  catch (...) {
194    CPPUNIT_FAIL;
195  }
196
197  try {
198    // On platform without real localization support we should rely on the "C" facet.
199    locale loc(locale::classic(), "", locale::collate);
200  }
201  catch (runtime_error const& e) {
202    CPPUNIT_MESSAGE( e.what() );
203    CPPUNIT_FAIL;
204  }
205  catch (...) {
206    CPPUNIT_FAIL;
207  }
208
209  try {
210    locale loc(locale::classic(), new collate_byname<char>("C"));
211
212    //We check that the C locale gives a lexicographical comparison:
213    collate<char> const& cfacet_byname = use_facet<collate<char> >(loc);
214    collate<char> const& cfacet = use_facet<collate<char> >(locale::classic());
215
216    char const str1[] = "abcdef1";
217    char const str2[] = "abcdef2";
218    const size_t size1 = sizeof(str1) / sizeof(str1[0]) - 1;
219    const size_t size2 = sizeof(str2) / sizeof(str2[0]) - 1;
220
221    CPPUNIT_ASSERT( cfacet_byname.compare(str1, str1 + size1 - 1, str2, str2 + size2 - 1) ==
222                    cfacet.compare(str1, str1 + size1 - 1, str2, str2 + size2 - 1) );
223    CPPUNIT_ASSERT( cfacet_byname.compare(str1, str1 + size1, str2, str2 + size2) ==
224                    cfacet.compare(str1, str1 + size1, str2, str2 + size2) );
225
226    //Smallest string should be before largest one:
227    CPPUNIT_ASSERT( cfacet_byname.compare(str1, str1 + size1 - 2, str2, str2 + size2 - 1) ==
228                    cfacet.compare(str1, str1 + size1 - 2, str2, str2 + size2 - 1) );
229    CPPUNIT_ASSERT( cfacet_byname.compare(str1, str1 + size1 - 1, str2, str2 + size2 - 2) ==
230                    cfacet.compare(str1, str1 + size1 - 1, str2, str2 + size2 - 2) );
231
232    // We cannot play with 'ç' char here because doing so would make test result
233    // dependant on char being consider as signed or not...
234    string strs[] = {"abdd", /* "abçd",*/ "abbd", "abcd"};
235
236    vector<string> v1(strs, strs + sizeof(strs) / sizeof(strs[0]));
237    sort(v1.begin(), v1.end(), loc);
238    vector<string> v2(strs, strs + sizeof(strs) / sizeof(strs[0]));
239    sort(v2.begin(), v2.end(), locale::classic());
240    CPPUNIT_ASSERT( v1 == v2 );
241
242    CPPUNIT_ASSERT( (cfacet_byname.transform(v1[0].data(), v1[0].data() + v1[0].size()).compare(cfacet_byname.transform(v1[1].data(), v1[1].data() + v1[1].size())) ==
243                    v1[0].compare(v1[1])) );
244  }
245  catch (runtime_error const& /* e */) {
246    /* CPPUNIT_MESSAGE( e.what() ); */
247    CPPUNIT_FAIL;
248  }
249  catch (...) {
250    CPPUNIT_FAIL;
251  }
252
253#    if !defined (STLPORT) || !defined (_STLP_NO_WCHAR_T)
254#      if defined (STLPORT) || !defined (__GNUC__)
255  try {
256    locale loc(locale::classic(), new collate_byname<wchar_t>(static_cast<char const*>(0)));
257    CPPUNIT_FAIL;
258  }
259  catch (runtime_error const&) {
260  }
261  catch (...) {
262    CPPUNIT_FAIL;
263  }
264#      endif
265
266  try {
267    locale loc(locale::classic(), new collate_byname<wchar_t>("yasli_language"));
268    CPPUNIT_FAIL;
269  }
270  catch (runtime_error const&) {
271  }
272  catch (...) {
273    CPPUNIT_FAIL;
274  }
275#    endif
276#  endif
277}
278
279#endif
280