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