1 #include "locale_test.h"
2 
3 #if !defined (STLPORT) || !defined (_STLP_USE_NO_IOSTREAMS)
4 #  include <locale>
5 #  include <stdexcept>
6 
7 #  if !defined (STLPORT) || defined(_STLP_USE_NAMESPACES)
8 using namespace std;
9 #  endif
10 
11 static const char* tested_locales[] = {
12 //name,
13 #  if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS)
14   // We need exception support to check support of the following localizations.
15   "fr_FR",
16   "ru_RU.koi8r",
17   "en_GB",
18   "en_US",
19 #  endif
20   "",
21   "C"
22 };
23 
24 //
25 // tests implementation
26 //
_ctype_facet(const locale & loc)27 void LocaleTest::_ctype_facet( const locale& loc)
28 {
29   CPPUNIT_ASSERT( has_facet<ctype<char> >(loc) );
30   ctype<char> const& ct = use_facet<ctype<char> >(loc);
31   //is
32   {
33     CPPUNIT_ASSERT( ct.is(ctype_base::digit, '0') );
34     CPPUNIT_ASSERT( ct.is(ctype_base::upper, 'A') );
35     CPPUNIT_ASSERT( ct.is(ctype_base::lower, 'a') );
36     CPPUNIT_ASSERT( ct.is(ctype_base::alpha, 'A') );
37     CPPUNIT_ASSERT( ct.is(ctype_base::space, ' ') );
38     CPPUNIT_ASSERT( !ct.is(ctype_base::space, '2') );
39     CPPUNIT_ASSERT( ct.is(ctype_base::punct, '.') );
40     CPPUNIT_ASSERT( ct.is(ctype_base::xdigit, 'a') );
41   }
42 
43   //is range
44   {
45     char values[] = "0Aa .";
46     ctype_base::mask res[sizeof(values)];
47     ct.is(values, values + sizeof(values), res);
48     // '0'
49     CPPUNIT_ASSERT( (res[0] & ctype_base::print) != 0 );
50     CPPUNIT_ASSERT( (res[0] & ctype_base::digit) != 0 );
51     CPPUNIT_ASSERT( (res[0] & ctype_base::xdigit) != 0 );
52     // 'A'
53     CPPUNIT_ASSERT( (res[1] & ctype_base::print) != 0 );
54     CPPUNIT_ASSERT( (res[1] & ctype_base::alpha) != 0 );
55     CPPUNIT_ASSERT( (res[1] & ctype_base::xdigit) != 0 );
56     CPPUNIT_ASSERT( (res[1] & ctype_base::upper) != 0 );
57     // 'a'
58     CPPUNIT_ASSERT( (res[2] & ctype_base::print) != 0 );
59     CPPUNIT_ASSERT( (res[2] & ctype_base::alpha) != 0 );
60     CPPUNIT_ASSERT( (res[2] & ctype_base::xdigit) != 0 );
61     CPPUNIT_ASSERT( (res[2] & ctype_base::lower) != 0 );
62     CPPUNIT_ASSERT( (res[2] & ctype_base::space) == 0 );
63     // ' '
64     CPPUNIT_ASSERT( (res[3] & ctype_base::print) != 0 );
65     CPPUNIT_ASSERT( (res[3] & ctype_base::space) != 0 );
66     CPPUNIT_ASSERT( (res[3] & ctype_base::digit) == 0 );
67     // '.'
68     CPPUNIT_ASSERT( (res[4] & ctype_base::print) != 0 );
69     CPPUNIT_ASSERT( (res[4] & ctype_base::punct) != 0 );
70     CPPUNIT_ASSERT( (res[4] & ctype_base::digit) == 0 );
71   }
72 
73   //scan_is
74   {
75     char range[] = "abAc123 .";
76     const char *rbeg = range;
77     const char *rend = range + sizeof(range);
78 
79     const char *res;
80     res = ct.scan_is((ctype_base::mask)(ctype_base::alpha | ctype_base::lower), rbeg, rend);
81     CPPUNIT_ASSERT( res != rend );
82     CPPUNIT_ASSERT( *res == 'a' );
83 
84     res = ct.scan_is(ctype_base::upper, rbeg, rend);
85     CPPUNIT_ASSERT( res != rend );
86     CPPUNIT_ASSERT( *res == 'A' );
87 
88     res = ct.scan_is(ctype_base::punct, rbeg, rend);
89     CPPUNIT_ASSERT( res != rend );
90     CPPUNIT_ASSERT( *res == '.' );
91   }
92 
93   //scan_not
94   {
95     char range[] = "abAc123 .";
96     const char *rbeg = range;
97     const char *rend = range + sizeof(range);
98 
99     const char *res;
100     res = ct.scan_not((ctype_base::mask)(ctype_base::alpha | ctype_base::lower), rbeg, rend);
101     CPPUNIT_ASSERT( res != rend );
102     CPPUNIT_ASSERT( *res == '1' );
103 
104     res = ct.scan_not(ctype_base::alpha, rbeg, rend);
105     CPPUNIT_ASSERT( res != rend );
106     CPPUNIT_ASSERT( *res == '1' );
107 
108     res = ct.scan_not(ctype_base::punct, rbeg, rend);
109     CPPUNIT_ASSERT( res != rend );
110     CPPUNIT_ASSERT( *res == 'a' );
111   }
112 
113   //toupper
114   {
115     CPPUNIT_ASSERT( ct.toupper('a') == 'A' );
116     CPPUNIT_ASSERT( ct.toupper('A') == 'A' );
117     CPPUNIT_ASSERT( ct.toupper('1') == '1' );
118   }
119 
120   //toupper range
121   {
122     char range[] = "abAc1";
123     char expected_range[] = "ABAC1";
124     ct.toupper(range, range + sizeof(range));
125     CPPUNIT_ASSERT( equal(range, range + sizeof(range), expected_range) );
126   }
127 
128   //tolower
129   {
130     CPPUNIT_ASSERT( ct.tolower('A') == 'a' );
131     CPPUNIT_ASSERT( ct.tolower('a') == 'a' );
132     CPPUNIT_ASSERT( ct.tolower('1') == '1' );
133   }
134 
135   //tolower range
136   {
137     char range[] = "ABaC1";
138     char expected_range[] = "abac1";
139     ct.tolower(range, range + sizeof(range));
140     CPPUNIT_ASSERT( equal(range, range + sizeof(range), expected_range) );
141   }
142 
143   //widen
144   {
145     CPPUNIT_ASSERT( ct.widen('a') == 'a' );
146   }
147 
148   //widen range
149   {
150     char range[] = "ABaC1";
151     char res[sizeof(range)];
152     ct.widen(range, range + sizeof(range), res);
153     CPPUNIT_ASSERT( equal(range, range + sizeof(range), res) );
154   }
155 
156   //narrow
157   {
158     CPPUNIT_ASSERT( ct.narrow('a', 'b') == 'a' );
159   }
160 
161   //narrow range
162   {
163     char range[] = "ABaC1";
164     char res[sizeof(range)];
165     ct.narrow(range, range + sizeof(range), 'b', res);
166     CPPUNIT_ASSERT( equal(range, range + sizeof(range), res) );
167   }
168 }
169 
_ctype_facet_w(const locale & loc)170 void LocaleTest::_ctype_facet_w( const locale& loc )
171 {
172 # ifndef _STLP_NO_WCHAR_T
173   CPPUNIT_ASSERT( has_facet<ctype<wchar_t> >(loc) );
174   ctype<wchar_t> const& wct = use_facet<ctype<wchar_t> >(loc);
175   //is
176   {
177     CPPUNIT_CHECK( wct.is(ctype_base::digit, L'0') );
178     CPPUNIT_CHECK( wct.is(ctype_base::upper, L'A') );
179     CPPUNIT_CHECK( wct.is(ctype_base::lower, L'a') );
180     CPPUNIT_CHECK( wct.is(ctype_base::alpha, L'A') );
181     CPPUNIT_CHECK( wct.is(ctype_base::space, L' ') );
182     CPPUNIT_CHECK( !wct.is(ctype_base::space, L'2') );
183     CPPUNIT_CHECK( wct.is(ctype_base::punct, L'.') );
184     CPPUNIT_CHECK( wct.is(ctype_base::xdigit, L'a') );
185   }
186 
187   //is range
188   {
189     wchar_t values[] = L"0Aa .";
190     ctype_base::mask res[sizeof(values) / sizeof(wchar_t)];
191     wct.is(values, values + (sizeof(values) / sizeof(wchar_t)), res);
192     // '0'
193     CPPUNIT_CHECK( (res[0] & ctype_base::print) != 0 );
194     CPPUNIT_CHECK( (res[0] & ctype_base::digit) != 0 );
195     CPPUNIT_CHECK( (res[0] & ctype_base::xdigit) != 0 );
196     // 'A'
197     CPPUNIT_CHECK( (res[1] & ctype_base::print) != 0 );
198     CPPUNIT_CHECK( (res[1] & ctype_base::alpha) != 0 );
199     CPPUNIT_CHECK( (res[1] & ctype_base::xdigit) != 0 );
200     CPPUNIT_CHECK( (res[1] & ctype_base::upper) != 0 );
201     // 'a'
202     CPPUNIT_CHECK( (res[2] & ctype_base::print) != 0 );
203     CPPUNIT_CHECK( (res[2] & ctype_base::alpha) != 0 );
204     CPPUNIT_CHECK( (res[2] & ctype_base::xdigit) != 0 );
205     CPPUNIT_CHECK( (res[2] & ctype_base::lower) != 0 );
206     CPPUNIT_CHECK( (res[2] & ctype_base::space) == 0 );
207     // ' '
208     CPPUNIT_CHECK( (res[3] & ctype_base::print) != 0 );
209     CPPUNIT_CHECK( (res[3] & ctype_base::space) != 0 );
210     CPPUNIT_CHECK( (res[3] & ctype_base::digit) == 0 );
211     // '.'
212     CPPUNIT_CHECK( (res[4] & ctype_base::print) != 0 );
213     CPPUNIT_CHECK( (res[4] & ctype_base::punct) != 0 );
214     CPPUNIT_CHECK( (res[4] & ctype_base::digit) == 0 );
215   }
216 
217   //scan_is
218   {
219     wchar_t range[] = L"abAc123 .";
220     const wchar_t *rbeg = range;
221     const wchar_t *rend = range + (sizeof(range) / sizeof(wchar_t));
222 
223     const wchar_t *res;
224     res = wct.scan_is((ctype_base::mask)(ctype_base::alpha | ctype_base::lower), rbeg, rend);
225     CPPUNIT_CHECK( res != rend );
226     CPPUNIT_CHECK( *res == L'a' );
227 
228     res = wct.scan_is(ctype_base::upper, rbeg, rend);
229     CPPUNIT_CHECK( res != rend );
230     CPPUNIT_CHECK( *res == L'A' );
231 
232     res = wct.scan_is(ctype_base::punct, rbeg, rend);
233     CPPUNIT_CHECK( res != rend );
234     CPPUNIT_CHECK( *res == L'.' );
235   }
236 
237   //scan_not
238   {
239     wchar_t range[] = L"abAc123 .";
240     const wchar_t *rbeg = range;
241     const wchar_t *rend = range + (sizeof(range) / sizeof(wchar_t));
242 
243     const wchar_t *res;
244     res = wct.scan_not((ctype_base::mask)(ctype_base::alpha | ctype_base::lower), rbeg, rend);
245     CPPUNIT_CHECK( res != rend );
246     CPPUNIT_CHECK( *res == L'1' );
247 
248     res = wct.scan_not(ctype_base::alpha, rbeg, rend);
249     CPPUNIT_CHECK( res != rend );
250     CPPUNIT_CHECK( *res == L'1' );
251 
252     res = wct.scan_not(ctype_base::punct, rbeg, rend);
253     CPPUNIT_CHECK( res != rend );
254     CPPUNIT_CHECK( *res == L'a' );
255   }
256 
257   //toupper
258   {
259     CPPUNIT_CHECK( wct.toupper(L'a') == L'A' );
260     CPPUNIT_CHECK( wct.toupper(L'A') == L'A' );
261     CPPUNIT_CHECK( wct.toupper(L'1') == L'1' );
262   }
263 
264   //toupper range
265   {
266     wchar_t range[] = L"abAc1";
267     wchar_t expected_range[] = L"ABAC1";
268     wct.toupper(range, range + sizeof(range) / sizeof(wchar_t));
269     CPPUNIT_CHECK( equal(range, range + sizeof(range) / sizeof(wchar_t), expected_range) );
270   }
271 
272   //tolower
273   {
274     CPPUNIT_CHECK( wct.tolower(L'A') == L'a' );
275     CPPUNIT_CHECK( wct.tolower(L'a') == L'a' );
276     CPPUNIT_CHECK( wct.tolower(L'1') == L'1' );
277   }
278 
279   //tolower range
280   {
281     wchar_t range[] = L"ABaC1";
282     wchar_t expected_range[] = L"abac1";
283     wct.tolower(range, range + sizeof(range) / sizeof(wchar_t));
284     CPPUNIT_CHECK( equal(range, range + sizeof(range) / sizeof(wchar_t), expected_range) );
285   }
286 
287   //widen
288   {
289     CPPUNIT_CHECK( wct.widen('a') == L'a' );
290   }
291 
292   //widen range
293   {
294     char range[] = "ABaC1";
295     wchar_t res[sizeof(range)];
296     wchar_t expected_res[] = L"ABaC1";
297     wct.widen(range, range + sizeof(range), res);
298     CPPUNIT_CHECK( equal(expected_res, expected_res + sizeof(range), res) );
299   }
300 
301   //narrow
302   {
303     CPPUNIT_CHECK( wct.narrow(L'a', 'b') == L'a' );
304   }
305 
306   //narrow range
307   {
308     wchar_t range[] = L"ABaC1";
309     char res[sizeof(range) / sizeof(wchar_t)];
310     char expected_res[] = "ABaC1";
311     wct.narrow(range, range + sizeof(range) / sizeof(wchar_t), 'b', res);
312     CPPUNIT_CHECK( equal(expected_res, expected_res + sizeof(range) / sizeof(wchar_t), res) );
313   }
314 # endif
315 }
316 
317 
318 typedef void (LocaleTest::*_Test) (const locale&);
test_supported_locale(LocaleTest & inst,_Test __test)319 static void test_supported_locale(LocaleTest& inst, _Test __test) {
320   size_t n = sizeof(tested_locales) / sizeof(tested_locales[0]);
321   for (size_t i = 0; i < n; ++i) {
322     locale loc;
323 #  if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS)
324     try
325 #  endif
326     {
327       locale tmp(tested_locales[i]);
328       loc = tmp;
329     }
330 #  if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS)
331     catch (runtime_error const&) {
332       //This locale is not supported.
333       continue;
334     }
335 #  endif
336 
337     CPPUNIT_MESSAGE( loc.name().c_str() );
338     (inst.*__test)(loc);
339 
340     {
341       locale tmp(locale::classic(), tested_locales[i], locale::ctype);
342       loc = tmp;
343     }
344     (inst.*__test)(loc);
345 
346     {
347       locale tmp(locale::classic(), new ctype_byname<char>(tested_locales[i]));
348 #ifndef _STLP_NO_WCHAR_T
349       locale tmp0(tmp, new ctype_byname<wchar_t>(tested_locales[i]));
350       tmp = tmp0;
351 #endif
352       loc = tmp;
353     }
354     (inst.*__test)(loc);
355   }
356 }
357 
ctype_facet()358 void LocaleTest::ctype_facet()
359 {
360   test_supported_locale(*this, &LocaleTest::_ctype_facet);
361 #ifndef _STLP_NO_WCHAR_T
362   test_supported_locale(*this, &LocaleTest::_ctype_facet_w);
363 #endif
364 }
365 
ctype_by_name()366 void LocaleTest::ctype_by_name()
367 {
368   /*
369    * Check of the 22.1.1.2.7 standard point. Construction of a locale
370    * instance from a null pointer or an unknown name should result in
371    * a runtime_error exception.
372    */
373 #  if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS)
374 #    if  defined (STLPORT) || (!defined(__GNUC__) && (!defined (_MSC_VER) || (_MSC_VER > 1400)))
375    // libstdc++ call freelocate on bad locale
376   try {
377     locale loc(locale::classic(), new ctype_byname<char>(static_cast<char const*>(0)));
378     CPPUNIT_ASSERT( false );
379   }
380   catch (runtime_error const& /* e */) {
381     //CPPUNIT_MESSAGE( e.what() );
382   }
383   catch (...) {
384     CPPUNIT_ASSERT( false );
385   }
386 #    endif
387 
388   try {
389     locale loc(locale::classic(), new ctype_byname<char>("yasli_language"));
390     CPPUNIT_FAIL;
391   }
392   catch (runtime_error const& /* e */) {
393     //CPPUNIT_MESSAGE( e.what() );
394   }
395   catch (...) {
396     CPPUNIT_FAIL;
397   }
398 
399 #    if  defined(STLPORT) || !defined(__GNUC__)
400   try {
401     locale loc(locale::classic(), new codecvt_byname<char, char, mbstate_t>(static_cast<char const*>(0)));
402     CPPUNIT_FAIL;
403   }
404   catch (runtime_error const& /* e */) {
405     //CPPUNIT_MESSAGE( e.what() );
406   }
407   catch (...) {
408     CPPUNIT_FAIL;
409   }
410 #    endif
411 
412   try {
413     locale loc(locale::classic(), new codecvt_byname<char, char, mbstate_t>("yasli_language"));
414     //STLport implementation do not care about name pass to this facet.
415 #    if !defined (STLPORT)
416     CPPUNIT_FAIL;
417 #    endif
418   }
419   catch (runtime_error const& /* e */) {
420     //CPPUNIT_MESSAGE( e.what() );
421   }
422   catch (...) {
423     CPPUNIT_FAIL;
424   }
425 
426   try {
427     locale loc(locale::classic(), new ctype_byname<char>("fr_FR"));
428     CPPUNIT_ASSERT( has_facet<ctype<char> >(loc) );
429     ctype<char> const& ct = use_facet<ctype<char> >(loc);
430     CPPUNIT_ASSERT( ct.is(ctype_base::mask(ctype_base::print | ctype_base::lower | ctype_base::alpha), '�') );
431   }
432   catch (runtime_error const& /* e */) {
433     //CPPUNIT_MESSAGE( e.what() );
434   }
435   catch (...) {
436     CPPUNIT_FAIL;
437   }
438 
439   try {
440     locale loc(locale::classic(), new ctype_byname<char>("C"));
441     ctype<char> const& cfacet_byname = use_facet<ctype<char> >(loc);
442     ctype<char> const& cfacet = use_facet<ctype<char> >(locale::classic());
443 
444     for (char c = 0;; ++c) {
445       CPPUNIT_CHECK(cfacet_byname.is(ctype_base::space, c) == cfacet.is(ctype_base::space, c));
446       if (cfacet_byname.is(ctype_base::print, c) != cfacet.is(ctype_base::print, c))
447       {
448         CPPUNIT_CHECK(cfacet_byname.is(ctype_base::print, c) == cfacet.is(ctype_base::print, c));
449       }
450       CPPUNIT_CHECK(cfacet_byname.is(ctype_base::cntrl, c) == cfacet.is(ctype_base::cntrl, c));
451       CPPUNIT_CHECK(cfacet_byname.is(ctype_base::upper, c) == cfacet.is(ctype_base::upper, c));
452       CPPUNIT_CHECK(cfacet_byname.is(ctype_base::lower, c) == cfacet.is(ctype_base::lower, c));
453       CPPUNIT_CHECK(cfacet_byname.is(ctype_base::alpha, c) == cfacet.is(ctype_base::alpha, c));
454       CPPUNIT_CHECK(cfacet_byname.is(ctype_base::digit, c) == cfacet.is(ctype_base::digit, c));
455       CPPUNIT_CHECK(cfacet_byname.is(ctype_base::punct, c) == cfacet.is(ctype_base::punct, c));
456       CPPUNIT_CHECK(cfacet_byname.is(ctype_base::xdigit, c) == cfacet.is(ctype_base::xdigit, c));
457       CPPUNIT_CHECK(cfacet_byname.is(ctype_base::alnum, c) == cfacet.is(ctype_base::alnum, c));
458       CPPUNIT_CHECK(cfacet_byname.is(ctype_base::graph, c) == cfacet.is(ctype_base::graph, c));
459       if (c == 127) break;
460     }
461   }
462   catch (runtime_error const& /* e */) {
463     /* CPPUNIT_MESSAGE( e.what() ); */
464     CPPUNIT_FAIL;
465   }
466   catch (...) {
467     CPPUNIT_FAIL;
468   }
469 
470 #    if !defined (STLPORT) || !defined (_STLP_NO_WCHAR_T)
471 #      if  defined(STLPORT) || !defined(__GNUC__)
472   try {
473     locale loc(locale::classic(), new ctype_byname<wchar_t>(static_cast<char const*>(0)));
474     CPPUNIT_FAIL;
475   }
476   catch (runtime_error const&) {
477   }
478   catch (...) {
479     CPPUNIT_FAIL;
480   }
481 #      endif
482 
483   try {
484     locale loc(locale::classic(), new ctype_byname<wchar_t>("yasli_language"));
485     CPPUNIT_FAIL;
486   }
487   catch (runtime_error const&) {
488   }
489   catch (...) {
490     CPPUNIT_FAIL;
491   }
492 
493 #      if  defined(STLPORT) || !defined(__GNUC__)
494   try {
495     locale loc(locale::classic(), new codecvt_byname<wchar_t, char, mbstate_t>(static_cast<char const*>(0)));
496     CPPUNIT_FAIL;
497   }
498   catch (runtime_error const& /* e */) {
499     //CPPUNIT_MESSAGE( e.what() );
500   }
501   catch (...) {
502     CPPUNIT_FAIL;
503   }
504 #      endif
505 
506   try {
507     locale loc(locale::classic(), new codecvt_byname<wchar_t, char, mbstate_t>("yasli_language"));
508     CPPUNIT_FAIL;
509   }
510   catch (runtime_error const& /* e */) {
511     //CPPUNIT_MESSAGE( e.what() );
512   }
513   catch (...) {
514     CPPUNIT_FAIL;
515   }
516 #    endif
517 #  endif
518 }
519 
520 #endif
521