1 /* 2 * Copyright 2010, Oliver Tappe, zooey@hirschkaefer.de 3 * Distributed under the terms of the MIT License. 4 */ 5 6 #include <ctype.h> 7 #include <errno.h> 8 #include <langinfo.h> 9 #include <locale.h> 10 #include <stdio.h> 11 #include <stdlib.h> 12 #include <string.h> 13 #include <time.h> 14 #include <wctype.h> 15 16 17 // #pragma mark - setlocale ---------------------------------------------------- 18 19 20 void 21 test_setlocale() 22 { 23 const char* locales[] = { 24 "POSIX", 25 "C", 26 "de_DE", 27 "en_US", 28 "en_US.US-ASCII", 29 "hr_HR.ISO-8859-2", 30 "nl_NL", 31 "nb_NO", 32 "fr_FR.UTF-8@collation=phonebook", 33 "de_DE.iso8859-1", 34 "De_dE.IsO8859-15", 35 "de_DE.utf8", 36 "de_DE.UTF-8", 37 "de_DE@euro", 38 "de_DE@EURO", 39 "de_DE.utf-8@Euro", 40 "POSIX", 41 "C", 42 NULL 43 }; 44 const char* expectedLocales[] = { 45 "POSIX", 46 "POSIX", 47 "de_DE", 48 "en_US", 49 "en_US.US-ASCII", 50 "hr_HR.ISO-8859-2", 51 "nl_NL", 52 "nb_NO", 53 "fr_FR.UTF-8@collation=phonebook", 54 "de_DE.iso8859-1", 55 "De_dE.IsO8859-15", 56 "de_DE.utf8", 57 "de_DE.UTF-8", 58 "de_DE@euro", 59 "de_DE@EURO", 60 "de_DE.utf-8@Euro", 61 "POSIX", 62 "POSIX" 63 }; 64 const char* categoryNames[] = { 65 "LC_ALL", 66 "LC_COLLATE", 67 "LC_CTYPE", 68 "LC_MONETARY", 69 "LC_NUMERIC", 70 "LC_TIME", 71 "LC_MESSAGES" 72 }; 73 printf("setlocale()\n"); 74 75 int problemCount = 0; 76 for (int i = 0; locales[i] != NULL; ++i) { 77 char* result = setlocale(LC_ALL, locales[i]); 78 if (!result || strcmp(result, expectedLocales[i]) != 0) { 79 printf("\tPROBLEM: setlocale(LC_ALL, \"%s\") = \"%s\" " 80 "(expected \"%s\")\n", 81 locales[i], result, expectedLocales[i]); 82 problemCount++; 83 } 84 } 85 86 for (int i = 1; i <= LC_LAST; ++i) 87 setlocale(i, locales[i + 1]); 88 char* result = setlocale(LC_ALL, NULL); 89 const char* expectedResult 90 = "LC_COLLATE=de_DE;LC_CTYPE=en_US;LC_MESSAGES=nb_NO;" 91 "LC_MONETARY=en_US.US-ASCII;LC_NUMERIC=hr_HR.ISO-8859-2;" 92 "LC_TIME=nl_NL"; 93 if (!result || strcmp(result, expectedResult) != 0) { 94 printf("\tPROBLEM: setlocale(LC_ALL, NULL) = \"%s\" " 95 "(expected \"%s\")\n", result, expectedResult); 96 problemCount++; 97 } 98 99 if (problemCount) 100 printf("\t%d problem(s) found!\n", problemCount); 101 else 102 printf("\tall fine\n"); 103 } 104 105 106 // #pragma mark - localeconv --------------------------------------------------- 107 108 109 void 110 dumpGrouping(const char* grouping, char* buf) 111 { 112 for (char* bufPtr = buf; *grouping; ++grouping) 113 bufPtr += sprintf(bufPtr, "\\x%02x", *grouping); 114 } 115 116 117 void 118 test_localeconv(const char* locale, const lconv* localeConv) 119 { 120 setlocale(LC_MONETARY, locale); 121 setlocale(LC_NUMERIC, locale); 122 printf("localeconv for '%s'\n", locale); 123 124 int problemCount = 0; 125 struct lconv* lc = localeconv(); 126 if (!lc) 127 printf("not ok - got no result from localeconv()\n"); 128 else { 129 if (strcmp(lc->decimal_point, localeConv->decimal_point) != 0) { 130 printf("\tPROBLEM: lc.decimal_point = \"%s\" (expected \"%s\")\n", 131 lc->decimal_point, localeConv->decimal_point); 132 problemCount++; 133 } 134 if (strcmp(lc->thousands_sep, localeConv->thousands_sep) != 0) { 135 printf("\tPROBLEM: lc.thousands_sep = \"%s\" (expected \"%s\")\n", 136 lc->thousands_sep, localeConv->thousands_sep); 137 problemCount++; 138 } 139 if (strcmp(lc->grouping, localeConv->grouping) != 0) { 140 char gotGrouping[20], expectedGrouping[20]; 141 dumpGrouping(lc->grouping, gotGrouping); 142 dumpGrouping(localeConv->grouping, expectedGrouping); 143 printf("\tPROBLEM: lc.grouping = \"%s\" (expected \"%s\")\n", 144 gotGrouping, expectedGrouping); 145 problemCount++; 146 } 147 if (strcmp(lc->int_curr_symbol, localeConv->int_curr_symbol) != 0) { 148 printf("\tPROBLEM: lc.int_curr_symbol = \"%s\" (expected \"%s\")\n", 149 lc->int_curr_symbol, localeConv->int_curr_symbol); 150 problemCount++; 151 } 152 if (strcmp(lc->currency_symbol, localeConv->currency_symbol) != 0) { 153 printf("\tPROBLEM: lc.currency_symbol = \"%s\" (expected \"%s\")\n", 154 lc->currency_symbol, localeConv->currency_symbol); 155 problemCount++; 156 } 157 if (strcmp(lc->mon_decimal_point, localeConv->mon_decimal_point) != 0) { 158 printf("\tPROBLEM: lc.mon_decimal_point = \"%s\" " 159 "(expected \"%s\")\n", 160 lc->mon_decimal_point, localeConv->mon_decimal_point); 161 problemCount++; 162 } 163 if (strcmp(lc->mon_thousands_sep, localeConv->mon_thousands_sep) != 0) { 164 printf("\tPROBLEM: lc.mon_thousands_sep = \"%s\" " 165 "(expected \"%s\")\n", 166 lc->mon_thousands_sep, localeConv->mon_thousands_sep); 167 problemCount++; 168 } 169 if (strcmp(lc->mon_grouping, localeConv->mon_grouping) != 0) { 170 char gotGrouping[20], expectedGrouping[20]; 171 dumpGrouping(lc->mon_grouping, gotGrouping); 172 dumpGrouping(localeConv->mon_grouping, expectedGrouping); 173 printf("\tPROBLEM: lc.mon_grouping: \"%s\" (expected \"%s\")\n", 174 gotGrouping, expectedGrouping); 175 problemCount++; 176 } 177 if (strcmp(lc->positive_sign, localeConv->positive_sign) != 0) { 178 printf("\tPROBLEM: lc.positive_sign = \"%s\" (expected \"%s\")\n", 179 lc->positive_sign, localeConv->positive_sign); 180 problemCount++; 181 } 182 if (strcmp(lc->negative_sign, localeConv->negative_sign) != 0) { 183 printf("\tPROBLEM: lc.negative_sign = \"%s\" (expected \"%s\")\n", 184 lc->negative_sign, localeConv->negative_sign); 185 problemCount++; 186 } 187 if (lc->frac_digits != localeConv->frac_digits) { 188 printf("\tPROBLEM: lc.frac_digits = %d (expected %d)\n", 189 lc->frac_digits, localeConv->frac_digits); 190 problemCount++; 191 } 192 if (lc->int_frac_digits != localeConv->int_frac_digits) { 193 printf("\tPROBLEM: lc.int_frac_digits = %d (expected %d)\n", 194 lc->int_frac_digits, localeConv->int_frac_digits); 195 problemCount++; 196 } 197 if (lc->p_cs_precedes != localeConv->p_cs_precedes) { 198 printf("\tPROBLEM: lc.p_cs_precedes = %d (expected %d)\n", 199 lc->p_cs_precedes, localeConv->p_cs_precedes); 200 problemCount++; 201 } 202 if (lc->p_sep_by_space != localeConv->p_sep_by_space) { 203 printf("\tPROBLEM: lc.p_sep_by_space = %d (expected %d)\n", 204 lc->p_sep_by_space, localeConv->p_sep_by_space); 205 problemCount++; 206 } 207 if (lc->p_sign_posn != localeConv->p_sign_posn) { 208 printf("\tPROBLEM: lc.p_sign_posn = %d (expected %d)\n", 209 lc->p_sign_posn, localeConv->p_sign_posn); 210 problemCount++; 211 } 212 if (lc->n_cs_precedes != localeConv->n_cs_precedes) { 213 printf("\tPROBLEM: lc.n_cs_precedes = %d (expected %d)\n", 214 lc->n_cs_precedes, localeConv->n_cs_precedes); 215 problemCount++; 216 } 217 if (lc->n_sep_by_space != localeConv->n_sep_by_space) { 218 printf("\tPROBLEM: lc.n_sep_by_space = %d (expected %d)\n", 219 lc->n_sep_by_space, localeConv->n_sep_by_space); 220 problemCount++; 221 } 222 if (lc->n_sign_posn != localeConv->n_sign_posn) { 223 printf("\tPROBLEM: lc.n_sign_posn = %d (expected %d)\n", 224 lc->n_sign_posn, localeConv->n_sign_posn); 225 problemCount++; 226 } 227 if (lc->int_p_cs_precedes != localeConv->int_p_cs_precedes) { 228 printf("\tPROBLEM: lc.int_p_cs_precedes = %d (expected %d)\n", 229 lc->int_p_cs_precedes, localeConv->int_p_cs_precedes); 230 problemCount++; 231 } 232 if (lc->int_p_sep_by_space != localeConv->int_p_sep_by_space) { 233 printf("\tPROBLEM: lc.int_p_sep_by_space = %d (expected %d)\n", 234 lc->int_p_sep_by_space, localeConv->int_p_sep_by_space); 235 problemCount++; 236 } 237 if (lc->int_p_sign_posn != localeConv->int_p_sign_posn) { 238 printf("\tPROBLEM: lc.int_p_sign_posn = %d (expected %d)\n", 239 lc->int_p_sign_posn, localeConv->int_p_sign_posn); 240 problemCount++; 241 } 242 if (lc->int_n_cs_precedes != localeConv->int_n_cs_precedes) { 243 printf("\tPROBLEM: lc.int_n_cs_precedes = %d (expected %d)\n", 244 lc->int_n_cs_precedes, localeConv->int_n_cs_precedes); 245 problemCount++; 246 } 247 if (lc->int_n_sep_by_space != localeConv->int_n_sep_by_space) { 248 printf("\tPROBLEM: lc.int_n_sep_by_space = %d (expected %d)\n", 249 lc->int_n_sep_by_space, localeConv->int_n_sep_by_space); 250 problemCount++; 251 } 252 if (lc->int_n_sign_posn != localeConv->int_n_sign_posn) { 253 printf("\tPROBLEM: lc.int_n_sign_posn = %d (expected %d)\n", 254 lc->int_n_sign_posn, localeConv->int_n_sign_posn); 255 problemCount++; 256 } 257 } 258 if (problemCount) 259 printf("\t%d problem(s) found!\n", problemCount); 260 else 261 printf("\tall fine\n"); 262 } 263 264 265 void 266 test_localeconv() 267 { 268 const lconv lconv_posix = { 269 (char*)".", 270 (char*)"", 271 (char*)"", 272 (char*)"", 273 (char*)"", 274 (char*)"", 275 (char*)"", 276 (char*)"", 277 (char*)"", 278 (char*)"", 279 CHAR_MAX, 280 CHAR_MAX, 281 CHAR_MAX, 282 CHAR_MAX, 283 CHAR_MAX, 284 CHAR_MAX, 285 CHAR_MAX, 286 CHAR_MAX, 287 CHAR_MAX, 288 CHAR_MAX, 289 CHAR_MAX, 290 CHAR_MAX, 291 CHAR_MAX, 292 CHAR_MAX 293 }; 294 test_localeconv("POSIX", &lconv_posix); 295 296 const lconv lconv_de = { 297 (char*)",", 298 (char*)".", 299 (char*)"\x03", 300 (char*)"EUR ", 301 (char*)"€", 302 (char*)",", 303 (char*)".", 304 (char*)"\x03", 305 (char*)"", 306 (char*)"-", 307 2, 308 2, 309 0, 310 1, 311 0, 312 1, 313 1, 314 1, 315 0, 316 1, 317 0, 318 1, 319 1, 320 1 321 }; 322 test_localeconv("de_DE", &lconv_de); 323 324 const lconv lconv_de_iso = { 325 (char*)",", 326 (char*)".", 327 (char*)"\x03", 328 (char*)"EUR ", 329 (char*)"EUR", 330 (char*)",", 331 (char*)".", 332 (char*)"\x03", 333 (char*)"", 334 (char*)"-", 335 2, 336 2, 337 0, 338 1, 339 0, 340 1, 341 1, 342 1, 343 0, 344 1, 345 0, 346 1, 347 1, 348 1 349 }; 350 test_localeconv("de_DE.ISO8859-1", &lconv_de_iso); 351 352 const lconv lconv_hr = { 353 (char*)",", 354 (char*)".", 355 (char*)"\x03", 356 (char*)"HRK ", 357 (char*)"kn", 358 (char*)",", 359 (char*)".", 360 (char*)"\x03", 361 (char*)"", 362 (char*)"-", 363 2, 364 2, 365 0, 366 1, 367 0, 368 1, 369 1, 370 1, 371 0, 372 1, 373 0, 374 1, 375 1, 376 1 377 }; 378 test_localeconv("hr_HR.ISO8859-2", &lconv_hr); 379 380 const lconv lconv_de_CH = { 381 (char*)".", 382 (char*)"'", 383 (char*)"\x03", 384 (char*)"CHF ", 385 (char*)"CHF", 386 (char*)".", 387 (char*)"'", 388 (char*)"\x03", 389 (char*)"", 390 (char*)"-", 391 2, 392 2, 393 1, 394 1, 395 1, 396 0, 397 4, 398 4, 399 1, 400 1, 401 1, 402 0, 403 4, 404 4 405 }; 406 test_localeconv("de_CH", &lconv_de_CH); 407 408 const lconv lconv_gu_IN = { 409 (char*)".", 410 (char*)",", 411 (char*)"\x03\x02", 412 (char*)"INR ", 413 (char*)"રુ", 414 (char*)".", 415 (char*)",", 416 (char*)"\x03\x02", 417 (char*)"", 418 (char*)"-", 419 2, 420 2, 421 1, 422 1, 423 1, 424 1, 425 1, 426 1, 427 1, 428 1, 429 1, 430 1, 431 1, 432 1 433 }; 434 test_localeconv("gu_IN", &lconv_gu_IN); 435 436 const lconv lconv_it = { 437 (char*)",", 438 (char*)".", 439 (char*)"\x03", 440 (char*)"EUR ", 441 (char*)"€", 442 (char*)",", 443 (char*)".", 444 (char*)"\x03", 445 (char*)"", 446 (char*)"-", 447 2, 448 2, 449 1, 450 1, 451 1, 452 1, 453 1, 454 1, 455 1, 456 1, 457 1, 458 1, 459 1, 460 1 461 }; 462 test_localeconv("it_IT", &lconv_it); 463 464 const lconv lconv_nl = { 465 (char*)",", 466 (char*)".", 467 (char*)"\x03", 468 (char*)"EUR ", 469 (char*)"€", 470 (char*)",", 471 (char*)".", 472 (char*)"\x03", 473 (char*)"", 474 (char*)"-", 475 2, 476 2, 477 1, 478 1, 479 1, 480 1, 481 2, 482 2, 483 1, 484 1, 485 1, 486 1, 487 2, 488 2 489 }; 490 test_localeconv("nl_NL", &lconv_nl); 491 492 const lconv lconv_nb = { 493 (char*)",", 494 (char*)" ", 495 (char*)"\x03", 496 (char*)"NOK ", 497 (char*)"kr", 498 (char*)",", 499 (char*)" ", 500 (char*)"\x03", 501 (char*)"", 502 (char*)"-", 503 2, 504 2, 505 1, 506 1, 507 1, 508 1, 509 1, 510 1, 511 1, 512 1, 513 1, 514 1, 515 1, 516 1 517 }; 518 test_localeconv("nb_NO", &lconv_nb); 519 } 520 521 522 // #pragma mark - strftime ----------------------------------------------------- 523 524 525 struct strftime_data { 526 const char* format; 527 const char* result; 528 }; 529 530 531 void 532 test_strftime(const char* locale, const strftime_data data[]) 533 { 534 setlocale(LC_TIME, locale); 535 printf("strftime for '%s'\n", locale); 536 537 time_t nowSecs = 1279391169; // pure magic 538 tm* now = localtime(&nowSecs); 539 int problemCount = 0; 540 for(int i = 0; data[i].format != NULL; ++i) { 541 char buf[100]; 542 strftime(buf, 100, data[i].format, now); 543 if (strcmp(buf, data[i].result) != 0) { 544 printf("\tPROBLEM: strftime(\"%s\") = \"%s\" (expected \"%s\")\n", 545 data[i].format, buf, data[i].result); 546 problemCount++; 547 } 548 } 549 if (problemCount) 550 printf("\t%d problem(s) found!\n", problemCount); 551 else 552 printf("\tall fine\n"); 553 } 554 555 556 void 557 test_strftime() 558 { 559 setenv("TZ", "GMT", 1); 560 561 const strftime_data strftime_posix[] = { 562 { "%c", "Sat Jul 17 18:26:09 2010" }, 563 { "%x", "07/17/10" }, 564 { "%X", "18:26:09" }, 565 { "%a", "Sat" }, 566 { "%A", "Saturday" }, 567 { "%b", "Jul" }, 568 { "%B", "July" }, 569 { NULL, NULL } 570 }; 571 test_strftime("POSIX", strftime_posix); 572 573 const strftime_data strftime_de[] = { 574 { "%c", "Samstag, 17. Juli 2010 18:26:09 GMT" }, 575 { "%x", "17.07.2010" }, 576 { "%X", "18:26:09" }, 577 { "%a", "Sa." }, 578 { "%A", "Samstag" }, 579 { "%b", "Jul" }, 580 { "%B", "Juli" }, 581 { NULL, NULL } 582 }; 583 test_strftime("de_DE.UTF-8", strftime_de); 584 585 const strftime_data strftime_hr[] = { 586 { "%c", "subota, 17. srpnja 2010. 18:26:09 GMT" }, 587 { "%x", "17. 07. 2010." }, 588 { "%X", "18:26:09" }, 589 { "%a", "sub" }, 590 { "%A", "subota" }, 591 { "%b", "srp" }, 592 { "%B", "srpnja" }, 593 { NULL, NULL } 594 }; 595 test_strftime("hr_HR.ISO8859-2", strftime_hr); 596 597 const strftime_data strftime_gu[] = { 598 { "%c", "શનિવાર, 17 જુલાઈ, 2010 06:26:09 PM GMT" }, 599 { "%x", "17 જુલાઈ, 2010" }, 600 { "%X", "06:26:09 PM" }, 601 { "%a", "શનિ" }, 602 { "%A", "શનિવાર" }, 603 { "%b", "જુલાઈ" }, 604 { "%B", "જુલાઈ" }, 605 { NULL, NULL } 606 }; 607 test_strftime("gu_IN", strftime_gu); 608 609 const strftime_data strftime_it[] = { 610 { "%c", "sabato 17 luglio 2010 18:26:09 GMT" }, 611 { "%x", "17/lug/2010" }, 612 { "%X", "18:26:09" }, 613 { "%a", "sab" }, 614 { "%A", "sabato" }, 615 { "%b", "lug" }, 616 { "%B", "luglio" }, 617 { NULL, NULL } 618 }; 619 test_strftime("it_IT", strftime_it); 620 621 const strftime_data strftime_nl[] = { 622 { "%c", "zaterdag 17 juli 2010 18:26:09 GMT" }, 623 { "%x", "17 jul. 2010" }, 624 { "%X", "18:26:09" }, 625 { "%a", "za" }, 626 { "%A", "zaterdag" }, 627 { "%b", "jul." }, 628 { "%B", "juli" }, 629 { NULL, NULL } 630 }; 631 test_strftime("nl_NL", strftime_nl); 632 633 const strftime_data strftime_nb[] = { 634 { "%c", "lørdag 17. juli 2010 kl. 18:26:09 GMT" }, 635 { "%x", "17. juli 2010" }, 636 { "%X", "18:26:09" }, 637 { "%a", "lør." }, 638 { "%A", "lørdag" }, 639 { "%b", "juli" }, 640 { "%B", "juli" }, 641 { NULL, NULL } 642 }; 643 test_strftime("nb_NO", strftime_nb); 644 } 645 646 647 // #pragma mark - ctype -------------------------------------------------------- 648 649 650 unsigned short 651 determineFullClassInfo(int i) 652 { 653 unsigned short classInfo = 0; 654 655 if (isblank(i)) 656 classInfo |= _ISblank; 657 if (iscntrl(i)) 658 classInfo |= _IScntrl; 659 if (ispunct(i)) 660 classInfo |= _ISpunct; 661 if (isalnum(i)) 662 classInfo |= _ISalnum; 663 if (isupper(i)) 664 classInfo |= _ISupper; 665 if (islower(i)) 666 classInfo |= _ISlower; 667 if (isalpha(i)) 668 classInfo |= _ISalpha; 669 if (isdigit(i)) 670 classInfo |= _ISdigit; 671 if (isxdigit(i)) 672 classInfo |= _ISxdigit; 673 if (isspace(i)) 674 classInfo |= _ISspace; 675 if (isprint(i)) 676 classInfo |= _ISprint; 677 if (isgraph(i)) 678 classInfo |= _ISgraph; 679 680 return classInfo; 681 } 682 683 684 void 685 test_ctype(const char* locale, const unsigned short int classInfos[], 686 const int toLowerMap[], const int toUpperMap[]) 687 { 688 setlocale(LC_CTYPE, locale); 689 printf("ctype of %s locale\n", locale); 690 691 int problemCount = 0; 692 for (int i = -1; i < 256; ++i) { 693 unsigned short classInfo = determineFullClassInfo(i); 694 695 if (i < 255) { 696 char iAsChar = (char)i; 697 unsigned short classInfoFromChar = determineFullClassInfo(iAsChar); 698 699 if (classInfo != classInfoFromChar) { 700 printf("\tPROBLEM: ctype((int)%d)=%x, but ctype((char)%d)=%x\n", 701 i, classInfo, i, classInfoFromChar); 702 problemCount++; 703 } 704 } 705 if (classInfo != classInfos[i + 1]) { 706 printf("\tPROBLEM: ctype(%d) = %x (expected %x)\n", i, classInfo, 707 classInfos[i + 1]); 708 problemCount++; 709 } 710 int lower = tolower(i); 711 if (lower != toLowerMap[i + 1]) { 712 printf("\tPROBLEM: tolower(%d) = %x (expected %x)\n", i, lower, 713 toLowerMap[i + 1]); 714 problemCount++; 715 } 716 int upper = toupper(i); 717 if (upper != toUpperMap[i + 1]) { 718 printf("\tPROBLEM: toupper(%d) = %x (expected %x)\n", i, upper, 719 toUpperMap[i + 1]); 720 problemCount++; 721 } 722 } 723 if (problemCount) 724 printf("\t%d problem(s) found!\n", problemCount); 725 else 726 printf("\tall fine\n"); 727 } 728 729 730 void 731 test_ctype() 732 { 733 const unsigned short int classInfos_posix[257] = { 734 /* -1 */ 0, // neutral value 735 /* 0 */ _IScntrl, _IScntrl, _IScntrl, _IScntrl, _IScntrl, _IScntrl, _IScntrl, _IScntrl, 736 /* 8 */ _IScntrl, _ISblank|_IScntrl|_ISspace, _IScntrl|_ISspace, _IScntrl|_ISspace, _IScntrl|_ISspace, _IScntrl|_ISspace, _IScntrl, _IScntrl, 737 /* 16 */ _IScntrl, _IScntrl, _IScntrl, _IScntrl, _IScntrl, _IScntrl, _IScntrl, _IScntrl, 738 /* 24 */ _IScntrl, _IScntrl, _IScntrl, _IScntrl, _IScntrl, _IScntrl, _IScntrl, _IScntrl, 739 /* 32 */ _ISblank|_ISspace|_ISprint, _ISpunct|_ISprint|_ISgraph, _ISpunct|_ISprint|_ISgraph, _ISpunct|_ISprint|_ISgraph, _ISpunct|_ISprint|_ISgraph, _ISpunct|_ISprint|_ISgraph, _ISpunct|_ISprint|_ISgraph, _ISpunct|_ISprint|_ISgraph, 740 /* 40 */ _ISpunct|_ISprint|_ISgraph, _ISpunct|_ISprint|_ISgraph, _ISpunct|_ISprint|_ISgraph, _ISpunct|_ISprint|_ISgraph, _ISpunct|_ISprint|_ISgraph, _ISpunct|_ISprint|_ISgraph, _ISpunct|_ISprint|_ISgraph, _ISpunct|_ISprint|_ISgraph, 741 /* 48 */ _ISalnum|_ISdigit|_ISxdigit|_ISprint|_ISgraph, _ISalnum|_ISdigit|_ISxdigit|_ISprint|_ISgraph, _ISalnum|_ISdigit|_ISxdigit|_ISprint|_ISgraph, _ISalnum|_ISdigit|_ISxdigit|_ISprint|_ISgraph, _ISalnum|_ISdigit|_ISxdigit|_ISprint|_ISgraph, _ISalnum|_ISdigit|_ISxdigit|_ISprint|_ISgraph, _ISalnum|_ISdigit|_ISxdigit|_ISprint|_ISgraph, _ISalnum|_ISdigit|_ISxdigit|_ISprint|_ISgraph, 742 /* 56 */ _ISalnum|_ISdigit|_ISxdigit|_ISprint|_ISgraph, _ISalnum|_ISdigit|_ISxdigit|_ISprint|_ISgraph, _ISpunct|_ISprint|_ISgraph, _ISpunct|_ISprint|_ISgraph, _ISpunct|_ISprint|_ISgraph, _ISpunct|_ISprint|_ISgraph, _ISpunct|_ISprint|_ISgraph, _ISpunct|_ISprint|_ISgraph, 743 /* 64 */ _ISpunct|_ISprint|_ISgraph, _ISalnum|_ISupper|_ISalpha|_ISxdigit|_ISprint|_ISgraph, _ISalnum|_ISupper|_ISalpha|_ISxdigit|_ISprint|_ISgraph, _ISalnum|_ISupper|_ISalpha|_ISxdigit|_ISprint|_ISgraph, _ISalnum|_ISupper|_ISalpha|_ISxdigit|_ISprint|_ISgraph, _ISalnum|_ISupper|_ISalpha|_ISxdigit|_ISprint|_ISgraph, _ISalnum|_ISupper|_ISalpha|_ISxdigit|_ISprint|_ISgraph, _ISalnum|_ISupper|_ISalpha|_ISprint|_ISgraph, 744 /* 72 */ _ISalnum|_ISupper|_ISalpha|_ISprint|_ISgraph, _ISalnum|_ISupper|_ISalpha|_ISprint|_ISgraph, _ISalnum|_ISupper|_ISalpha|_ISprint|_ISgraph, _ISalnum|_ISupper|_ISalpha|_ISprint|_ISgraph, _ISalnum|_ISupper|_ISalpha|_ISprint|_ISgraph, _ISalnum|_ISupper|_ISalpha|_ISprint|_ISgraph, _ISalnum|_ISupper|_ISalpha|_ISprint|_ISgraph, _ISalnum|_ISupper|_ISalpha|_ISprint|_ISgraph, 745 /* 80 */ _ISalnum|_ISupper|_ISalpha|_ISprint|_ISgraph, _ISalnum|_ISupper|_ISalpha|_ISprint|_ISgraph, _ISalnum|_ISupper|_ISalpha|_ISprint|_ISgraph, _ISalnum|_ISupper|_ISalpha|_ISprint|_ISgraph, _ISalnum|_ISupper|_ISalpha|_ISprint|_ISgraph, _ISalnum|_ISupper|_ISalpha|_ISprint|_ISgraph, _ISalnum|_ISupper|_ISalpha|_ISprint|_ISgraph, _ISalnum|_ISupper|_ISalpha|_ISprint|_ISgraph, 746 /* 88 */ _ISalnum|_ISupper|_ISalpha|_ISprint|_ISgraph, _ISalnum|_ISupper|_ISalpha|_ISprint|_ISgraph, _ISalnum|_ISupper|_ISalpha|_ISprint|_ISgraph, _ISpunct|_ISprint|_ISgraph, _ISpunct|_ISprint|_ISgraph, _ISpunct|_ISprint|_ISgraph, _ISpunct|_ISprint|_ISgraph, _ISpunct|_ISprint|_ISgraph, 747 /* 96 */ _ISpunct|_ISprint|_ISgraph, _ISalnum|_ISlower|_ISalpha|_ISxdigit|_ISprint|_ISgraph, _ISalnum|_ISlower|_ISalpha|_ISxdigit|_ISprint|_ISgraph, _ISalnum|_ISlower|_ISalpha|_ISxdigit|_ISprint|_ISgraph, _ISalnum|_ISlower|_ISalpha|_ISxdigit|_ISprint|_ISgraph, _ISalnum|_ISlower|_ISalpha|_ISxdigit|_ISprint|_ISgraph, _ISalnum|_ISlower|_ISalpha|_ISxdigit|_ISprint|_ISgraph, _ISalnum|_ISlower|_ISalpha|_ISprint|_ISgraph, 748 /* 104 */ _ISalnum|_ISlower|_ISalpha|_ISprint|_ISgraph, _ISalnum|_ISlower|_ISalpha|_ISprint|_ISgraph, _ISalnum|_ISlower|_ISalpha|_ISprint|_ISgraph, _ISalnum|_ISlower|_ISalpha|_ISprint|_ISgraph, _ISalnum|_ISlower|_ISalpha|_ISprint|_ISgraph, _ISalnum|_ISlower|_ISalpha|_ISprint|_ISgraph, _ISalnum|_ISlower|_ISalpha|_ISprint|_ISgraph, _ISalnum|_ISlower|_ISalpha|_ISprint|_ISgraph, 749 /* 112 */ _ISalnum|_ISlower|_ISalpha|_ISprint|_ISgraph, _ISalnum|_ISlower|_ISalpha|_ISprint|_ISgraph, _ISalnum|_ISlower|_ISalpha|_ISprint|_ISgraph, _ISalnum|_ISlower|_ISalpha|_ISprint|_ISgraph, _ISalnum|_ISlower|_ISalpha|_ISprint|_ISgraph, _ISalnum|_ISlower|_ISalpha|_ISprint|_ISgraph, _ISalnum|_ISlower|_ISalpha|_ISprint|_ISgraph, _ISalnum|_ISlower|_ISalpha|_ISprint|_ISgraph, 750 /* 120 */ _ISalnum|_ISlower|_ISalpha|_ISprint|_ISgraph, _ISalnum|_ISlower|_ISalpha|_ISprint|_ISgraph, _ISalnum|_ISlower|_ISalpha|_ISprint|_ISgraph, _ISpunct|_ISprint|_ISgraph, _ISpunct|_ISprint|_ISgraph, _ISpunct|_ISprint|_ISgraph, _ISpunct|_ISprint|_ISgraph, _IScntrl, 751 /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, 752 /* 136 */ 0, 0, 0, 0, 0, 0, 0, 0, 753 /* 144 */ 0, 0, 0, 0, 0, 0, 0, 0, 754 /* 152 */ 0, 0, 0, 0, 0, 0, 0, 0, 755 /* 160 */ 0, 0, 0, 0, 0, 0, 0, 0, 756 /* 168 */ 0, 0, 0, 0, 0, 0, 0, 0, 757 /* 176 */ 0, 0, 0, 0, 0, 0, 0, 0, 758 /* 184 */ 0, 0, 0, 0, 0, 0, 0, 0, 759 /* 192 */ 0, 0, 0, 0, 0, 0, 0, 0, 760 /* 200 */ 0, 0, 0, 0, 0, 0, 0, 0, 761 /* 208 */ 0, 0, 0, 0, 0, 0, 0, 0, 762 /* 216 */ 0, 0, 0, 0, 0, 0, 0, 0, 763 /* 224 */ 0, 0, 0, 0, 0, 0, 0, 0, 764 /* 232 */ 0, 0, 0, 0, 0, 0, 0, 0, 765 /* 240 */ 0, 0, 0, 0, 0, 0, 0, 0, 766 /* 248 */ 0, 0, 0, 0, 0, 0, 0, 0, 767 }; 768 const int toLowerMap_posix[257] = { 769 /* -1 */ -1, // identity value 770 /* 0 */ 0, 1, 2, 3, 4, 5, 6, 7, 771 /* 8 */ 8, 9, 10, 11, 12, 13, 14, 15, 772 /* 16 */ 16, 17, 18, 19, 20, 21, 22, 23, 773 /* 24 */ 24, 25, 26, 27, 28, 29, 30, 31, 774 /* 32 */ 32, 33, 34, 35, 36, 37, 38, 39, 775 /* 40 */ 40, 41, 42, 43, 44, 45, 46, 47, 776 /* 48 */ '0', '1', '2', '3', '4', '5', '6', '7', 777 /* 56 */ '8', '9', 58, 59, 60, 61, 62, 63, 778 /* 64 */ 64, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 779 /* 72 */ 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 780 /* 80 */ 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 781 /* 88 */ 'x', 'y', 'z', 91, 92, 93, 94, 95, 782 /* 96 */ 96, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 783 /* 104 */ 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 784 /* 112 */ 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 785 /* 120 */ 'x', 'y', 'z', 123, 124, 125, 126, 127, 786 /* 128 */ 128, 129, 130, 131, 132, 133, 134, 135, 787 /* 136 */ 136, 137, 138, 139, 140, 141, 142, 143, 788 /* 144 */ 144, 145, 146, 147, 148, 149, 150, 151, 789 /* 152 */ 152, 153, 154, 155, 156, 157, 158, 159, 790 /* 160 */ 160, 161, 162, 163, 164, 165, 166, 167, 791 /* 168 */ 168, 169, 170, 171, 172, 173, 174, 175, 792 /* 176 */ 176, 177, 178, 179, 180, 181, 182, 183, 793 /* 184 */ 184, 185, 186, 187, 188, 189, 190, 191, 794 /* 192 */ 192, 193, 194, 195, 196, 197, 198, 199, 795 /* 200 */ 200, 201, 202, 203, 204, 205, 206, 207, 796 /* 208 */ 208, 209, 210, 211, 212, 213, 214, 215, 797 /* 216 */ 216, 217, 218, 219, 220, 221, 222, 223, 798 /* 224 */ 224, 225, 226, 227, 228, 229, 230, 231, 799 /* 232 */ 232, 233, 234, 235, 236, 237, 238, 239, 800 /* 240 */ 240, 241, 242, 243, 244, 245, 246, 247, 801 /* 248 */ 248, 249, 250, 251, 252, 253, 254, 255, 802 }; 803 const int toUpperMap_posix[257] = { 804 /* -1 */ -1, // identity value 805 /* 0 */ 0, 1, 2, 3, 4, 5, 6, 7, 806 /* 8 */ 8, 9, 10, 11, 12, 13, 14, 15, 807 /* 16 */ 16, 17, 18, 19, 20, 21, 22, 23, 808 /* 24 */ 24, 25, 26, 27, 28, 29, 30, 31, 809 /* 32 */ 32, 33, 34, 35, 36, 37, 38, 39, 810 /* 40 */ 40, 41, 42, 43, 44, 45, 46, 47, 811 /* 48 */ '0', '1', '2', '3', '4', '5', '6', '7', 812 /* 56 */ '8', '9', 58, 59, 60, 61, 62, 63, 813 /* 64 */ 64, 'A', 'B', 'C', 'D', 'E', 'F', 'G', 814 /* 72 */ 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 815 /* 80 */ 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 816 /* 88 */ 'X', 'Y', 'Z', 91, 92, 93, 94, 95, 817 /* 96 */ 96, 'A', 'B', 'C', 'D', 'E', 'F', 'G', 818 /* 104 */ 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 819 /* 112 */ 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 820 /* 120 */ 'X', 'Y', 'Z', 123, 124, 125, 126, 127, 821 /* 128 */ 128, 129, 130, 131, 132, 133, 134, 135, 822 /* 136 */ 136, 137, 138, 139, 140, 141, 142, 143, 823 /* 144 */ 144, 145, 146, 147, 148, 149, 150, 151, 824 /* 152 */ 152, 153, 154, 155, 156, 157, 158, 159, 825 /* 160 */ 160, 161, 162, 163, 164, 165, 166, 167, 826 /* 168 */ 168, 169, 170, 171, 172, 173, 174, 175, 827 /* 176 */ 176, 177, 178, 179, 180, 181, 182, 183, 828 /* 184 */ 184, 185, 186, 187, 188, 189, 190, 191, 829 /* 192 */ 192, 193, 194, 195, 196, 197, 198, 199, 830 /* 200 */ 200, 201, 202, 203, 204, 205, 206, 207, 831 /* 208 */ 208, 209, 210, 211, 212, 213, 214, 215, 832 /* 216 */ 216, 217, 218, 219, 220, 221, 222, 223, 833 /* 224 */ 224, 225, 226, 227, 228, 229, 230, 231, 834 /* 232 */ 232, 233, 234, 235, 236, 237, 238, 239, 835 /* 240 */ 240, 241, 242, 243, 244, 245, 246, 247, 836 /* 248 */ 248, 249, 250, 251, 252, 253, 254, 255, 837 }; 838 test_ctype("POSIX", classInfos_posix, toLowerMap_posix, toUpperMap_posix); 839 840 const unsigned short int classInfos_de[257] = { 841 /* -1 */ 0, // neutral value 842 /* 0 */ _IScntrl, _IScntrl, _IScntrl, _IScntrl, _IScntrl, _IScntrl, _IScntrl, _IScntrl, 843 /* 8 */ _IScntrl, _ISblank|_IScntrl|_ISspace, _IScntrl|_ISspace, _IScntrl|_ISspace, _IScntrl|_ISspace, _IScntrl|_ISspace, _IScntrl, _IScntrl, 844 /* 16 */ _IScntrl, _IScntrl, _IScntrl, _IScntrl, _IScntrl, _IScntrl, _IScntrl, _IScntrl, 845 /* 24 */ _IScntrl, _IScntrl, _IScntrl, _IScntrl, _IScntrl, _IScntrl, _IScntrl, _IScntrl, 846 /* 32 */ _ISblank|_ISspace|_ISprint, _ISpunct|_ISprint|_ISgraph, _ISpunct|_ISprint|_ISgraph, _ISpunct|_ISprint|_ISgraph, _ISprint|_ISgraph, _ISpunct|_ISprint|_ISgraph, _ISpunct|_ISprint|_ISgraph, _ISpunct|_ISprint|_ISgraph, 847 /* 40 */ _ISpunct|_ISprint|_ISgraph, _ISpunct|_ISprint|_ISgraph, _ISpunct|_ISprint|_ISgraph, _ISprint|_ISgraph, _ISpunct|_ISprint|_ISgraph, _ISpunct|_ISprint|_ISgraph, _ISpunct|_ISprint|_ISgraph, _ISpunct|_ISprint|_ISgraph, 848 /* 48 */ _ISalnum|_ISdigit|_ISxdigit|_ISprint|_ISgraph, _ISalnum|_ISdigit|_ISxdigit|_ISprint|_ISgraph, _ISalnum|_ISdigit|_ISxdigit|_ISprint|_ISgraph, _ISalnum|_ISdigit|_ISxdigit|_ISprint|_ISgraph, _ISalnum|_ISdigit|_ISxdigit|_ISprint|_ISgraph, _ISalnum|_ISdigit|_ISxdigit|_ISprint|_ISgraph, _ISalnum|_ISdigit|_ISxdigit|_ISprint|_ISgraph, _ISalnum|_ISdigit|_ISxdigit|_ISprint|_ISgraph, 849 /* 56 */ _ISalnum|_ISdigit|_ISxdigit|_ISprint|_ISgraph, _ISalnum|_ISdigit|_ISxdigit|_ISprint|_ISgraph, _ISpunct|_ISprint|_ISgraph, _ISpunct|_ISprint|_ISgraph, _ISprint|_ISgraph, _ISprint|_ISgraph, _ISprint|_ISgraph, _ISpunct|_ISprint|_ISgraph, 850 /* 64 */ _ISpunct|_ISprint|_ISgraph, _ISalnum|_ISupper|_ISalpha|_ISxdigit|_ISprint|_ISgraph, _ISalnum|_ISupper|_ISalpha|_ISxdigit|_ISprint|_ISgraph, _ISalnum|_ISupper|_ISalpha|_ISxdigit|_ISprint|_ISgraph, _ISalnum|_ISupper|_ISalpha|_ISxdigit|_ISprint|_ISgraph, _ISalnum|_ISupper|_ISalpha|_ISxdigit|_ISprint|_ISgraph, _ISalnum|_ISupper|_ISalpha|_ISxdigit|_ISprint|_ISgraph, _ISalnum|_ISupper|_ISalpha|_ISprint|_ISgraph, 851 /* 72 */ _ISalnum|_ISupper|_ISalpha|_ISprint|_ISgraph, _ISalnum|_ISupper|_ISalpha|_ISprint|_ISgraph, _ISalnum|_ISupper|_ISalpha|_ISprint|_ISgraph, _ISalnum|_ISupper|_ISalpha|_ISprint|_ISgraph, _ISalnum|_ISupper|_ISalpha|_ISprint|_ISgraph, _ISalnum|_ISupper|_ISalpha|_ISprint|_ISgraph, _ISalnum|_ISupper|_ISalpha|_ISprint|_ISgraph, _ISalnum|_ISupper|_ISalpha|_ISprint|_ISgraph, 852 /* 80 */ _ISalnum|_ISupper|_ISalpha|_ISprint|_ISgraph, _ISalnum|_ISupper|_ISalpha|_ISprint|_ISgraph, _ISalnum|_ISupper|_ISalpha|_ISprint|_ISgraph, _ISalnum|_ISupper|_ISalpha|_ISprint|_ISgraph, _ISalnum|_ISupper|_ISalpha|_ISprint|_ISgraph, _ISalnum|_ISupper|_ISalpha|_ISprint|_ISgraph, _ISalnum|_ISupper|_ISalpha|_ISprint|_ISgraph, _ISalnum|_ISupper|_ISalpha|_ISprint|_ISgraph, 853 /* 88 */ _ISalnum|_ISupper|_ISalpha|_ISprint|_ISgraph, _ISalnum|_ISupper|_ISalpha|_ISprint|_ISgraph, _ISalnum|_ISupper|_ISalpha|_ISprint|_ISgraph, _ISpunct|_ISprint|_ISgraph, _ISpunct|_ISprint|_ISgraph, _ISpunct|_ISprint|_ISgraph, _ISprint|_ISgraph, _ISpunct|_ISprint|_ISgraph, 854 /* 96 */ _ISprint|_ISgraph, _ISalnum|_ISlower|_ISalpha|_ISxdigit|_ISprint|_ISgraph, _ISalnum|_ISlower|_ISalpha|_ISxdigit|_ISprint|_ISgraph, _ISalnum|_ISlower|_ISalpha|_ISxdigit|_ISprint|_ISgraph, _ISalnum|_ISlower|_ISalpha|_ISxdigit|_ISprint|_ISgraph, _ISalnum|_ISlower|_ISalpha|_ISxdigit|_ISprint|_ISgraph, _ISalnum|_ISlower|_ISalpha|_ISxdigit|_ISprint|_ISgraph, _ISalnum|_ISlower|_ISalpha|_ISprint|_ISgraph, 855 /* 104 */ _ISalnum|_ISlower|_ISalpha|_ISprint|_ISgraph, _ISalnum|_ISlower|_ISalpha|_ISprint|_ISgraph, _ISalnum|_ISlower|_ISalpha|_ISprint|_ISgraph, _ISalnum|_ISlower|_ISalpha|_ISprint|_ISgraph, _ISalnum|_ISlower|_ISalpha|_ISprint|_ISgraph, _ISalnum|_ISlower|_ISalpha|_ISprint|_ISgraph, _ISalnum|_ISlower|_ISalpha|_ISprint|_ISgraph, _ISalnum|_ISlower|_ISalpha|_ISprint|_ISgraph, 856 /* 112 */ _ISalnum|_ISlower|_ISalpha|_ISprint|_ISgraph, _ISalnum|_ISlower|_ISalpha|_ISprint|_ISgraph, _ISalnum|_ISlower|_ISalpha|_ISprint|_ISgraph, _ISalnum|_ISlower|_ISalpha|_ISprint|_ISgraph, _ISalnum|_ISlower|_ISalpha|_ISprint|_ISgraph, _ISalnum|_ISlower|_ISalpha|_ISprint|_ISgraph, _ISalnum|_ISlower|_ISalpha|_ISprint|_ISgraph, _ISalnum|_ISlower|_ISalpha|_ISprint|_ISgraph, 857 /* 120 */ _ISalnum|_ISlower|_ISalpha|_ISprint|_ISgraph, _ISalnum|_ISlower|_ISalpha|_ISprint|_ISgraph, _ISalnum|_ISlower|_ISalpha|_ISprint|_ISgraph, _ISpunct|_ISprint|_ISgraph, _ISprint|_ISgraph, _ISpunct|_ISprint|_ISgraph, _ISprint|_ISgraph, _IScntrl, 858 /* 128 */ _IScntrl, _IScntrl, _IScntrl, _IScntrl, _IScntrl, _IScntrl|_ISspace, _IScntrl, _IScntrl, 859 /* 136 */ _IScntrl, _IScntrl, _IScntrl, _IScntrl, _IScntrl, _IScntrl, _IScntrl, _IScntrl, 860 /* 144 */ _IScntrl, _IScntrl, _IScntrl, _IScntrl, _IScntrl, _IScntrl, _IScntrl, _IScntrl, 861 /* 152 */ _IScntrl, _IScntrl, _IScntrl, _IScntrl, _IScntrl, _IScntrl, _IScntrl, _IScntrl, 862 /* 160 */ _ISprint|_ISspace|_ISblank, _ISprint|_ISgraph|_ISpunct, _ISprint|_ISgraph, _ISprint|_ISgraph, _ISprint|_ISgraph, _ISprint|_ISgraph, _ISprint|_ISgraph, _ISprint|_ISgraph, 863 /* 168 */ _ISprint|_ISgraph, _ISprint|_ISgraph, _ISprint|_ISgraph|_ISalnum|_ISalpha|_ISlower, _ISprint|_ISgraph|_ISpunct, _ISprint|_ISgraph, _ISprint|_ISgraph, _ISprint|_ISgraph, _ISprint|_ISgraph, 864 /* 176 */ _ISprint|_ISgraph, _ISprint|_ISgraph, _ISprint|_ISgraph, _ISprint|_ISgraph, _ISprint|_ISgraph, _ISprint|_ISgraph|_ISalnum|_ISalpha|_ISlower, _ISprint|_ISgraph, _ISprint|_ISgraph|_ISpunct, 865 /* 184 */ _ISprint|_ISgraph, _ISprint|_ISgraph, _ISprint|_ISgraph|_ISalnum|_ISalpha|_ISlower, _ISprint|_ISgraph|_ISpunct, _ISprint|_ISgraph, _ISprint|_ISgraph, _ISprint|_ISgraph, _ISprint|_ISgraph|_ISpunct, 866 /* 192 */ _ISprint|_ISgraph|_ISalnum|_ISalpha|_ISupper, _ISprint|_ISgraph|_ISalnum|_ISalpha|_ISupper, _ISprint|_ISgraph|_ISalnum|_ISalpha|_ISupper, _ISprint|_ISgraph|_ISalnum|_ISalpha|_ISupper, _ISprint|_ISgraph|_ISalnum|_ISalpha|_ISupper, _ISprint|_ISgraph|_ISalnum|_ISalpha|_ISupper, _ISprint|_ISgraph|_ISalnum|_ISalpha|_ISupper, _ISprint|_ISgraph|_ISalnum|_ISalpha|_ISupper, 867 /* 200 */ _ISprint|_ISgraph|_ISalnum|_ISalpha|_ISupper, _ISprint|_ISgraph|_ISalnum|_ISalpha|_ISupper, _ISprint|_ISgraph|_ISalnum|_ISalpha|_ISupper, _ISprint|_ISgraph|_ISalnum|_ISalpha|_ISupper, _ISprint|_ISgraph|_ISalnum|_ISalpha|_ISupper, _ISprint|_ISgraph|_ISalnum|_ISalpha|_ISupper, _ISprint|_ISgraph|_ISalnum|_ISalpha|_ISupper, _ISprint|_ISgraph|_ISalnum|_ISalpha|_ISupper, 868 /* 208 */ _ISprint|_ISgraph|_ISalnum|_ISalpha|_ISupper, _ISprint|_ISgraph|_ISalnum|_ISalpha|_ISupper, _ISprint|_ISgraph|_ISalnum|_ISalpha|_ISupper, _ISprint|_ISgraph|_ISalnum|_ISalpha|_ISupper, _ISprint|_ISgraph|_ISalnum|_ISalpha|_ISupper, _ISprint|_ISgraph|_ISalnum|_ISalpha|_ISupper, _ISprint|_ISgraph|_ISalnum|_ISalpha|_ISupper, _ISprint|_ISgraph, 869 /* 216 */ _ISprint|_ISgraph|_ISalnum|_ISalpha|_ISupper, _ISprint|_ISgraph|_ISalnum|_ISalpha|_ISupper, _ISprint|_ISgraph|_ISalnum|_ISalpha|_ISupper, _ISprint|_ISgraph|_ISalnum|_ISalpha|_ISupper, _ISprint|_ISgraph|_ISalnum|_ISalpha|_ISupper, _ISprint|_ISgraph|_ISalnum|_ISalpha|_ISupper, _ISprint|_ISgraph|_ISalnum|_ISalpha|_ISupper, _ISprint|_ISgraph|_ISalnum|_ISalpha|_ISlower, 870 /* 224 */ _ISprint|_ISgraph|_ISalnum|_ISalpha|_ISlower, _ISprint|_ISgraph|_ISalnum|_ISalpha|_ISlower, _ISprint|_ISgraph|_ISalnum|_ISalpha|_ISlower, _ISprint|_ISgraph|_ISalnum|_ISalpha|_ISlower, _ISprint|_ISgraph|_ISalnum|_ISalpha|_ISlower, _ISprint|_ISgraph|_ISalnum|_ISalpha|_ISlower, _ISprint|_ISgraph|_ISalnum|_ISalpha|_ISlower, _ISprint|_ISgraph|_ISalnum|_ISalpha|_ISlower, 871 /* 232 */ _ISprint|_ISgraph|_ISalnum|_ISalpha|_ISlower, _ISprint|_ISgraph|_ISalnum|_ISalpha|_ISlower, _ISprint|_ISgraph|_ISalnum|_ISalpha|_ISlower, _ISprint|_ISgraph|_ISalnum|_ISalpha|_ISlower, _ISprint|_ISgraph|_ISalnum|_ISalpha|_ISlower, _ISprint|_ISgraph|_ISalnum|_ISalpha|_ISlower, _ISprint|_ISgraph|_ISalnum|_ISalpha|_ISlower, _ISprint|_ISgraph|_ISalnum|_ISalpha|_ISlower, 872 /* 240 */ _ISprint|_ISgraph|_ISalnum|_ISalpha|_ISlower, _ISprint|_ISgraph|_ISalnum|_ISalpha|_ISlower, _ISprint|_ISgraph|_ISalnum|_ISalpha|_ISlower, _ISprint|_ISgraph|_ISalnum|_ISalpha|_ISlower, _ISprint|_ISgraph|_ISalnum|_ISalpha|_ISlower, _ISprint|_ISgraph|_ISalnum|_ISalpha|_ISlower, _ISprint|_ISgraph|_ISalnum|_ISalpha|_ISlower, _ISprint|_ISgraph, 873 /* 248 */ _ISprint|_ISgraph|_ISalnum|_ISalpha|_ISlower, _ISprint|_ISgraph|_ISalnum|_ISalpha|_ISlower, _ISprint|_ISgraph|_ISalnum|_ISalpha|_ISlower, _ISprint|_ISgraph|_ISalnum|_ISalpha|_ISlower, _ISprint|_ISgraph|_ISalnum|_ISalpha|_ISlower, _ISprint|_ISgraph|_ISalnum|_ISalpha|_ISlower, _ISprint|_ISgraph|_ISalnum|_ISalpha|_ISlower, _ISprint|_ISgraph|_ISalnum|_ISalpha|_ISlower, 874 }; 875 const int toLowerMap_de[257] = { 876 /* -1 */ -1, // identity value 877 /* 0 */ 0, 1, 2, 3, 4, 5, 6, 7, 878 /* 8 */ 8, 9, 10, 11, 12, 13, 14, 15, 879 /* 16 */ 16, 17, 18, 19, 20, 21, 22, 23, 880 /* 24 */ 24, 25, 26, 27, 28, 29, 30, 31, 881 /* 32 */ 32, 33, 34, 35, 36, 37, 38, 39, 882 /* 40 */ 40, 41, 42, 43, 44, 45, 46, 47, 883 /* 48 */ '0', '1', '2', '3', '4', '5', '6', '7', 884 /* 56 */ '8', '9', 58, 59, 60, 61, 62, 63, 885 /* 64 */ 64, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 886 /* 72 */ 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 887 /* 80 */ 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 888 /* 88 */ 'x', 'y', 'z', 91, 92, 93, 94, 95, 889 /* 96 */ 96, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 890 /* 104 */ 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 891 /* 112 */ 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 892 /* 120 */ 'x', 'y', 'z', 123, 124, 125, 126, 127, 893 /* 128 */ 128, 129, 130, 131, 132, 133, 134, 135, 894 /* 136 */ 136, 137, 138, 139, 140, 141, 142, 143, 895 /* 144 */ 144, 145, 146, 147, 148, 149, 150, 151, 896 /* 152 */ 152, 153, 154, 155, 156, 157, 158, 159, 897 /* 160 */ 160, 161, 162, 163, 164, 165, 166, 167, 898 /* 168 */ 168, 169, 170, 171, 172, 173, 174, 175, 899 /* 176 */ 176, 177, 178, 179, 180, 181, 182, 183, 900 /* 184 */ 184, 185, 186, 187, 188, 189, 190, 191, 901 /* 192 */ 224, 225, 226, 227, 228, 229, 230, 231, 902 /* 200 */ 232, 233, 234, 235, 236, 237, 238, 239, 903 /* 208 */ 240, 241, 242, 243, 244, 245, 246, 215, 904 /* 216 */ 248, 249, 250, 251, 252, 253, 254, 223, 905 /* 224 */ 224, 225, 226, 227, 228, 229, 230, 231, 906 /* 232 */ 232, 233, 234, 235, 236, 237, 238, 239, 907 /* 240 */ 240, 241, 242, 243, 244, 245, 246, 247, 908 /* 248 */ 248, 249, 250, 251, 252, 253, 254, 255, 909 }; 910 const int toUpperMap_de[257] = { 911 /* -1 */ -1, // identity value 912 /* 0 */ 0, 1, 2, 3, 4, 5, 6, 7, 913 /* 8 */ 8, 9, 10, 11, 12, 13, 14, 15, 914 /* 16 */ 16, 17, 18, 19, 20, 21, 22, 23, 915 /* 24 */ 24, 25, 26, 27, 28, 29, 30, 31, 916 /* 32 */ 32, 33, 34, 35, 36, 37, 38, 39, 917 /* 40 */ 40, 41, 42, 43, 44, 45, 46, 47, 918 /* 48 */ '0', '1', '2', '3', '4', '5', '6', '7', 919 /* 56 */ '8', '9', 58, 59, 60, 61, 62, 63, 920 /* 64 */ 64, 'A', 'B', 'C', 'D', 'E', 'F', 'G', 921 /* 72 */ 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 922 /* 80 */ 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 923 /* 88 */ 'X', 'Y', 'Z', 91, 92, 93, 94, 95, 924 /* 96 */ 96, 'A', 'B', 'C', 'D', 'E', 'F', 'G', 925 /* 104 */ 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 926 /* 112 */ 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 927 /* 120 */ 'X', 'Y', 'Z', 123, 124, 125, 126, 127, 928 /* 128 */ 128, 129, 130, 131, 132, 133, 134, 135, 929 /* 136 */ 136, 137, 138, 139, 140, 141, 142, 143, 930 /* 144 */ 144, 145, 146, 147, 148, 149, 150, 151, 931 /* 152 */ 152, 153, 154, 155, 156, 157, 158, 159, 932 /* 160 */ 160, 161, 162, 163, 164, 165, 166, 167, 933 /* 168 */ 168, 169, 170, 171, 172, 173, 174, 175, 934 /* 176 */ 176, 177, 178, 179, 180, 181, 182, 183, 935 /* 184 */ 184, 185, 186, 187, 188, 189, 190, 191, 936 /* 192 */ 192, 193, 194, 195, 196, 197, 198, 199, 937 /* 200 */ 200, 201, 202, 203, 204, 205, 206, 207, 938 /* 208 */ 208, 209, 210, 211, 212, 213, 214, 215, 939 /* 216 */ 216, 217, 218, 219, 220, 221, 222, 223, 940 /* 224 */ 192, 193, 194, 195, 196, 197, 198, 199, 941 /* 232 */ 200, 201, 202, 203, 204, 205, 206, 207, 942 /* 240 */ 208, 209, 210, 211, 212, 213, 214, 247, 943 /* 248 */ 216, 217, 218, 219, 220, 221, 222, 255, 944 }; 945 test_ctype("de_DE.ISO8859-1", classInfos_de, toLowerMap_de, toUpperMap_de); 946 947 const unsigned short int classInfos_utf8[257] = { 948 /* -1 */ 0, // neutral value 949 /* 0 */ _IScntrl, _IScntrl, _IScntrl, _IScntrl, _IScntrl, _IScntrl, _IScntrl, _IScntrl, 950 /* 8 */ _IScntrl, _ISblank|_IScntrl|_ISspace, _IScntrl|_ISspace, _IScntrl|_ISspace, _IScntrl|_ISspace, _IScntrl|_ISspace, _IScntrl, _IScntrl, 951 /* 16 */ _IScntrl, _IScntrl, _IScntrl, _IScntrl, _IScntrl, _IScntrl, _IScntrl, _IScntrl, 952 /* 24 */ _IScntrl, _IScntrl, _IScntrl, _IScntrl, _IScntrl, _IScntrl, _IScntrl, _IScntrl, 953 /* 32 */ _ISblank|_ISspace|_ISprint, _ISpunct|_ISprint|_ISgraph, _ISpunct|_ISprint|_ISgraph, _ISpunct|_ISprint|_ISgraph, _ISprint|_ISgraph, _ISpunct|_ISprint|_ISgraph, _ISpunct|_ISprint|_ISgraph, _ISpunct|_ISprint|_ISgraph, 954 /* 40 */ _ISpunct|_ISprint|_ISgraph, _ISpunct|_ISprint|_ISgraph, _ISpunct|_ISprint|_ISgraph, _ISprint|_ISgraph, _ISpunct|_ISprint|_ISgraph, _ISpunct|_ISprint|_ISgraph, _ISpunct|_ISprint|_ISgraph, _ISpunct|_ISprint|_ISgraph, 955 /* 48 */ _ISalnum|_ISdigit|_ISxdigit|_ISprint|_ISgraph, _ISalnum|_ISdigit|_ISxdigit|_ISprint|_ISgraph, _ISalnum|_ISdigit|_ISxdigit|_ISprint|_ISgraph, _ISalnum|_ISdigit|_ISxdigit|_ISprint|_ISgraph, _ISalnum|_ISdigit|_ISxdigit|_ISprint|_ISgraph, _ISalnum|_ISdigit|_ISxdigit|_ISprint|_ISgraph, _ISalnum|_ISdigit|_ISxdigit|_ISprint|_ISgraph, _ISalnum|_ISdigit|_ISxdigit|_ISprint|_ISgraph, 956 /* 56 */ _ISalnum|_ISdigit|_ISxdigit|_ISprint|_ISgraph, _ISalnum|_ISdigit|_ISxdigit|_ISprint|_ISgraph, _ISpunct|_ISprint|_ISgraph, _ISpunct|_ISprint|_ISgraph, _ISprint|_ISgraph, _ISprint|_ISgraph, _ISprint|_ISgraph, _ISpunct|_ISprint|_ISgraph, 957 /* 64 */ _ISpunct|_ISprint|_ISgraph, _ISalnum|_ISupper|_ISalpha|_ISxdigit|_ISprint|_ISgraph, _ISalnum|_ISupper|_ISalpha|_ISxdigit|_ISprint|_ISgraph, _ISalnum|_ISupper|_ISalpha|_ISxdigit|_ISprint|_ISgraph, _ISalnum|_ISupper|_ISalpha|_ISxdigit|_ISprint|_ISgraph, _ISalnum|_ISupper|_ISalpha|_ISxdigit|_ISprint|_ISgraph, _ISalnum|_ISupper|_ISalpha|_ISxdigit|_ISprint|_ISgraph, _ISalnum|_ISupper|_ISalpha|_ISprint|_ISgraph, 958 /* 72 */ _ISalnum|_ISupper|_ISalpha|_ISprint|_ISgraph, _ISalnum|_ISupper|_ISalpha|_ISprint|_ISgraph, _ISalnum|_ISupper|_ISalpha|_ISprint|_ISgraph, _ISalnum|_ISupper|_ISalpha|_ISprint|_ISgraph, _ISalnum|_ISupper|_ISalpha|_ISprint|_ISgraph, _ISalnum|_ISupper|_ISalpha|_ISprint|_ISgraph, _ISalnum|_ISupper|_ISalpha|_ISprint|_ISgraph, _ISalnum|_ISupper|_ISalpha|_ISprint|_ISgraph, 959 /* 80 */ _ISalnum|_ISupper|_ISalpha|_ISprint|_ISgraph, _ISalnum|_ISupper|_ISalpha|_ISprint|_ISgraph, _ISalnum|_ISupper|_ISalpha|_ISprint|_ISgraph, _ISalnum|_ISupper|_ISalpha|_ISprint|_ISgraph, _ISalnum|_ISupper|_ISalpha|_ISprint|_ISgraph, _ISalnum|_ISupper|_ISalpha|_ISprint|_ISgraph, _ISalnum|_ISupper|_ISalpha|_ISprint|_ISgraph, _ISalnum|_ISupper|_ISalpha|_ISprint|_ISgraph, 960 /* 88 */ _ISalnum|_ISupper|_ISalpha|_ISprint|_ISgraph, _ISalnum|_ISupper|_ISalpha|_ISprint|_ISgraph, _ISalnum|_ISupper|_ISalpha|_ISprint|_ISgraph, _ISpunct|_ISprint|_ISgraph, _ISpunct|_ISprint|_ISgraph, _ISpunct|_ISprint|_ISgraph, _ISprint|_ISgraph, _ISpunct|_ISprint|_ISgraph, 961 /* 96 */ _ISprint|_ISgraph, _ISalnum|_ISlower|_ISalpha|_ISxdigit|_ISprint|_ISgraph, _ISalnum|_ISlower|_ISalpha|_ISxdigit|_ISprint|_ISgraph, _ISalnum|_ISlower|_ISalpha|_ISxdigit|_ISprint|_ISgraph, _ISalnum|_ISlower|_ISalpha|_ISxdigit|_ISprint|_ISgraph, _ISalnum|_ISlower|_ISalpha|_ISxdigit|_ISprint|_ISgraph, _ISalnum|_ISlower|_ISalpha|_ISxdigit|_ISprint|_ISgraph, _ISalnum|_ISlower|_ISalpha|_ISprint|_ISgraph, 962 /* 104 */ _ISalnum|_ISlower|_ISalpha|_ISprint|_ISgraph, _ISalnum|_ISlower|_ISalpha|_ISprint|_ISgraph, _ISalnum|_ISlower|_ISalpha|_ISprint|_ISgraph, _ISalnum|_ISlower|_ISalpha|_ISprint|_ISgraph, _ISalnum|_ISlower|_ISalpha|_ISprint|_ISgraph, _ISalnum|_ISlower|_ISalpha|_ISprint|_ISgraph, _ISalnum|_ISlower|_ISalpha|_ISprint|_ISgraph, _ISalnum|_ISlower|_ISalpha|_ISprint|_ISgraph, 963 /* 112 */ _ISalnum|_ISlower|_ISalpha|_ISprint|_ISgraph, _ISalnum|_ISlower|_ISalpha|_ISprint|_ISgraph, _ISalnum|_ISlower|_ISalpha|_ISprint|_ISgraph, _ISalnum|_ISlower|_ISalpha|_ISprint|_ISgraph, _ISalnum|_ISlower|_ISalpha|_ISprint|_ISgraph, _ISalnum|_ISlower|_ISalpha|_ISprint|_ISgraph, _ISalnum|_ISlower|_ISalpha|_ISprint|_ISgraph, _ISalnum|_ISlower|_ISalpha|_ISprint|_ISgraph, 964 /* 120 */ _ISalnum|_ISlower|_ISalpha|_ISprint|_ISgraph, _ISalnum|_ISlower|_ISalpha|_ISprint|_ISgraph, _ISalnum|_ISlower|_ISalpha|_ISprint|_ISgraph, _ISpunct|_ISprint|_ISgraph, _ISprint|_ISgraph, _ISpunct|_ISprint|_ISgraph, _ISprint|_ISgraph, _IScntrl, 965 /* 128 */ 0, 0, 0, 0, 0, 0, 0, 0, 966 /* 136 */ 0, 0, 0, 0, 0, 0, 0, 0, 967 /* 144 */ 0, 0, 0, 0, 0, 0, 0, 0, 968 /* 152 */ 0, 0, 0, 0, 0, 0, 0, 0, 969 /* 160 */ 0, 0, 0, 0, 0, 0, 0, 0, 970 /* 168 */ 0, 0, 0, 0, 0, 0, 0, 0, 971 /* 176 */ 0, 0, 0, 0, 0, 0, 0, 0, 972 /* 184 */ 0, 0, 0, 0, 0, 0, 0, 0, 973 /* 192 */ 0, 0, 0, 0, 0, 0, 0, 0, 974 /* 200 */ 0, 0, 0, 0, 0, 0, 0, 0, 975 /* 208 */ 0, 0, 0, 0, 0, 0, 0, 0, 976 /* 216 */ 0, 0, 0, 0, 0, 0, 0, 0, 977 /* 224 */ 0, 0, 0, 0, 0, 0, 0, 0, 978 /* 232 */ 0, 0, 0, 0, 0, 0, 0, 0, 979 /* 240 */ 0, 0, 0, 0, 0, 0, 0, 0, 980 /* 248 */ 0, 0, 0, 0, 0, 0, 0, 0, 981 }; 982 test_ctype("de_DE.UTF-8", classInfos_utf8, toLowerMap_posix, 983 toUpperMap_posix); 984 } 985 986 987 // #pragma mark - wctype ------------------------------------------------------- 988 989 990 unsigned short 991 determineWideFullClassInfo(int i) 992 { 993 unsigned short classInfo = 0; 994 995 if (iswblank(i)) 996 classInfo |= _ISblank; 997 if (iswcntrl(i)) 998 classInfo |= _IScntrl; 999 if (iswpunct(i)) 1000 classInfo |= _ISpunct; 1001 if (iswalnum(i)) 1002 classInfo |= _ISalnum; 1003 if (iswupper(i)) 1004 classInfo |= _ISupper; 1005 if (iswlower(i)) 1006 classInfo |= _ISlower; 1007 if (iswalpha(i)) 1008 classInfo |= _ISalpha; 1009 if (iswdigit(i)) 1010 classInfo |= _ISdigit; 1011 if (iswxdigit(i)) 1012 classInfo |= _ISxdigit; 1013 if (iswspace(i)) 1014 classInfo |= _ISspace; 1015 if (iswprint(i)) 1016 classInfo |= _ISprint; 1017 if (iswgraph(i)) 1018 classInfo |= _ISgraph; 1019 1020 return classInfo; 1021 } 1022 1023 1024 void 1025 test_wctype(const char* locale, const wchar_t* text, 1026 const unsigned short int wcs[], const unsigned short int classInfos[]) 1027 { 1028 setlocale(LC_CTYPE, locale); 1029 printf("wctype of %s locale\n", locale); 1030 1031 int problemCount = 0; 1032 unsigned short classInfo = determineWideFullClassInfo(WEOF); 1033 if (classInfo != 0) { 1034 printf("\tPROBLEM: classinfo for WEOF = %x (expected 0)\n", classInfo); 1035 problemCount++; 1036 } 1037 wint_t wc = *text; 1038 for (int i = 0; i < 48; wc = *++text, ++i) { 1039 classInfo = determineWideFullClassInfo(wc); 1040 if (wc != wcs[i]) { 1041 printf("\tPROBLEM: wc for char #%d = %x (expected %x)\n", i, wc, 1042 wcs[i]); 1043 problemCount++; 1044 } 1045 1046 if (classInfo != classInfos[i]) { 1047 printf("\tPROBLEM: classinfo for #%d = %x (expected %x)\n", i, 1048 classInfo, classInfos[i]); 1049 problemCount++; 1050 } 1051 } 1052 if (problemCount) 1053 printf("\t%d problem(s) found!\n", problemCount); 1054 else 1055 printf("\tall fine\n"); 1056 } 1057 1058 1059 void 1060 test_wctype() 1061 { 1062 // haiku wide chars are always in UTF32, so nothing should change between 1063 // different locales 1064 1065 const wchar_t* text = L"Hi there, how do you do? (äÜößáéúíó€'¤¹²$%#@) 12"; 1066 1067 const unsigned short int wcs[48] = { 1068 0x48, 0x69, 0x20, 0x74, 0x68, 0x65, 0x72, 0x65, 1069 0x2c, 0x20, 0x68, 0x6f, 0x77, 0x20, 0x64, 0x6f, 1070 0x20, 0x79, 0x6f, 0x75, 0x20, 0x64, 0x6f, 0x3f, 1071 0x20, 0x28, 0xe4, 0xdc, 0xf6, 0xdf, 0xe1, 0xe9, 1072 0xfa, 0xed, 0xf3, 0x20ac, 0x27, 0xa4, 0xb9, 0xb2, 1073 0x24, 0x25, 0x23, 0x40, 0x29, 0x20, 0x31, 0x32 1074 }; 1075 const unsigned short int classInfos[48] = { 1076 _ISprint|_ISgraph|_ISalpha|_ISalnum|_ISupper, 1077 _ISprint|_ISgraph|_ISalpha|_ISalnum|_ISlower, 1078 _ISspace|_ISprint|_ISblank, 1079 _ISprint|_ISgraph|_ISalpha|_ISalnum|_ISlower, 1080 _ISprint|_ISgraph|_ISalpha|_ISalnum|_ISlower, 1081 _ISprint|_ISgraph|_ISalpha|_ISalnum|_ISlower|_ISxdigit, 1082 _ISprint|_ISgraph|_ISalpha|_ISalnum|_ISlower, 1083 _ISprint|_ISgraph|_ISalpha|_ISalnum|_ISlower|_ISxdigit, 1084 _ISprint|_ISgraph|_ISpunct, 1085 _ISspace|_ISprint|_ISblank, 1086 _ISprint|_ISgraph|_ISalpha|_ISalnum|_ISlower, 1087 _ISprint|_ISgraph|_ISalpha|_ISalnum|_ISlower, 1088 _ISprint|_ISgraph|_ISalpha|_ISalnum|_ISlower, 1089 _ISspace|_ISprint|_ISblank, 1090 _ISprint|_ISgraph|_ISalpha|_ISalnum|_ISlower|_ISxdigit, 1091 _ISprint|_ISgraph|_ISalpha|_ISalnum|_ISlower, 1092 _ISspace|_ISprint|_ISblank, 1093 _ISprint|_ISgraph|_ISalpha|_ISalnum|_ISlower, 1094 _ISprint|_ISgraph|_ISalpha|_ISalnum|_ISlower, 1095 _ISprint|_ISgraph|_ISalpha|_ISalnum|_ISlower, 1096 _ISspace|_ISprint|_ISblank, 1097 _ISprint|_ISgraph|_ISalpha|_ISalnum|_ISlower|_ISxdigit, 1098 _ISprint|_ISgraph|_ISalpha|_ISalnum|_ISlower, 1099 _ISprint|_ISgraph|_ISpunct, 1100 _ISspace|_ISprint|_ISblank, 1101 _ISprint|_ISgraph|_ISpunct, 1102 _ISprint|_ISgraph|_ISalpha|_ISalnum|_ISlower, 1103 _ISprint|_ISgraph|_ISalpha|_ISalnum|_ISupper, 1104 _ISprint|_ISgraph|_ISalpha|_ISalnum|_ISlower, 1105 _ISprint|_ISgraph|_ISalpha|_ISalnum|_ISlower, 1106 _ISprint|_ISgraph|_ISalpha|_ISalnum|_ISlower, 1107 _ISprint|_ISgraph|_ISalpha|_ISalnum|_ISlower, 1108 _ISprint|_ISgraph|_ISalpha|_ISalnum|_ISlower, 1109 _ISprint|_ISgraph|_ISalpha|_ISalnum|_ISlower, 1110 _ISprint|_ISgraph|_ISalpha|_ISalnum|_ISlower, 1111 _ISprint|_ISgraph, 1112 _ISprint|_ISgraph|_ISpunct, 1113 _ISprint|_ISgraph, 1114 _ISprint|_ISgraph, 1115 _ISprint|_ISgraph, 1116 _ISprint|_ISgraph, 1117 _ISpunct|_ISprint|_ISgraph, 1118 _ISpunct|_ISprint|_ISgraph, 1119 _ISpunct|_ISprint|_ISgraph, 1120 _ISpunct|_ISprint|_ISgraph, 1121 _ISspace|_ISprint|_ISblank, 1122 _ISprint|_ISgraph|_ISalnum|_ISdigit|_ISxdigit, 1123 _ISprint|_ISgraph|_ISalnum|_ISdigit|_ISxdigit 1124 }; 1125 1126 test_wctype("POSIX", text, wcs, classInfos); 1127 test_wctype("de_DE.ISO8859-1", text, wcs, classInfos); 1128 test_wctype("de_DE.ISO8859-15", text, wcs, classInfos); 1129 test_wctype("de_DE.UTF-8", text, wcs, classInfos); 1130 } 1131 1132 1133 void 1134 test_wctrans(const char* locale, const wchar_t* text, wctrans_t transition, 1135 const wchar_t* expectedResult) 1136 { 1137 setlocale(LC_CTYPE, locale); 1138 printf("towctrans(%s) of %s locale\n", 1139 transition == _ISlower ? "tolower" : "toupper", locale); 1140 1141 int problemCount = 0; 1142 wint_t wc = *text; 1143 for (int i = 0; wc != 0; wc = *++text, ++i) { 1144 errno = 0; 1145 wint_t result = towctrans(wc, transition); 1146 if (result != expectedResult[i] || errno != 0) { 1147 printf("\tPROBLEM: result for char #%d = %x (expected %x), " 1148 "errno = %x (expected %x)\n", 1149 i, result, expectedResult[i], errno, 0); 1150 problemCount++; 1151 } 1152 } 1153 if (problemCount) 1154 printf("\t%d problem(s) found!\n", problemCount); 1155 else 1156 printf("\tall fine\n"); 1157 } 1158 1159 1160 void 1161 test_wctrans() 1162 { 1163 // haiku wide chars are always in UTF32, so nothing should change between 1164 // different locales 1165 1166 setlocale(LC_CTYPE, "POSIX"); 1167 printf("wctrans setup\n"); 1168 1169 int problemCount = 0; 1170 errno = 0; 1171 wctrans_t toU = wctrans("toupper"); 1172 if (errno != 0 || toU != _ISupper) { 1173 printf("\tPROBLEM: wctrans(\"upper\") = %x (expected %x), " 1174 "errno=%x (expected %x)\n", 1175 toU, _ISupper, errno, 0); 1176 problemCount++; 1177 } 1178 errno = 0; 1179 wctrans_t toL = wctrans("tolower"); 1180 if (errno != 0 || toL != _ISlower) { 1181 printf("\tPROBLEM: wctrans(\"lower\") = %x (expected %x), " 1182 "errno=%x (expected %x)\n", 1183 toL, _ISlower, errno, 0); 1184 problemCount++; 1185 } 1186 errno = 0; 1187 wctrans_t invalid1 = wctrans(NULL); 1188 if (errno != EINVAL || invalid1 != 0) { 1189 printf("\tPROBLEM: wctrans(NULL) = %x (expected %x), " 1190 "errno=%x (expected %x)\n", 1191 invalid1, 0, errno, EINVAL); 1192 problemCount++; 1193 } 1194 errno = 0; 1195 wctrans_t invalid2 = wctrans("invalid"); 1196 if (errno != EINVAL || invalid2 != 0) { 1197 printf("\tPROBLEM: wctrans(\"invalid\") = %x (expected %x), " 1198 "errno=%x (expected %x)\n", 1199 invalid2, 0, errno, EINVAL); 1200 problemCount++; 1201 } 1202 if (problemCount) 1203 printf("\t%d problem(s) found!\n", problemCount); 1204 else 1205 printf("\tall fine\n"); 1206 1207 const wchar_t* text = L"Hi there, how do you do? (äÜößáéúíó€'¤¹²$%#@) 12"; 1208 const wchar_t* textU = L"HI THERE, HOW DO YOU DO? (ÄÜÖßÁÉÚÍÓ€'¤¹²$%#@) 12"; 1209 const wchar_t* textL = L"hi there, how do you do? (äüößáéúíó€'¤¹²$%#@) 12"; 1210 1211 test_wctrans("POSIX", text, toU, textU); 1212 test_wctrans("de_DE.ISO8859-1", text, toU, textU); 1213 test_wctrans("de_DE.ISO8859-15", text, toU, textU); 1214 test_wctrans("de_DE.UTF-8", text, toU, textU); 1215 test_wctrans("fr_Fr", text, toU, textU); 1216 1217 test_wctrans("POSIX", text, toL, textL); 1218 test_wctrans("de_DE.ISO8859-1", text, toL, textL); 1219 test_wctrans("de_DE.ISO8859-15", text, toL, textL); 1220 test_wctrans("de_DE.UTF-8", text, toL, textL); 1221 test_wctrans("fr_Fr", text, toL, textL); 1222 } 1223 1224 1225 // #pragma mark - nl_langinfo -------------------------------------------------- 1226 1227 1228 void 1229 test_langinfo(const char* locale, const char* langinfos[]) 1230 { 1231 setlocale(LC_ALL, locale); 1232 printf("langinfo of %s locale\n", locale); 1233 1234 int problemCount = 0; 1235 for (int i = -1; langinfos[i + 1] != NULL; ++i) { 1236 const char* langinfo = nl_langinfo(i); 1237 if (strcmp(langinfo, langinfos[i + 1]) != 0) { 1238 printf("\tPROBLEM: langinfo for #%d = '%s' (expected '%s')\n", i, 1239 langinfo, langinfos[i + 1]); 1240 problemCount++; 1241 } 1242 } 1243 if (problemCount) 1244 printf("\t%d problem(s) found!\n", problemCount); 1245 else 1246 printf("\tall fine\n"); 1247 } 1248 1249 1250 void 1251 test_langinfo() 1252 { 1253 const char* li_posix[] = { 1254 "", // out of bounds 1255 "US-ASCII", 1256 "%a %b %e %H:%M:%S %Y", 1257 "%m/%d/%y", 1258 "%H:%M:%S", 1259 "%I:%M:%S %p", 1260 "AM", 1261 "PM", 1262 1263 "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", 1264 "Saturday", 1265 1266 "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", 1267 1268 "January", "February", "March", "April", "May", "June", 1269 "July", "August", "September", "October", "November", "December", 1270 1271 "Jan", "Feb", "Mar", "Apr", "May", "Jun", 1272 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", 1273 1274 "%EC, %Ey, %EY", 1275 "%Ex", 1276 "%Ec", 1277 "%EX", 1278 "%O", 1279 1280 ".", 1281 "", 1282 1283 "^[yY]", 1284 "^[nN]", 1285 1286 "", 1287 1288 "", // out of bounds 1289 NULL 1290 }; 1291 test_langinfo("POSIX", li_posix); 1292 1293 const char* li_de[] = { 1294 "", // out of bounds 1295 "UTF-8", 1296 "%A, %e. %B %Y %H:%M:%S %Z", 1297 "%d.%m.%Y", 1298 "%H:%M:%S", 1299 "%I:%M:%S %p", 1300 "vorm.", 1301 "nachm.", 1302 1303 "Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", 1304 "Samstag", 1305 1306 "So.", "Mo.", "Di.", "Mi.", "Do.", "Fr.", "Sa.", 1307 1308 "Januar", "Februar", "März", "April", "Mai", "Juni", 1309 "Juli", "August", "September", "Oktober", "November", "Dezember", 1310 1311 "Jan", "Feb", "Mär", "Apr", "Mai", "Jun", 1312 "Jul", "Aug", "Sep", "Okt", "Nov", "Dez", 1313 1314 "%EC, %Ey, %EY", 1315 "%Ex", 1316 "%Ec", 1317 "%EX", 1318 "%O", 1319 1320 ",", 1321 ".", 1322 1323 "^[yY]", 1324 "^[nN]", 1325 1326 "€", 1327 1328 "", // out of bounds 1329 NULL, 1330 }; 1331 test_langinfo("de_DE.UTF-8", li_de); 1332 1333 const char* li_de_iso[] = { 1334 "", // out of bounds 1335 "ISO8859-15", 1336 "%A, %e. %B %Y %H:%M:%S %Z", 1337 "%d.%m.%Y", 1338 "%H:%M:%S", 1339 "%I:%M:%S %p", 1340 "vorm.", 1341 "nachm.", 1342 1343 "Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", 1344 "Samstag", 1345 1346 "So.", "Mo.", "Di.", "Mi.", "Do.", "Fr.", "Sa.", 1347 1348 "Januar", "Februar", "M\xE4rz", "April", "Mai", "Juni", 1349 "Juli", "August", "September", "Oktober", "November", "Dezember", 1350 1351 "Jan", "Feb", "M\xE4r", "Apr", "Mai", "Jun", 1352 "Jul", "Aug", "Sep", "Okt", "Nov", "Dez", 1353 1354 "%EC, %Ey, %EY", 1355 "%Ex", 1356 "%Ec", 1357 "%EX", 1358 "%O", 1359 1360 ",", 1361 ".", 1362 1363 "^[yY]", 1364 "^[nN]", 1365 1366 "\xA4", 1367 1368 "", // out of bounds 1369 NULL 1370 }; 1371 test_langinfo("de_DE.ISO8859-15", li_de_iso); 1372 } 1373 1374 1375 // #pragma mark - collation ---------------------------------------------------- 1376 1377 1378 struct coll_data { 1379 const char* a; 1380 const char* b; 1381 int result; 1382 int err; 1383 }; 1384 1385 1386 static int sign (int a) 1387 { 1388 if (a < 0) 1389 return -1; 1390 if (a > 0) 1391 return 1; 1392 return 0; 1393 } 1394 1395 1396 void 1397 test_coll(bool useStrxfrm, const char* locale, const coll_data coll[]) 1398 { 1399 setlocale(LC_COLLATE, locale); 1400 printf("%s in %s locale\n", useStrxfrm ? "strxfrm" : "strcoll", locale); 1401 1402 int problemCount = 0; 1403 for (unsigned int i = 0; i < sizeof(coll) / sizeof(coll_data); ++i) { 1404 errno = 0; 1405 int result; 1406 char funcCall[100]; 1407 if (useStrxfrm) { 1408 char sortKeyA[100], sortKeyB[100]; 1409 strxfrm(sortKeyA, coll[i].a, 100); 1410 strxfrm(sortKeyB, coll[i].b, 100); 1411 result = sign(strcmp(sortKeyA, sortKeyB)); 1412 sprintf(funcCall, "strcmp(strxfrm(\"%s\"), strxfrm(\"%s\"))", 1413 coll[i].a, coll[i].b); 1414 } else { 1415 result = sign(strcoll(coll[i].a, coll[i].b)); 1416 sprintf(funcCall, "strcoll(\"%s\", \"%s\")", coll[i].a, coll[i].b); 1417 } 1418 1419 if (result != coll[i].result || errno != coll[i].err) { 1420 printf( 1421 "\tPROBLEM: %s = %d (expected %d), errno = %x (expected %x)\n", 1422 funcCall, result, coll[i].result, errno, coll[i].err); 1423 problemCount++; 1424 } 1425 } 1426 if (problemCount) 1427 printf("\t%d problem(s) found!\n", problemCount); 1428 else 1429 printf("\tall fine\n"); 1430 } 1431 1432 1433 void 1434 test_collation() 1435 { 1436 const coll_data coll_posix[] = { 1437 { "", "", 0, 0 }, 1438 { "test", "test", 0, 0 }, 1439 { "tester", "test", 1, 0 }, 1440 { "tEst", "teSt", -1, 0 }, 1441 { "test", "tester", -1, 0 }, 1442 { "tast", "täst", -1, EINVAL }, 1443 { "tæst", "test", 1, EINVAL }, 1444 }; 1445 test_coll(0, "POSIX", coll_posix); 1446 test_coll(1, "POSIX", coll_posix); 1447 1448 const coll_data coll_en[] = { 1449 { "", "", 0, 0 }, 1450 { "test", "test", 0, 0 }, 1451 { "tester", "test", 1, 0 }, 1452 { "tEst", "test", 1, 0 }, 1453 { "test", "tester", -1, 0 }, 1454 { "täst", "täst", 0, 0 }, 1455 { "tast", "täst", -1, 0 }, 1456 { "tbst", "täst", 1, 0 }, 1457 { "tbst", "tæst", 1, 0 }, 1458 { "täst", "tÄst", -1, 0 }, 1459 { "tBst", "tÄst", 1, 0 }, 1460 { "tBst", "täst", 1, 0 }, 1461 { "taest", "tæst", -1, 0 }, 1462 { "tafst", "tæst", 1, 0 }, 1463 { "taa", "täa", -1, 0 }, 1464 { "tab", "täb", -1, 0 }, 1465 { "tad", "täd", -1, 0 }, 1466 { "tae", "täe", -1, 0 }, 1467 { "taf", "täf", -1, 0 }, 1468 { "cote", "coté", -1, 0 }, 1469 { "coté", "côte", -1, 0 }, 1470 { "côte", "côté", -1, 0 }, 1471 }; 1472 test_coll(0, "en_US.UTF-8", coll_en); 1473 test_coll(1, "en_US.UTF-8", coll_en); 1474 1475 const coll_data coll_de[] = { 1476 { "", "", 0, 0 }, 1477 { "test", "test", 0, 0 }, 1478 { "tester", "test", 1, 0 }, 1479 { "tEst", "test", 1, 0 }, 1480 { "test", "tester", -1, 0 }, 1481 { "täst", "täst", 0, 0 }, 1482 { "tast", "täst", -1, 0 }, 1483 { "tbst", "täst", 1, 0 }, 1484 { "tbst", "tæst", 1, 0 }, 1485 { "täst", "tÄst", -1, 0 }, 1486 { "tBst", "tÄst", 1, 0 }, 1487 { "tBst", "täst", 1, 0 }, 1488 { "taest", "tæst", -1, 0 }, 1489 { "tafst", "tæst", 1, 0 }, 1490 { "taa", "tä", 1, 0 }, 1491 { "tab", "tä", 1, 0 }, 1492 { "tad", "tä", 1, 0 }, 1493 { "tae", "tä", 1, 0 }, 1494 { "taf", "tä", 1, 0 }, 1495 { "cote", "coté", -1, 0 }, 1496 { "coté", "côte", -1, 0 }, 1497 { "côte", "côté", -1, 0 }, 1498 }; 1499 test_coll(0, "de_DE.UTF-8", coll_de); 1500 test_coll(1, "de_DE.UTF-8", coll_de); 1501 1502 const coll_data coll_de_phonebook[] = { 1503 { "", "", 0, 0 }, 1504 { "test", "test", 0, 0 }, 1505 { "tester", "test", 1, 0 }, 1506 { "tEst", "test", 1, 0 }, 1507 { "test", "tester", -1, 0 }, 1508 { "täst", "täst", 0, 0 }, 1509 { "tast", "täst", 1, 0 }, 1510 { "tbst", "täst", 1, 0 }, 1511 { "tbst", "tæst", 1, 0 }, 1512 { "täst", "tÄst", -1, 0 }, 1513 { "tBst", "tÄst", 1, 0 }, 1514 { "tBst", "täst", 1, 0 }, 1515 { "taest", "tæst", -1, 0 }, 1516 { "tafst", "tæst", 1, 0 }, 1517 { "taa", "tä", -1, 0 }, 1518 { "tab", "tä", -1, 0 }, 1519 { "tad", "tä", -1, 0 }, 1520 { "tae", "tä", -1, 0 }, 1521 { "taf", "tä", 1, 0 }, 1522 { "cote", "coté", -1, 0 }, 1523 { "coté", "côte", -1, 0 }, 1524 { "côte", "côté", -1, 0 }, 1525 }; 1526 test_coll(0, "de_DE.UTF-8@collation=phonebook", coll_de_phonebook); 1527 test_coll(1, "de_DE.UTF-8@collation=phonebook", coll_de_phonebook); 1528 1529 const coll_data coll_fr[] = { 1530 { "", "", 0, 0 }, 1531 { "test", "test", 0, 0 }, 1532 { "tester", "test", 1, 0 }, 1533 { "tEst", "test", 1, 0 }, 1534 { "test", "tester", -1, 0 }, 1535 { "täst", "täst", 0, 0 }, 1536 { "tast", "täst", -1, 0 }, 1537 { "tbst", "täst", 1, 0 }, 1538 { "tbst", "tæst", 1, 0 }, 1539 { "täst", "tÄst", -1, 0 }, 1540 { "tBst", "tÄst", 1, 0 }, 1541 { "tBst", "täst", 1, 0 }, 1542 { "taest", "tæst", -1, 0 }, 1543 { "tafst", "tæst", 1, 0 }, 1544 { "taa", "tä", 1, 0 }, 1545 { "tab", "tä", 1, 0 }, 1546 { "tad", "tä", 1, 0 }, 1547 { "tae", "tä", 1, 0 }, 1548 { "taf", "tä", 1, 0 }, 1549 { "cote", "coté", -1, 0 }, 1550 { "coté", "côte", 1, 0 }, 1551 { "côte", "côté", -1, 0 }, 1552 }; 1553 test_coll(0, "fr_FR.UTF-8", coll_fr); 1554 test_coll(1, "fr_FR.UTF-8", coll_fr); 1555 } 1556 1557 1558 // #pragma mark - time conversion ---------------------------------------------- 1559 1560 1561 void 1562 test_localtime(const char* tz, time_t nowSecs, const tm& expected) 1563 { 1564 setenv("TZ", tz, 1); 1565 printf("localtime for '%s'\n", tz); 1566 1567 tm now; 1568 tm* result = localtime_r(&nowSecs, &now); 1569 int problemCount = 0; 1570 if (result == NULL) { 1571 printf("\tPROBLEM: localtime(\"%ld\") = NULL\n", nowSecs); 1572 problemCount++; 1573 } 1574 if (now.tm_year != expected.tm_year) { 1575 printf("\tPROBLEM: localtime().tm_year = %d (expected %d)\n", 1576 now.tm_year, expected.tm_year); 1577 problemCount++; 1578 } 1579 if (now.tm_mon != expected.tm_mon) { 1580 printf("\tPROBLEM: localtime().tm_mon = %d (expected %d)\n", 1581 now.tm_mon, expected.tm_mon); 1582 problemCount++; 1583 } 1584 if (now.tm_mday != expected.tm_mday) { 1585 printf("\tPROBLEM: localtime().tm_mday = %d (expected %d)\n", 1586 now.tm_mday, expected.tm_mday); 1587 problemCount++; 1588 } 1589 if (now.tm_hour != expected.tm_hour) { 1590 printf("\tPROBLEM: localtime().tm_hour = %d (expected %d)\n", 1591 now.tm_hour, expected.tm_hour); 1592 problemCount++; 1593 } 1594 if (now.tm_min != expected.tm_min) { 1595 printf("\tPROBLEM: localtime().tm_min = %d (expected %d)\n", 1596 now.tm_min, expected.tm_min); 1597 problemCount++; 1598 } 1599 if (now.tm_sec != expected.tm_sec) { 1600 printf("\tPROBLEM: localtime().tm_sec = %d (expected %d)\n", 1601 now.tm_sec, expected.tm_sec); 1602 problemCount++; 1603 } 1604 if (now.tm_wday != expected.tm_wday) { 1605 printf("\tPROBLEM: localtime().tm_wday = %d (expected %d)\n", 1606 now.tm_wday, expected.tm_wday); 1607 problemCount++; 1608 } 1609 if (now.tm_yday != expected.tm_yday) { 1610 printf("\tPROBLEM: localtime().tm_yday = %d (expected %d)\n", 1611 now.tm_yday, expected.tm_yday); 1612 problemCount++; 1613 } 1614 if (now.tm_isdst != expected.tm_isdst) { 1615 printf("\tPROBLEM: localtime().tm_isdst = %d (expected %d)\n", 1616 now.tm_isdst, expected.tm_isdst); 1617 problemCount++; 1618 } 1619 if (now.tm_gmtoff != expected.tm_gmtoff) { 1620 printf("\tPROBLEM: localtime().tm_gmtoff = %d (expected %d)\n", 1621 now.tm_gmtoff, expected.tm_gmtoff); 1622 problemCount++; 1623 } 1624 if (strcasecmp(now.tm_zone, expected.tm_zone) != 0) { 1625 printf("\tPROBLEM: localtime().tm_zone = '%s' (expected '%s')\n", 1626 now.tm_zone, expected.tm_zone); 1627 problemCount++; 1628 } 1629 if (problemCount) 1630 printf("\t%d problem(s) found!\n", problemCount); 1631 else 1632 printf("\tall fine\n"); 1633 } 1634 1635 1636 void 1637 test_gmtime(const char* tz, time_t nowSecs, const tm& expected) 1638 { 1639 setenv("TZ", tz, 1); 1640 printf("gmtime for '%s'\n", tz); 1641 1642 tm now; 1643 tm* result = gmtime_r(&nowSecs, &now); 1644 int problemCount = 0; 1645 if (result == NULL) { 1646 printf("\tPROBLEM: localtime(\"%ld\") = NULL\n", nowSecs); 1647 problemCount++; 1648 } 1649 if (now.tm_year != expected.tm_year) { 1650 printf("\tPROBLEM: localtime().tm_year = %d (expected %d)\n", 1651 now.tm_year, expected.tm_year); 1652 problemCount++; 1653 } 1654 if (now.tm_mon != expected.tm_mon) { 1655 printf("\tPROBLEM: localtime().tm_mon = %d (expected %d)\n", 1656 now.tm_mon, expected.tm_mon); 1657 problemCount++; 1658 } 1659 if (now.tm_mday != expected.tm_mday) { 1660 printf("\tPROBLEM: localtime().tm_mday = %d (expected %d)\n", 1661 now.tm_mday, expected.tm_mday); 1662 problemCount++; 1663 } 1664 if (now.tm_hour != expected.tm_hour) { 1665 printf("\tPROBLEM: localtime().tm_hour = %d (expected %d)\n", 1666 now.tm_hour, expected.tm_hour); 1667 problemCount++; 1668 } 1669 if (now.tm_min != expected.tm_min) { 1670 printf("\tPROBLEM: localtime().tm_min = %d (expected %d)\n", 1671 now.tm_min, expected.tm_min); 1672 problemCount++; 1673 } 1674 if (now.tm_sec != expected.tm_sec) { 1675 printf("\tPROBLEM: localtime().tm_sec = %d (expected %d)\n", 1676 now.tm_sec, expected.tm_sec); 1677 problemCount++; 1678 } 1679 if (now.tm_wday != expected.tm_wday) { 1680 printf("\tPROBLEM: localtime().tm_wday = %d (expected %d)\n", 1681 now.tm_wday, expected.tm_wday); 1682 problemCount++; 1683 } 1684 if (now.tm_yday != expected.tm_yday) { 1685 printf("\tPROBLEM: localtime().tm_yday = %d (expected %d)\n", 1686 now.tm_yday, expected.tm_yday); 1687 problemCount++; 1688 } 1689 if (now.tm_isdst != expected.tm_isdst) { 1690 printf("\tPROBLEM: localtime().tm_isdst = %d (expected %d)\n", 1691 now.tm_isdst, expected.tm_isdst); 1692 problemCount++; 1693 } 1694 if (now.tm_gmtoff != expected.tm_gmtoff) { 1695 printf("\tPROBLEM: localtime().tm_gmtoff = %d (expected %d)\n", 1696 now.tm_gmtoff, expected.tm_gmtoff); 1697 problemCount++; 1698 } 1699 if (strcasecmp(now.tm_zone, expected.tm_zone) != 0) { 1700 printf("\tPROBLEM: localtime().tm_zone = '%s' (expected '%s')\n", 1701 now.tm_zone, expected.tm_zone); 1702 problemCount++; 1703 } 1704 if (problemCount) 1705 printf("\t%d problem(s) found!\n", problemCount); 1706 else 1707 printf("\tall fine\n"); 1708 } 1709 1710 1711 void 1712 test_mktime(const char* tz, tm& tm, time_t expected, int expectedWeekDay, 1713 int expectedYearDay) 1714 { 1715 setenv("TZ", tz, 1); 1716 printf("mktime for '%s'\n", tz); 1717 1718 time_t result = mktime(&tm); 1719 int problemCount = 0; 1720 if (result != expected) { 1721 printf("\tPROBLEM: mktime() = %ld (expected %ld)\n", result, expected); 1722 problemCount++; 1723 } 1724 if (tm.tm_wday != expectedWeekDay) { 1725 printf("\tPROBLEM: mktime().tm_wday = %d (expected %d)\n", 1726 tm.tm_wday, expectedWeekDay); 1727 problemCount++; 1728 } 1729 if (tm.tm_yday != expectedYearDay) { 1730 printf("\tPROBLEM: mktime().tm_yday = %d (expected %d)\n", 1731 tm.tm_yday, expectedYearDay); 1732 problemCount++; 1733 } 1734 if (problemCount) 1735 printf("\t%d problem(s) found!\n", problemCount); 1736 else 1737 printf("\tall fine\n"); 1738 } 1739 1740 1741 void 1742 test_timeconversions() 1743 { 1744 setlocale(LC_ALL, ""); 1745 { 1746 time_t testTime = 1279391169; // Sat Jul 17 18:26:09 GMT 2010 1747 tm gtm = { 1748 9, 26, 18, 17, 6, 110, 6, 197, 0, 0, (char*)"GMT" 1749 }; 1750 test_localtime("GMT", testTime, gtm); 1751 test_gmtime("GMT", testTime, gtm); 1752 gtm.tm_wday = -1; 1753 gtm.tm_yday = -1; 1754 test_mktime("GMT", gtm, testTime, 6, 197); 1755 tm btm = { 1756 9, 26, 20, 17, 6, 110, 6, 197, 1, 2 * 3600, (char*)"CEST" 1757 }; 1758 test_localtime("Europe/Berlin", testTime, btm); 1759 test_gmtime("Europe/Berlin", testTime, gtm); 1760 btm.tm_wday = -1; 1761 btm.tm_yday = -1; 1762 test_mktime("Europe/Berlin", btm, testTime, 6, 197); 1763 tm latm = { 1764 9, 26, 11, 17, 6, 110, 6, 197, 1, -7 * 3600, (char*)"PDT" 1765 }; 1766 test_localtime("America/Los_Angeles", testTime, latm); 1767 test_gmtime("America/Los_Angeles", testTime, gtm); 1768 latm.tm_wday = -1; 1769 latm.tm_yday = -1; 1770 test_mktime("America/Los_Angeles", latm, testTime, 6, 197); 1771 tm ttm = { 1772 9, 26, 3, 18, 6, 110, 0, 198, 0, 9 * 3600, (char*)"JST" 1773 }; 1774 test_localtime("Asia/Tokyo", testTime, ttm); 1775 test_gmtime("Asia/Tokyo", testTime, gtm); 1776 ttm.tm_wday = -1; 1777 ttm.tm_yday = -1; 1778 test_mktime("Asia/Tokyo", ttm, testTime, 0, 198); 1779 } 1780 1781 { 1782 time_t testTime = 1268159169; // Tue Mar 9 18:26:09 GMT 2010 1783 tm gtm = { 1784 9, 26, 18, 9, 2, 110, 2, 67, 0, 0, (char*)"GMT" 1785 }; 1786 test_localtime("GMT", testTime, gtm); 1787 test_gmtime("GMT", testTime, gtm); 1788 gtm.tm_wday = -1; 1789 gtm.tm_yday = -1; 1790 test_mktime("GMT", gtm, testTime, 2, 67); 1791 tm btm = { 1792 9, 26, 19, 9, 2, 110, 2, 67, 0, 3600, (char*)"CET" 1793 }; 1794 test_localtime("Europe/Berlin", testTime, btm); 1795 test_gmtime("Europe/Berlin", testTime, gtm); 1796 btm.tm_wday = -1; 1797 btm.tm_yday = -1; 1798 test_mktime("Europe/Berlin", btm, testTime, 2, 67); 1799 tm latm = { 1800 9, 26, 10, 9, 2, 110, 2, 67, 0, -8 * 3600, (char*)"PST" 1801 }; 1802 test_localtime("America/Los_Angeles", testTime, latm); 1803 test_gmtime("America/Los_Angeles", testTime, gtm); 1804 latm.tm_wday = -1; 1805 latm.tm_yday = -1; 1806 test_mktime("America/Los_Angeles", latm, testTime, 2, 67); 1807 tm ttm = { 1808 9, 26, 3, 10, 2, 110, 3, 68, 0, 9 * 3600, (char*)"JST" 1809 }; 1810 test_localtime("Asia/Tokyo", testTime, ttm); 1811 test_gmtime("Asia/Tokyo", testTime, gtm); 1812 ttm.tm_wday = -1; 1813 ttm.tm_yday = -1; 1814 test_mktime("Asia/Tokyo", ttm, testTime, 3, 68); 1815 } 1816 1817 { 1818 time_t testTime = 0; // Thu Jan 1 00:00:00 GMT 1970 1819 tm gtm = { 1820 0, 0, 0, 1, 0, 70, 4, 0, 0, 0, (char*)"GMT" 1821 }; 1822 test_localtime("GMT", testTime, gtm); 1823 test_gmtime("GMT", testTime, gtm); 1824 gtm.tm_wday = -1; 1825 gtm.tm_yday = -1; 1826 test_mktime("GMT", gtm, testTime, 4, 0); 1827 tm btm = { 1828 0, 0, 1, 1, 0, 70, 4, 0, 0, 1 * 3600, (char*)"CET" 1829 }; 1830 test_localtime("Europe/Berlin", testTime, btm); 1831 test_gmtime("Europe/Berlin", testTime, gtm); 1832 btm.tm_wday = -1; 1833 btm.tm_yday = -1; 1834 test_mktime("Europe/Berlin", btm, testTime, 4, 0); 1835 tm latm = { 1836 0, 0, 16, 31, 11, 69, 3, 364, 0, -8 * 3600, (char*)"PST" 1837 }; 1838 test_localtime("America/Los_Angeles", testTime, latm); 1839 test_gmtime("America/Los_Angeles", testTime, gtm); 1840 latm.tm_wday = -1; 1841 latm.tm_yday = -1; 1842 test_mktime("America/Los_Angeles", latm, testTime, 3, 364); 1843 tm ttm = { 1844 0, 0, 9, 1, 0, 70, 4, 0, 0, 9 * 3600, (char*)"JST" 1845 }; 1846 test_localtime("Asia/Tokyo", testTime, ttm); 1847 test_gmtime("Asia/Tokyo", testTime, gtm); 1848 ttm.tm_wday = -1; 1849 ttm.tm_yday = -1; 1850 test_mktime("Asia/Tokyo", ttm, testTime, 4, 0); 1851 } 1852 } 1853 1854 1855 // #pragma mark - printf ------------------------------------------------------- 1856 1857 1858 struct sprintf_data { 1859 const char* format; 1860 double value; 1861 const char* result; 1862 }; 1863 1864 1865 void 1866 test_sprintf(const char* locale, const sprintf_data data[]) 1867 { 1868 setlocale(LC_ALL, locale); 1869 printf("sprintf for '%s'\n", locale); 1870 1871 int problemCount = 0; 1872 for(int i = 0; data[i].format != NULL; ++i) { 1873 char buf[100]; 1874 if (strchr(data[i].format, 'd') != NULL) 1875 sprintf(buf, data[i].format, (int)data[i].value); 1876 else if (strchr(data[i].format, 'f') != NULL) 1877 sprintf(buf, data[i].format, data[i].value); 1878 if (strcmp(buf, data[i].result) != 0) { 1879 printf("\tPROBLEM: sprintf(\"%s\") = \"%s\" (expected \"%s\")\n", 1880 data[i].format, buf, data[i].result); 1881 problemCount++; 1882 } 1883 } 1884 if (problemCount) 1885 printf("\t%d problem(s) found!\n", problemCount); 1886 else 1887 printf("\tall fine\n"); 1888 } 1889 1890 1891 void 1892 test_sprintf() 1893 { 1894 const sprintf_data sprintf_posix[] = { 1895 { "%d", 123, "123" }, 1896 { "%d", -123, "-123" }, 1897 { "%d", 123456, "123456" }, 1898 { "%'d", 123456, "123456" }, 1899 { "%f", 123, "123.000000" }, 1900 { "%f", -123, "-123.000000" }, 1901 { "%.2f", 123456.789, "123456.79" }, 1902 { "%'.2f", 123456.789, "123456.79" }, 1903 { NULL, 0.0, NULL } 1904 }; 1905 test_sprintf("POSIX", sprintf_posix); 1906 1907 const sprintf_data sprintf_de[] = { 1908 { "%d", 123, "123" }, 1909 { "%d", -123, "-123" }, 1910 { "%d", 123456, "123456" }, 1911 { "%'d", 123456, "123.456" }, 1912 { "%f", 123, "123,000000" }, 1913 { "%f", -123, "-123,000000" }, 1914 { "%.2f", 123456.789, "123456,79" }, 1915 { "%'.2f", 123456.789, "123.456,79" }, 1916 { NULL, 0.0, NULL } 1917 }; 1918 test_sprintf("de_DE.UTF-8", sprintf_de); 1919 1920 const sprintf_data sprintf_gu[] = { 1921 { "%d", 123, "123" }, 1922 { "%d", -123, "-123" }, 1923 { "%d", 123456, "123456" }, 1924 { "%'d", 123456, "123,456" }, 1925 { "%f", 123, "123.000000" }, 1926 { "%f", -123, "-123.000000" }, 1927 { "%.2f", 123456.789, "123456.79" }, 1928 { "%'.2f", 123456.789, "1,23,456.79" }, 1929 { NULL, 0.0, NULL } 1930 }; 1931 test_sprintf("gu_IN", sprintf_gu); 1932 1933 const sprintf_data sprintf_nb[] = { 1934 { "%d", 123, "123" }, 1935 { "%d", -123, "-123" }, 1936 { "%d", 123456, "123456" }, 1937 { "%'d", 123456, "123 456" }, 1938 { "%f", 123, "123,000000" }, 1939 { "%f", -123, "-123,000000" }, 1940 { "%.2f", 123456.789, "123456,79" }, 1941 { "%'.2f", 123456.789, "123 456,79" }, 1942 { NULL, 0.0, NULL } 1943 }; 1944 test_sprintf("nb_NO", sprintf_nb); 1945 } 1946 1947 1948 // #pragma mark - main --------------------------------------------------------- 1949 1950 1951 /* 1952 * Test several different aspects of the POSIX locale and the functions 1953 * influenced by it. 1954 */ 1955 int 1956 main(void) 1957 { 1958 test_setlocale(); 1959 test_localeconv(); 1960 test_strftime(); 1961 test_ctype(); 1962 test_wctype(); 1963 test_wctrans(); 1964 test_langinfo(); 1965 test_collation(); 1966 test_timeconversions(); 1967 test_sprintf(); 1968 1969 return 0; 1970 } 1971