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) 8using namespace std; 9# endif 10 11static 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// 27void 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 170void 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 318typedef void (LocaleTest::*_Test) (const locale&); 319static 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 358void 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 366void 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