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 // #pragma mark - wctrans ------------------------------------------------------ 1134 1135 1136 void 1137 test_wctrans(const char* locale, const wchar_t* text, wctrans_t transition, 1138 const wchar_t* expectedResult) 1139 { 1140 setlocale(LC_CTYPE, locale); 1141 printf("towctrans(%s) of %s locale\n", 1142 transition == _ISlower ? "tolower" : "toupper", locale); 1143 1144 int problemCount = 0; 1145 wint_t wc = *text; 1146 for (int i = 0; wc != 0; wc = *++text, ++i) { 1147 errno = 0; 1148 wint_t result = towctrans(wc, transition); 1149 if (result != expectedResult[i] || errno != 0) { 1150 printf("\tPROBLEM: result for char #%d = %x (expected %x), " 1151 "errno = %x (expected %x)\n", 1152 i, result, expectedResult[i], errno, 0); 1153 problemCount++; 1154 } 1155 } 1156 if (problemCount) 1157 printf("\t%d problem(s) found!\n", problemCount); 1158 else 1159 printf("\tall fine\n"); 1160 } 1161 1162 1163 void 1164 test_wctrans() 1165 { 1166 // haiku wide chars are always in UTF32, so nothing should change between 1167 // different locales 1168 1169 setlocale(LC_CTYPE, "POSIX"); 1170 printf("wctrans setup\n"); 1171 1172 int problemCount = 0; 1173 errno = 0; 1174 wctrans_t toU = wctrans("toupper"); 1175 if (errno != 0 || toU != _ISupper) { 1176 printf("\tPROBLEM: wctrans(\"upper\") = %x (expected %x), " 1177 "errno=%x (expected %x)\n", 1178 toU, _ISupper, errno, 0); 1179 problemCount++; 1180 } 1181 errno = 0; 1182 wctrans_t toL = wctrans("tolower"); 1183 if (errno != 0 || toL != _ISlower) { 1184 printf("\tPROBLEM: wctrans(\"lower\") = %x (expected %x), " 1185 "errno=%x (expected %x)\n", 1186 toL, _ISlower, errno, 0); 1187 problemCount++; 1188 } 1189 errno = 0; 1190 wctrans_t invalid1 = wctrans(NULL); 1191 if (errno != EINVAL || invalid1 != 0) { 1192 printf("\tPROBLEM: wctrans(NULL) = %x (expected %x), " 1193 "errno=%x (expected %x)\n", 1194 invalid1, 0, errno, EINVAL); 1195 problemCount++; 1196 } 1197 errno = 0; 1198 wctrans_t invalid2 = wctrans("invalid"); 1199 if (errno != EINVAL || invalid2 != 0) { 1200 printf("\tPROBLEM: wctrans(\"invalid\") = %x (expected %x), " 1201 "errno=%x (expected %x)\n", 1202 invalid2, 0, errno, EINVAL); 1203 problemCount++; 1204 } 1205 if (problemCount) 1206 printf("\t%d problem(s) found!\n", problemCount); 1207 else 1208 printf("\tall fine\n"); 1209 1210 const wchar_t* text = L"Hi there, how do you do? (äÜößáéúíó€'¤¹²$%#@) 12"; 1211 const wchar_t* textU = L"HI THERE, HOW DO YOU DO? (ÄÜÖßÁÉÚÍÓ€'¤¹²$%#@) 12"; 1212 const wchar_t* textL = L"hi there, how do you do? (äüößáéúíó€'¤¹²$%#@) 12"; 1213 1214 test_wctrans("POSIX", text, toU, textU); 1215 test_wctrans("de_DE.ISO8859-1", text, toU, textU); 1216 test_wctrans("de_DE.ISO8859-15", text, toU, textU); 1217 test_wctrans("de_DE.UTF-8", text, toU, textU); 1218 test_wctrans("fr_Fr", text, toU, textU); 1219 1220 test_wctrans("POSIX", text, toL, textL); 1221 test_wctrans("de_DE.ISO8859-1", text, toL, textL); 1222 test_wctrans("de_DE.ISO8859-15", text, toL, textL); 1223 test_wctrans("de_DE.UTF-8", text, toL, textL); 1224 test_wctrans("fr_Fr", text, toL, textL); 1225 } 1226 1227 1228 // #pragma mark - wcwidth ------------------------------------------------------ 1229 1230 1231 void 1232 test_wcwidth() 1233 { 1234 setlocale(LC_ALL, "fr_FR.UTF-8"); 1235 printf("wcwidth()\n"); 1236 1237 /* many of the following tests have been copied from gnulib */ 1238 1239 int problemCount = 0; 1240 int result = 0; 1241 1242 /* Test width of ASCII characters. */ 1243 for (wchar_t wc = 0x20; wc < 0x7F; wc++) { 1244 result = wcwidth(wc); 1245 if (result != 1) { 1246 printf("\tPROBLEM: wcwidth(%x)=%x (expected %x)\n", wc, result, 1); 1247 problemCount++; 1248 } 1249 } 1250 1251 struct { 1252 wchar_t wc; 1253 int result; 1254 } data[] = { 1255 { 0x0, 0 }, 1256 { 0x1, -1 }, 1257 { 0x1F, -1 }, 1258 { 0x80, -1 }, 1259 { 0x9F, -1 }, 1260 { 0xA0, 1 }, 1261 { 0x0301, 0 }, 1262 { 0x05B0, 0 }, 1263 { 0x200E, 0 }, 1264 { 0x2060, 0 }, 1265 { 0xE0001, 0 }, 1266 { 0xE0044, 0 }, 1267 { 0x200B, 0 }, 1268 { 0xFEFF, 0 }, 1269 { 0x3000, 2 }, 1270 { 0xB250, 2 }, 1271 { 0xFF1A, 2 }, 1272 { 0x20369, 2 }, 1273 { 0x2F876, 2 }, 1274 { 0x0, 0 }, 1275 }; 1276 for (int i = 0; data[i].wc != 0 || i == 0; i++) { 1277 result = wcwidth(data[i].wc); 1278 if (result != data[i].result) { 1279 printf("\tPROBLEM: wcwidth(%x)=%x (expected %x)\n", data[i].wc, 1280 result, data[i].result); 1281 problemCount++; 1282 } 1283 } 1284 1285 if (problemCount) 1286 printf("\t%d problem(s) found!\n", problemCount); 1287 else 1288 printf("\tall fine\n"); 1289 } 1290 1291 1292 // #pragma mark - nl_langinfo -------------------------------------------------- 1293 1294 1295 void 1296 test_langinfo(const char* locale, const char* langinfos[]) 1297 { 1298 setlocale(LC_ALL, locale); 1299 printf("langinfo of %s locale\n", locale); 1300 1301 int problemCount = 0; 1302 for (int i = -1; langinfos[i + 1] != NULL; ++i) { 1303 const char* langinfo = nl_langinfo(i); 1304 if (strcmp(langinfo, langinfos[i + 1]) != 0) { 1305 printf("\tPROBLEM: langinfo for #%d = '%s' (expected '%s')\n", i, 1306 langinfo, langinfos[i + 1]); 1307 problemCount++; 1308 } 1309 } 1310 if (problemCount) 1311 printf("\t%d problem(s) found!\n", problemCount); 1312 else 1313 printf("\tall fine\n"); 1314 } 1315 1316 1317 void 1318 test_langinfo() 1319 { 1320 const char* li_posix[] = { 1321 "", // out of bounds 1322 "US-ASCII", 1323 "%a %b %e %H:%M:%S %Y", 1324 "%m/%d/%y", 1325 "%H:%M:%S", 1326 "%I:%M:%S %p", 1327 "AM", 1328 "PM", 1329 1330 "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", 1331 "Saturday", 1332 1333 "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", 1334 1335 "January", "February", "March", "April", "May", "June", 1336 "July", "August", "September", "October", "November", "December", 1337 1338 "Jan", "Feb", "Mar", "Apr", "May", "Jun", 1339 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", 1340 1341 "%EC, %Ey, %EY", 1342 "%Ex", 1343 "%Ec", 1344 "%EX", 1345 "%O", 1346 1347 ".", 1348 "", 1349 1350 "^[yY]", 1351 "^[nN]", 1352 1353 "", 1354 1355 "", // out of bounds 1356 NULL 1357 }; 1358 test_langinfo("POSIX", li_posix); 1359 1360 const char* li_de[] = { 1361 "", // out of bounds 1362 "UTF-8", 1363 "%A, %e. %B %Y %H:%M:%S %Z", 1364 "%d.%m.%Y", 1365 "%H:%M:%S", 1366 "%I:%M:%S %p", 1367 "vorm.", 1368 "nachm.", 1369 1370 "Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", 1371 "Samstag", 1372 1373 "So.", "Mo.", "Di.", "Mi.", "Do.", "Fr.", "Sa.", 1374 1375 "Januar", "Februar", "März", "April", "Mai", "Juni", 1376 "Juli", "August", "September", "Oktober", "November", "Dezember", 1377 1378 "Jan", "Feb", "Mär", "Apr", "Mai", "Jun", 1379 "Jul", "Aug", "Sep", "Okt", "Nov", "Dez", 1380 1381 "%EC, %Ey, %EY", 1382 "%Ex", 1383 "%Ec", 1384 "%EX", 1385 "%O", 1386 1387 ",", 1388 ".", 1389 1390 "^[yY]", 1391 "^[nN]", 1392 1393 "€", 1394 1395 "", // out of bounds 1396 NULL, 1397 }; 1398 test_langinfo("de_DE.UTF-8", li_de); 1399 1400 const char* li_de_iso[] = { 1401 "", // out of bounds 1402 "ISO8859-15", 1403 "%A, %e. %B %Y %H:%M:%S %Z", 1404 "%d.%m.%Y", 1405 "%H:%M:%S", 1406 "%I:%M:%S %p", 1407 "vorm.", 1408 "nachm.", 1409 1410 "Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", 1411 "Samstag", 1412 1413 "So.", "Mo.", "Di.", "Mi.", "Do.", "Fr.", "Sa.", 1414 1415 "Januar", "Februar", "M\xE4rz", "April", "Mai", "Juni", 1416 "Juli", "August", "September", "Oktober", "November", "Dezember", 1417 1418 "Jan", "Feb", "M\xE4r", "Apr", "Mai", "Jun", 1419 "Jul", "Aug", "Sep", "Okt", "Nov", "Dez", 1420 1421 "%EC, %Ey, %EY", 1422 "%Ex", 1423 "%Ec", 1424 "%EX", 1425 "%O", 1426 1427 ",", 1428 ".", 1429 1430 "^[yY]", 1431 "^[nN]", 1432 1433 "\xA4", 1434 1435 "", // out of bounds 1436 NULL 1437 }; 1438 test_langinfo("de_DE.ISO8859-15", li_de_iso); 1439 } 1440 1441 1442 // #pragma mark - collation ---------------------------------------------------- 1443 1444 1445 struct coll_data { 1446 const char* a; 1447 const char* b; 1448 int result; 1449 int err; 1450 }; 1451 1452 1453 static int sign (int a) 1454 { 1455 if (a < 0) 1456 return -1; 1457 if (a > 0) 1458 return 1; 1459 return 0; 1460 } 1461 1462 1463 void 1464 test_coll(bool useStrxfrm, const char* locale, const coll_data coll[]) 1465 { 1466 setlocale(LC_COLLATE, locale); 1467 printf("%s in %s locale\n", useStrxfrm ? "strxfrm" : "strcoll", locale); 1468 1469 int problemCount = 0; 1470 for (unsigned int i = 0; i < sizeof(coll) / sizeof(coll_data); ++i) { 1471 errno = 0; 1472 int result; 1473 char funcCall[100]; 1474 if (useStrxfrm) { 1475 char sortKeyA[100], sortKeyB[100]; 1476 strxfrm(sortKeyA, coll[i].a, 100); 1477 strxfrm(sortKeyB, coll[i].b, 100); 1478 result = sign(strcmp(sortKeyA, sortKeyB)); 1479 sprintf(funcCall, "strcmp(strxfrm(\"%s\"), strxfrm(\"%s\"))", 1480 coll[i].a, coll[i].b); 1481 } else { 1482 result = sign(strcoll(coll[i].a, coll[i].b)); 1483 sprintf(funcCall, "strcoll(\"%s\", \"%s\")", coll[i].a, coll[i].b); 1484 } 1485 1486 if (result != coll[i].result || errno != coll[i].err) { 1487 printf( 1488 "\tPROBLEM: %s = %d (expected %d), errno = %x (expected %x)\n", 1489 funcCall, result, coll[i].result, errno, coll[i].err); 1490 problemCount++; 1491 } 1492 } 1493 if (problemCount) 1494 printf("\t%d problem(s) found!\n", problemCount); 1495 else 1496 printf("\tall fine\n"); 1497 } 1498 1499 1500 void 1501 test_collation() 1502 { 1503 const coll_data coll_posix[] = { 1504 { "", "", 0, 0 }, 1505 { "test", "test", 0, 0 }, 1506 { "tester", "test", 1, 0 }, 1507 { "tEst", "teSt", -1, 0 }, 1508 { "test", "tester", -1, 0 }, 1509 { "tast", "täst", -1, EINVAL }, 1510 { "tæst", "test", 1, EINVAL }, 1511 }; 1512 test_coll(0, "POSIX", coll_posix); 1513 test_coll(1, "POSIX", coll_posix); 1514 1515 const coll_data coll_en[] = { 1516 { "", "", 0, 0 }, 1517 { "test", "test", 0, 0 }, 1518 { "tester", "test", 1, 0 }, 1519 { "tEst", "test", 1, 0 }, 1520 { "test", "tester", -1, 0 }, 1521 { "täst", "täst", 0, 0 }, 1522 { "tast", "täst", -1, 0 }, 1523 { "tbst", "täst", 1, 0 }, 1524 { "tbst", "tæst", 1, 0 }, 1525 { "täst", "tÄst", -1, 0 }, 1526 { "tBst", "tÄst", 1, 0 }, 1527 { "tBst", "täst", 1, 0 }, 1528 { "taest", "tæst", -1, 0 }, 1529 { "tafst", "tæst", 1, 0 }, 1530 { "taa", "täa", -1, 0 }, 1531 { "tab", "täb", -1, 0 }, 1532 { "tad", "täd", -1, 0 }, 1533 { "tae", "täe", -1, 0 }, 1534 { "taf", "täf", -1, 0 }, 1535 { "cote", "coté", -1, 0 }, 1536 { "coté", "côte", -1, 0 }, 1537 { "côte", "côté", -1, 0 }, 1538 }; 1539 test_coll(0, "en_US.UTF-8", coll_en); 1540 test_coll(1, "en_US.UTF-8", coll_en); 1541 1542 const coll_data coll_de[] = { 1543 { "", "", 0, 0 }, 1544 { "test", "test", 0, 0 }, 1545 { "tester", "test", 1, 0 }, 1546 { "tEst", "test", 1, 0 }, 1547 { "test", "tester", -1, 0 }, 1548 { "täst", "täst", 0, 0 }, 1549 { "tast", "täst", -1, 0 }, 1550 { "tbst", "täst", 1, 0 }, 1551 { "tbst", "tæst", 1, 0 }, 1552 { "täst", "tÄst", -1, 0 }, 1553 { "tBst", "tÄst", 1, 0 }, 1554 { "tBst", "täst", 1, 0 }, 1555 { "taest", "tæst", -1, 0 }, 1556 { "tafst", "tæst", 1, 0 }, 1557 { "taa", "tä", 1, 0 }, 1558 { "tab", "tä", 1, 0 }, 1559 { "tad", "tä", 1, 0 }, 1560 { "tae", "tä", 1, 0 }, 1561 { "taf", "tä", 1, 0 }, 1562 { "cote", "coté", -1, 0 }, 1563 { "coté", "côte", -1, 0 }, 1564 { "côte", "côté", -1, 0 }, 1565 }; 1566 test_coll(0, "de_DE.UTF-8", coll_de); 1567 test_coll(1, "de_DE.UTF-8", coll_de); 1568 1569 const coll_data coll_de_phonebook[] = { 1570 { "", "", 0, 0 }, 1571 { "test", "test", 0, 0 }, 1572 { "tester", "test", 1, 0 }, 1573 { "tEst", "test", 1, 0 }, 1574 { "test", "tester", -1, 0 }, 1575 { "täst", "täst", 0, 0 }, 1576 { "tast", "täst", 1, 0 }, 1577 { "tbst", "täst", 1, 0 }, 1578 { "tbst", "tæst", 1, 0 }, 1579 { "täst", "tÄst", -1, 0 }, 1580 { "tBst", "tÄst", 1, 0 }, 1581 { "tBst", "täst", 1, 0 }, 1582 { "taest", "tæst", -1, 0 }, 1583 { "tafst", "tæst", 1, 0 }, 1584 { "taa", "tä", -1, 0 }, 1585 { "tab", "tä", -1, 0 }, 1586 { "tad", "tä", -1, 0 }, 1587 { "tae", "tä", -1, 0 }, 1588 { "taf", "tä", 1, 0 }, 1589 { "cote", "coté", -1, 0 }, 1590 { "coté", "côte", -1, 0 }, 1591 { "côte", "côté", -1, 0 }, 1592 }; 1593 test_coll(0, "de_DE.UTF-8@collation=phonebook", coll_de_phonebook); 1594 test_coll(1, "de_DE.UTF-8@collation=phonebook", coll_de_phonebook); 1595 1596 const coll_data coll_fr[] = { 1597 { "", "", 0, 0 }, 1598 { "test", "test", 0, 0 }, 1599 { "tester", "test", 1, 0 }, 1600 { "tEst", "test", 1, 0 }, 1601 { "test", "tester", -1, 0 }, 1602 { "täst", "täst", 0, 0 }, 1603 { "tast", "täst", -1, 0 }, 1604 { "tbst", "täst", 1, 0 }, 1605 { "tbst", "tæst", 1, 0 }, 1606 { "täst", "tÄst", -1, 0 }, 1607 { "tBst", "tÄst", 1, 0 }, 1608 { "tBst", "täst", 1, 0 }, 1609 { "taest", "tæst", -1, 0 }, 1610 { "tafst", "tæst", 1, 0 }, 1611 { "taa", "tä", 1, 0 }, 1612 { "tab", "tä", 1, 0 }, 1613 { "tad", "tä", 1, 0 }, 1614 { "tae", "tä", 1, 0 }, 1615 { "taf", "tä", 1, 0 }, 1616 { "cote", "coté", -1, 0 }, 1617 { "coté", "côte", 1, 0 }, 1618 { "côte", "côté", -1, 0 }, 1619 }; 1620 test_coll(0, "fr_FR.UTF-8", coll_fr); 1621 test_coll(1, "fr_FR.UTF-8", coll_fr); 1622 } 1623 1624 1625 // #pragma mark - time conversion ---------------------------------------------- 1626 1627 1628 void 1629 test_localtime(const char* tz, time_t nowSecs, const tm& expected) 1630 { 1631 setenv("TZ", tz, 1); 1632 printf("localtime for '%s'\n", tz); 1633 1634 tm now; 1635 tm* result = localtime_r(&nowSecs, &now); 1636 int problemCount = 0; 1637 if (result == NULL) { 1638 printf("\tPROBLEM: localtime(\"%ld\") = NULL\n", nowSecs); 1639 problemCount++; 1640 } 1641 if (now.tm_year != expected.tm_year) { 1642 printf("\tPROBLEM: localtime().tm_year = %d (expected %d)\n", 1643 now.tm_year, expected.tm_year); 1644 problemCount++; 1645 } 1646 if (now.tm_mon != expected.tm_mon) { 1647 printf("\tPROBLEM: localtime().tm_mon = %d (expected %d)\n", 1648 now.tm_mon, expected.tm_mon); 1649 problemCount++; 1650 } 1651 if (now.tm_mday != expected.tm_mday) { 1652 printf("\tPROBLEM: localtime().tm_mday = %d (expected %d)\n", 1653 now.tm_mday, expected.tm_mday); 1654 problemCount++; 1655 } 1656 if (now.tm_hour != expected.tm_hour) { 1657 printf("\tPROBLEM: localtime().tm_hour = %d (expected %d)\n", 1658 now.tm_hour, expected.tm_hour); 1659 problemCount++; 1660 } 1661 if (now.tm_min != expected.tm_min) { 1662 printf("\tPROBLEM: localtime().tm_min = %d (expected %d)\n", 1663 now.tm_min, expected.tm_min); 1664 problemCount++; 1665 } 1666 if (now.tm_sec != expected.tm_sec) { 1667 printf("\tPROBLEM: localtime().tm_sec = %d (expected %d)\n", 1668 now.tm_sec, expected.tm_sec); 1669 problemCount++; 1670 } 1671 if (now.tm_wday != expected.tm_wday) { 1672 printf("\tPROBLEM: localtime().tm_wday = %d (expected %d)\n", 1673 now.tm_wday, expected.tm_wday); 1674 problemCount++; 1675 } 1676 if (now.tm_yday != expected.tm_yday) { 1677 printf("\tPROBLEM: localtime().tm_yday = %d (expected %d)\n", 1678 now.tm_yday, expected.tm_yday); 1679 problemCount++; 1680 } 1681 if (now.tm_isdst != expected.tm_isdst) { 1682 printf("\tPROBLEM: localtime().tm_isdst = %d (expected %d)\n", 1683 now.tm_isdst, expected.tm_isdst); 1684 problemCount++; 1685 } 1686 if (now.tm_gmtoff != expected.tm_gmtoff) { 1687 printf("\tPROBLEM: localtime().tm_gmtoff = %d (expected %d)\n", 1688 now.tm_gmtoff, expected.tm_gmtoff); 1689 problemCount++; 1690 } 1691 if (strcasecmp(now.tm_zone, expected.tm_zone) != 0) { 1692 printf("\tPROBLEM: localtime().tm_zone = '%s' (expected '%s')\n", 1693 now.tm_zone, expected.tm_zone); 1694 problemCount++; 1695 } 1696 if (problemCount) 1697 printf("\t%d problem(s) found!\n", problemCount); 1698 else 1699 printf("\tall fine\n"); 1700 } 1701 1702 1703 void 1704 test_gmtime(const char* tz, time_t nowSecs, const tm& expected) 1705 { 1706 setenv("TZ", tz, 1); 1707 printf("gmtime for '%s'\n", tz); 1708 1709 tm now; 1710 tm* result = gmtime_r(&nowSecs, &now); 1711 int problemCount = 0; 1712 if (result == NULL) { 1713 printf("\tPROBLEM: localtime(\"%ld\") = NULL\n", nowSecs); 1714 problemCount++; 1715 } 1716 if (now.tm_year != expected.tm_year) { 1717 printf("\tPROBLEM: localtime().tm_year = %d (expected %d)\n", 1718 now.tm_year, expected.tm_year); 1719 problemCount++; 1720 } 1721 if (now.tm_mon != expected.tm_mon) { 1722 printf("\tPROBLEM: localtime().tm_mon = %d (expected %d)\n", 1723 now.tm_mon, expected.tm_mon); 1724 problemCount++; 1725 } 1726 if (now.tm_mday != expected.tm_mday) { 1727 printf("\tPROBLEM: localtime().tm_mday = %d (expected %d)\n", 1728 now.tm_mday, expected.tm_mday); 1729 problemCount++; 1730 } 1731 if (now.tm_hour != expected.tm_hour) { 1732 printf("\tPROBLEM: localtime().tm_hour = %d (expected %d)\n", 1733 now.tm_hour, expected.tm_hour); 1734 problemCount++; 1735 } 1736 if (now.tm_min != expected.tm_min) { 1737 printf("\tPROBLEM: localtime().tm_min = %d (expected %d)\n", 1738 now.tm_min, expected.tm_min); 1739 problemCount++; 1740 } 1741 if (now.tm_sec != expected.tm_sec) { 1742 printf("\tPROBLEM: localtime().tm_sec = %d (expected %d)\n", 1743 now.tm_sec, expected.tm_sec); 1744 problemCount++; 1745 } 1746 if (now.tm_wday != expected.tm_wday) { 1747 printf("\tPROBLEM: localtime().tm_wday = %d (expected %d)\n", 1748 now.tm_wday, expected.tm_wday); 1749 problemCount++; 1750 } 1751 if (now.tm_yday != expected.tm_yday) { 1752 printf("\tPROBLEM: localtime().tm_yday = %d (expected %d)\n", 1753 now.tm_yday, expected.tm_yday); 1754 problemCount++; 1755 } 1756 if (now.tm_isdst != expected.tm_isdst) { 1757 printf("\tPROBLEM: localtime().tm_isdst = %d (expected %d)\n", 1758 now.tm_isdst, expected.tm_isdst); 1759 problemCount++; 1760 } 1761 if (now.tm_gmtoff != expected.tm_gmtoff) { 1762 printf("\tPROBLEM: localtime().tm_gmtoff = %d (expected %d)\n", 1763 now.tm_gmtoff, expected.tm_gmtoff); 1764 problemCount++; 1765 } 1766 if (strcasecmp(now.tm_zone, expected.tm_zone) != 0) { 1767 printf("\tPROBLEM: localtime().tm_zone = '%s' (expected '%s')\n", 1768 now.tm_zone, expected.tm_zone); 1769 problemCount++; 1770 } 1771 if (problemCount) 1772 printf("\t%d problem(s) found!\n", problemCount); 1773 else 1774 printf("\tall fine\n"); 1775 } 1776 1777 1778 void 1779 test_mktime(const char* tz, tm& tm, time_t expected, int expectedWeekDay, 1780 int expectedYearDay) 1781 { 1782 setenv("TZ", tz, 1); 1783 printf("mktime for '%s'\n", tz); 1784 1785 time_t result = mktime(&tm); 1786 int problemCount = 0; 1787 if (result != expected) { 1788 printf("\tPROBLEM: mktime() = %ld (expected %ld)\n", result, expected); 1789 problemCount++; 1790 } 1791 if (tm.tm_wday != expectedWeekDay) { 1792 printf("\tPROBLEM: mktime().tm_wday = %d (expected %d)\n", 1793 tm.tm_wday, expectedWeekDay); 1794 problemCount++; 1795 } 1796 if (tm.tm_yday != expectedYearDay) { 1797 printf("\tPROBLEM: mktime().tm_yday = %d (expected %d)\n", 1798 tm.tm_yday, expectedYearDay); 1799 problemCount++; 1800 } 1801 if (problemCount) 1802 printf("\t%d problem(s) found!\n", problemCount); 1803 else 1804 printf("\tall fine\n"); 1805 } 1806 1807 1808 void 1809 test_timeconversions() 1810 { 1811 setlocale(LC_ALL, ""); 1812 { 1813 time_t testTime = 1279391169; // Sat Jul 17 18:26:09 GMT 2010 1814 tm gtm = { 1815 9, 26, 18, 17, 6, 110, 6, 197, 0, 0, (char*)"GMT" 1816 }; 1817 test_localtime("GMT", testTime, gtm); 1818 test_gmtime("GMT", testTime, gtm); 1819 gtm.tm_wday = -1; 1820 gtm.tm_yday = -1; 1821 test_mktime("GMT", gtm, testTime, 6, 197); 1822 1823 tm gtmplus2 = { 1824 9, 26, 16, 17, 6, 110, 6, 197, 0, -2 * 3600, (char*)"GMT+2" 1825 }; 1826 test_localtime("GMT+2", testTime, gtmplus2); 1827 test_gmtime("GMT+2", testTime, gtm); 1828 gtmplus2.tm_wday = -1; 1829 gtmplus2.tm_yday = -1; 1830 test_mktime("GMT+2", gtmplus2, testTime, 6, 197); 1831 1832 tm gtmminus2 = { 1833 9, 26, 20, 17, 6, 110, 6, 197, 0, 2 * 3600, (char*)"GMT-2" 1834 }; 1835 test_localtime("GMT-2", testTime, gtmminus2); 1836 test_gmtime("GMT-2", testTime, gtm); 1837 gtmminus2.tm_wday = -1; 1838 gtmminus2.tm_yday = -1; 1839 test_mktime("GMT-2", gtmminus2, testTime, 6, 197); 1840 1841 tm btm = { 1842 9, 26, 20, 17, 6, 110, 6, 197, 1, 2 * 3600, (char*)"CEST" 1843 }; 1844 test_localtime(":Europe/Berlin", testTime, btm); 1845 test_gmtime(":Europe/Berlin", testTime, gtm); 1846 btm.tm_wday = -1; 1847 btm.tm_yday = -1; 1848 test_mktime(":Europe/Berlin", btm, testTime, 6, 197); 1849 1850 tm ctm = { 1851 9, 26, 20, 17, 6, 110, 6, 197, 1, 2 * 3600, (char*)"CEST" 1852 }; 1853 test_localtime("CET", testTime, ctm); 1854 test_gmtime("CET", testTime, gtm); 1855 ctm.tm_wday = -1; 1856 ctm.tm_yday = -1; 1857 test_mktime("CET", ctm, testTime, 6, 197); 1858 1859 tm latm = { 1860 9, 26, 11, 17, 6, 110, 6, 197, 1, -7 * 3600, (char*)"PDT" 1861 }; 1862 test_localtime(":America/Los_Angeles", testTime, latm); 1863 test_gmtime(":America/Los_Angeles", testTime, gtm); 1864 latm.tm_wday = -1; 1865 latm.tm_yday = -1; 1866 test_mktime(":America/Los_Angeles", latm, testTime, 6, 197); 1867 1868 tm ttm = { 1869 9, 26, 3, 18, 6, 110, 0, 198, 0, 9 * 3600, (char*)"JST" 1870 }; 1871 test_localtime(":Asia/Tokyo", testTime, ttm); 1872 test_gmtime(":Asia/Tokyo", testTime, gtm); 1873 ttm.tm_wday = -1; 1874 ttm.tm_yday = -1; 1875 test_mktime(":Asia/Tokyo", ttm, testTime, 0, 198); 1876 } 1877 1878 { 1879 time_t testTime = 1268159169; // Tue Mar 9 18:26:09 GMT 2010 1880 tm gtm = { 1881 9, 26, 18, 9, 2, 110, 2, 67, 0, 0, (char*)"GMT" 1882 }; 1883 test_localtime("GMT", testTime, gtm); 1884 test_gmtime("GMT", testTime, gtm); 1885 gtm.tm_wday = -1; 1886 gtm.tm_yday = -1; 1887 test_mktime("GMT", gtm, testTime, 2, 67); 1888 1889 tm btm = { 1890 9, 26, 19, 9, 2, 110, 2, 67, 0, 3600, (char*)"CET" 1891 }; 1892 test_localtime(":Europe/Berlin", testTime, btm); 1893 test_gmtime(":Europe/Berlin", testTime, gtm); 1894 btm.tm_wday = -1; 1895 btm.tm_yday = -1; 1896 test_mktime(":Europe/Berlin", btm, testTime, 2, 67); 1897 1898 tm ctm = { 1899 9, 26, 19, 9, 2, 110, 2, 67, 0, 3600, (char*)"CET" 1900 }; 1901 test_localtime("CET", testTime, ctm); 1902 test_gmtime("CET", testTime, gtm); 1903 ctm.tm_wday = -1; 1904 ctm.tm_yday = -1; 1905 test_mktime("CET", ctm, testTime, 2, 67); 1906 1907 tm latm = { 1908 9, 26, 10, 9, 2, 110, 2, 67, 0, -8 * 3600, (char*)"PST" 1909 }; 1910 test_localtime(":America/Los_Angeles", testTime, latm); 1911 test_gmtime(":America/Los_Angeles", testTime, gtm); 1912 latm.tm_wday = -1; 1913 latm.tm_yday = -1; 1914 test_mktime(":America/Los_Angeles", latm, testTime, 2, 67); 1915 1916 tm ttm = { 1917 9, 26, 3, 10, 2, 110, 3, 68, 0, 9 * 3600, (char*)"JST" 1918 }; 1919 test_localtime(":Asia/Tokyo", testTime, ttm); 1920 test_gmtime(":Asia/Tokyo", testTime, gtm); 1921 ttm.tm_wday = -1; 1922 ttm.tm_yday = -1; 1923 test_mktime(":Asia/Tokyo", ttm, testTime, 3, 68); 1924 } 1925 1926 { 1927 time_t testTime = 0; // Thu Jan 1 00:00:00 GMT 1970 1928 tm gtm = { 1929 0, 0, 0, 1, 0, 70, 4, 0, 0, 0, (char*)"GMT" 1930 }; 1931 test_localtime("GMT", testTime, gtm); 1932 test_gmtime("GMT", testTime, gtm); 1933 gtm.tm_wday = -1; 1934 gtm.tm_yday = -1; 1935 test_mktime("GMT", gtm, testTime, 4, 0); 1936 1937 tm btm = { 1938 0, 0, 1, 1, 0, 70, 4, 0, 0, 1 * 3600, (char*)"CET" 1939 }; 1940 test_localtime(":Europe/Berlin", testTime, btm); 1941 test_gmtime(":Europe/Berlin", testTime, gtm); 1942 btm.tm_wday = -1; 1943 btm.tm_yday = -1; 1944 test_mktime(":Europe/Berlin", btm, testTime, 4, 0); 1945 1946 tm ctm = { 1947 0, 0, 1, 1, 0, 70, 4, 0, 0, 1 * 3600, (char*)"CET" 1948 }; 1949 test_localtime("CET", testTime, ctm); 1950 test_gmtime("CET", testTime, gtm); 1951 ctm.tm_wday = -1; 1952 ctm.tm_yday = -1; 1953 test_mktime("CET", ctm, testTime, 4, 0); 1954 1955 tm latm = { 1956 0, 0, 16, 31, 11, 69, 3, 364, 0, -8 * 3600, (char*)"PST" 1957 }; 1958 test_localtime(":America/Los_Angeles", testTime, latm); 1959 test_gmtime(":America/Los_Angeles", testTime, gtm); 1960 latm.tm_wday = -1; 1961 latm.tm_yday = -1; 1962 test_mktime(":America/Los_Angeles", latm, testTime, 3, 364); 1963 1964 tm ttm = { 1965 0, 0, 9, 1, 0, 70, 4, 0, 0, 9 * 3600, (char*)"JST" 1966 }; 1967 test_localtime(":Asia/Tokyo", testTime, ttm); 1968 test_gmtime(":Asia/Tokyo", testTime, gtm); 1969 ttm.tm_wday = -1; 1970 ttm.tm_yday = -1; 1971 test_mktime(":Asia/Tokyo", ttm, testTime, 4, 0); 1972 } 1973 } 1974 1975 1976 // #pragma mark - printf ------------------------------------------------------- 1977 1978 1979 struct sprintf_data { 1980 const char* format; 1981 double value; 1982 const char* result; 1983 }; 1984 1985 1986 void 1987 test_sprintf(const char* locale, const sprintf_data data[]) 1988 { 1989 setlocale(LC_ALL, locale); 1990 printf("sprintf for '%s'\n", locale); 1991 1992 int problemCount = 0; 1993 for(int i = 0; data[i].format != NULL; ++i) { 1994 char buf[100]; 1995 if (strchr(data[i].format, 'd') != NULL) 1996 sprintf(buf, data[i].format, (int)data[i].value); 1997 else if (strchr(data[i].format, 'f') != NULL) 1998 sprintf(buf, data[i].format, data[i].value); 1999 if (strcmp(buf, data[i].result) != 0) { 2000 printf("\tPROBLEM: sprintf(\"%s\") = \"%s\" (expected \"%s\")\n", 2001 data[i].format, buf, data[i].result); 2002 problemCount++; 2003 } 2004 } 2005 if (problemCount) 2006 printf("\t%d problem(s) found!\n", problemCount); 2007 else 2008 printf("\tall fine\n"); 2009 } 2010 2011 2012 void 2013 test_sprintf() 2014 { 2015 const sprintf_data sprintf_posix[] = { 2016 { "%d", 123, "123" }, 2017 { "%d", -123, "-123" }, 2018 { "%d", 123456, "123456" }, 2019 { "%'d", 123456, "123456" }, 2020 { "%f", 123, "123.000000" }, 2021 { "%f", -123, "-123.000000" }, 2022 { "%.2f", 123456.789, "123456.79" }, 2023 { "%'.2f", 123456.789, "123456.79" }, 2024 { NULL, 0.0, NULL } 2025 }; 2026 test_sprintf("POSIX", sprintf_posix); 2027 2028 const sprintf_data sprintf_de[] = { 2029 { "%d", 123, "123" }, 2030 { "%d", -123, "-123" }, 2031 { "%d", 123456, "123456" }, 2032 { "%'d", 123456, "123.456" }, 2033 { "%f", 123, "123,000000" }, 2034 { "%f", -123, "-123,000000" }, 2035 { "%.2f", 123456.789, "123456,79" }, 2036 { "%'.2f", 123456.789, "123.456,79" }, 2037 { NULL, 0.0, NULL } 2038 }; 2039 test_sprintf("de_DE.UTF-8", sprintf_de); 2040 2041 const sprintf_data sprintf_gu[] = { 2042 { "%d", 123, "123" }, 2043 { "%d", -123, "-123" }, 2044 { "%d", 123456, "123456" }, 2045 { "%'d", 123456, "123,456" }, 2046 { "%f", 123, "123.000000" }, 2047 { "%f", -123, "-123.000000" }, 2048 { "%.2f", 123456.789, "123456.79" }, 2049 { "%'.2f", 123456.789, "1,23,456.79" }, 2050 { NULL, 0.0, NULL } 2051 }; 2052 test_sprintf("gu_IN", sprintf_gu); 2053 2054 const sprintf_data sprintf_nb[] = { 2055 { "%d", 123, "123" }, 2056 { "%d", -123, "-123" }, 2057 { "%d", 123456, "123456" }, 2058 { "%'d", 123456, "123 456" }, 2059 { "%f", 123, "123,000000" }, 2060 { "%f", -123, "-123,000000" }, 2061 { "%.2f", 123456.789, "123456,79" }, 2062 { "%'.2f", 123456.789, "123 456,79" }, 2063 { NULL, 0.0, NULL } 2064 }; 2065 test_sprintf("nb_NO", sprintf_nb); 2066 } 2067 2068 2069 // #pragma mark - main --------------------------------------------------------- 2070 2071 2072 /* 2073 * Test several different aspects of the POSIX locale and the functions 2074 * influenced by it. 2075 */ 2076 int 2077 main(void) 2078 { 2079 test_setlocale(); 2080 test_localeconv(); 2081 test_strftime(); 2082 test_ctype(); 2083 test_wctype(); 2084 test_wctrans(); 2085 test_wcwidth(); 2086 test_langinfo(); 2087 test_collation(); 2088 test_timeconversions(); 2089 test_sprintf(); 2090 2091 return 0; 2092 } 2093