1/******************************************************************** 2 * COPYRIGHT: 3 * Copyright (c) 1997-2010, International Business Machines Corporation and 4 * others. All Rights Reserved. 5 ********************************************************************/ 6/******************************************************************************** 7* 8* File CNORMTST.C 9* 10* Modification History: 11* Name Description 12* Madhu Katragadda Ported for C API 13* synwee added test for quick check 14* synwee added test for checkFCD 15*********************************************************************************/ 16/*tests for u_normalization*/ 17#include "unicode/utypes.h" 18#include "unicode/unorm.h" 19#include "cintltst.h" 20 21#if UCONFIG_NO_NORMALIZATION 22 23void addNormTest(TestNode** root) { 24 /* no normalization - nothing to do */ 25} 26 27#else 28 29#include <stdlib.h> 30#include <time.h> 31#include "unicode/uchar.h" 32#include "unicode/ustring.h" 33#include "unicode/unorm.h" 34#include "cnormtst.h" 35 36#define LENGTHOF(array) (int32_t)(sizeof(array)/sizeof ((array)[0])) 37 38static void 39TestAPI(void); 40 41static void 42TestNormCoverage(void); 43 44static void 45TestConcatenate(void); 46 47static void 48TestNextPrevious(void); 49 50static void TestIsNormalized(void); 51 52static void 53TestFCNFKCClosure(void); 54 55static void 56TestQuickCheckPerCP(void); 57 58static void 59TestComposition(void); 60 61const static char* canonTests[][3] = { 62 /* Input*/ /*Decomposed*/ /*Composed*/ 63 { "cat", "cat", "cat" }, 64 { "\\u00e0ardvark", "a\\u0300ardvark", "\\u00e0ardvark", }, 65 66 { "\\u1e0a", "D\\u0307", "\\u1e0a" }, /* D-dot_above*/ 67 { "D\\u0307", "D\\u0307", "\\u1e0a" }, /* D dot_above*/ 68 69 { "\\u1e0c\\u0307", "D\\u0323\\u0307", "\\u1e0c\\u0307" }, /* D-dot_below dot_above*/ 70 { "\\u1e0a\\u0323", "D\\u0323\\u0307", "\\u1e0c\\u0307" }, /* D-dot_above dot_below */ 71 { "D\\u0307\\u0323", "D\\u0323\\u0307", "\\u1e0c\\u0307" }, /* D dot_below dot_above */ 72 73 { "\\u1e10\\u0307\\u0323", "D\\u0327\\u0323\\u0307", "\\u1e10\\u0323\\u0307" }, /*D dot_below cedilla dot_above*/ 74 { "D\\u0307\\u0328\\u0323", "D\\u0328\\u0323\\u0307", "\\u1e0c\\u0328\\u0307" }, /* D dot_above ogonek dot_below*/ 75 76 { "\\u1E14", "E\\u0304\\u0300", "\\u1E14" }, /* E-macron-grave*/ 77 { "\\u0112\\u0300", "E\\u0304\\u0300", "\\u1E14" }, /* E-macron + grave*/ 78 { "\\u00c8\\u0304", "E\\u0300\\u0304", "\\u00c8\\u0304" }, /* E-grave + macron*/ 79 80 { "\\u212b", "A\\u030a", "\\u00c5" }, /* angstrom_sign*/ 81 { "\\u00c5", "A\\u030a", "\\u00c5" }, /* A-ring*/ 82 83 { "\\u00C4ffin", "A\\u0308ffin", "\\u00C4ffin" }, 84 { "\\u00C4\\uFB03n", "A\\u0308\\uFB03n", "\\u00C4\\uFB03n" }, 85 86 { "Henry IV", "Henry IV", "Henry IV" }, 87 { "Henry \\u2163", "Henry \\u2163", "Henry \\u2163" }, 88 89 { "\\u30AC", "\\u30AB\\u3099", "\\u30AC" }, /* ga (Katakana)*/ 90 { "\\u30AB\\u3099", "\\u30AB\\u3099", "\\u30AC" }, /*ka + ten*/ 91 { "\\uFF76\\uFF9E", "\\uFF76\\uFF9E", "\\uFF76\\uFF9E" }, /* hw_ka + hw_ten*/ 92 { "\\u30AB\\uFF9E", "\\u30AB\\uFF9E", "\\u30AB\\uFF9E" }, /* ka + hw_ten*/ 93 { "\\uFF76\\u3099", "\\uFF76\\u3099", "\\uFF76\\u3099" }, /* hw_ka + ten*/ 94 { "A\\u0300\\u0316", "A\\u0316\\u0300", "\\u00C0\\u0316" } /* hw_ka + ten*/ 95}; 96 97const static char* compatTests[][3] = { 98 /* Input*/ /*Decomposed */ /*Composed*/ 99 { "cat", "cat", "cat" }, 100 101 { "\\uFB4f", "\\u05D0\\u05DC", "\\u05D0\\u05DC" }, /* Alef-Lamed vs. Alef, Lamed*/ 102 103 { "\\u00C4ffin", "A\\u0308ffin", "\\u00C4ffin" }, 104 { "\\u00C4\\uFB03n", "A\\u0308ffin", "\\u00C4ffin" }, /* ffi ligature -> f + f + i*/ 105 106 { "Henry IV", "Henry IV", "Henry IV" }, 107 { "Henry \\u2163", "Henry IV", "Henry IV" }, 108 109 { "\\u30AC", "\\u30AB\\u3099", "\\u30AC" }, /* ga (Katakana)*/ 110 { "\\u30AB\\u3099", "\\u30AB\\u3099", "\\u30AC" }, /*ka + ten*/ 111 112 { "\\uFF76\\u3099", "\\u30AB\\u3099", "\\u30AC" }, /* hw_ka + ten*/ 113 114 /*These two are broken in Unicode 2.1.2 but fixed in 2.1.5 and later*/ 115 { "\\uFF76\\uFF9E", "\\u30AB\\u3099", "\\u30AC" }, /* hw_ka + hw_ten*/ 116 { "\\u30AB\\uFF9E", "\\u30AB\\u3099", "\\u30AC" } /* ka + hw_ten*/ 117 118}; 119 120void addNormTest(TestNode** root); 121 122void addNormTest(TestNode** root) 123{ 124 addTest(root, &TestAPI, "tsnorm/cnormtst/TestAPI"); 125 addTest(root, &TestDecomp, "tsnorm/cnormtst/TestDecomp"); 126 addTest(root, &TestCompatDecomp, "tsnorm/cnormtst/TestCompatDecomp"); 127 addTest(root, &TestCanonDecompCompose, "tsnorm/cnormtst/TestCanonDecompCompose"); 128 addTest(root, &TestCompatDecompCompose, "tsnorm/cnormtst/CompatDecompCompose"); 129 addTest(root, &TestNull, "tsnorm/cnormtst/TestNull"); 130 addTest(root, &TestQuickCheck, "tsnorm/cnormtst/TestQuickCheck"); 131 addTest(root, &TestQuickCheckPerCP, "tsnorm/cnormtst/TestQuickCheckPerCP"); 132 addTest(root, &TestIsNormalized, "tsnorm/cnormtst/TestIsNormalized"); 133 addTest(root, &TestCheckFCD, "tsnorm/cnormtst/TestCheckFCD"); 134 addTest(root, &TestNormCoverage, "tsnorm/cnormtst/TestNormCoverage"); 135 addTest(root, &TestConcatenate, "tsnorm/cnormtst/TestConcatenate"); 136 addTest(root, &TestNextPrevious, "tsnorm/cnormtst/TestNextPrevious"); 137 addTest(root, &TestFCNFKCClosure, "tsnorm/cnormtst/TestFCNFKCClosure"); 138 addTest(root, &TestComposition, "tsnorm/cnormtst/TestComposition"); 139} 140 141void TestDecomp() 142{ 143 UErrorCode status = U_ZERO_ERROR; 144 int32_t x, neededLen, resLen; 145 UChar *source=NULL, *result=NULL; 146 status = U_ZERO_ERROR; 147 resLen=0; 148 log_verbose("Testing unorm_normalize with Decomp canonical\n"); 149 for(x=0; x < LENGTHOF(canonTests); x++) 150 { 151 source=CharsToUChars(canonTests[x][0]); 152 neededLen= unorm_normalize(source, u_strlen(source), UNORM_NFD, 0, NULL, 0, &status); 153 if(status==U_BUFFER_OVERFLOW_ERROR) 154 { 155 status=U_ZERO_ERROR; 156 resLen=neededLen+1; 157 result=(UChar*)malloc(sizeof(UChar*) * resLen); 158 unorm_normalize(source, u_strlen(source), UNORM_NFD, 0, result, resLen, &status); 159 } 160 if(U_FAILURE(status)){ 161 log_data_err("ERROR in unorm_normalize at %s: %s - (Are you missing data?)\n", austrdup(source), myErrorName(status) ); 162 } else { 163 assertEqual(result, canonTests[x][1], x); 164 } 165 free(result); 166 free(source); 167 } 168} 169 170void TestCompatDecomp() 171{ 172 UErrorCode status = U_ZERO_ERROR; 173 int32_t x, neededLen, resLen; 174 UChar *source=NULL, *result=NULL; 175 status = U_ZERO_ERROR; 176 resLen=0; 177 log_verbose("Testing unorm_normalize with Decomp compat\n"); 178 for(x=0; x < LENGTHOF(compatTests); x++) 179 { 180 source=CharsToUChars(compatTests[x][0]); 181 neededLen= unorm_normalize(source, u_strlen(source), UNORM_NFKD, 0, NULL, 0, &status); 182 if(status==U_BUFFER_OVERFLOW_ERROR) 183 { 184 status=U_ZERO_ERROR; 185 resLen=neededLen+1; 186 result=(UChar*)malloc(sizeof(UChar*) * resLen); 187 unorm_normalize(source, u_strlen(source), UNORM_NFKD, 0, result, resLen, &status); 188 } 189 if(U_FAILURE(status)){ 190 log_data_err("ERROR in unorm_normalize at %s: %s - (Are you missing data?)\n", austrdup(source), myErrorName(status) ); 191 } else { 192 assertEqual(result, compatTests[x][1], x); 193 } 194 free(result); 195 free(source); 196 } 197} 198 199void TestCanonDecompCompose() 200{ 201 UErrorCode status = U_ZERO_ERROR; 202 int32_t x, neededLen, resLen; 203 UChar *source=NULL, *result=NULL; 204 status = U_ZERO_ERROR; 205 resLen=0; 206 log_verbose("Testing unorm_normalize with Decomp can compose compat\n"); 207 for(x=0; x < LENGTHOF(canonTests); x++) 208 { 209 source=CharsToUChars(canonTests[x][0]); 210 neededLen= unorm_normalize(source, u_strlen(source), UNORM_NFC, 0, NULL, 0, &status); 211 if(status==U_BUFFER_OVERFLOW_ERROR) 212 { 213 status=U_ZERO_ERROR; 214 resLen=neededLen+1; 215 result=(UChar*)malloc(sizeof(UChar*) * resLen); 216 unorm_normalize(source, u_strlen(source), UNORM_NFC, 0, result, resLen, &status); 217 } 218 if(U_FAILURE(status)){ 219 log_data_err("ERROR in unorm_normalize at %s: %s - (Are you missing data?)\n", austrdup(source),myErrorName(status) ); 220 } else { 221 assertEqual(result, canonTests[x][2], x); 222 } 223 free(result); 224 free(source); 225 } 226} 227 228void TestCompatDecompCompose() 229{ 230 UErrorCode status = U_ZERO_ERROR; 231 int32_t x, neededLen, resLen; 232 UChar *source=NULL, *result=NULL; 233 status = U_ZERO_ERROR; 234 resLen=0; 235 log_verbose("Testing unorm_normalize with compat decomp compose can\n"); 236 for(x=0; x < LENGTHOF(compatTests); x++) 237 { 238 source=CharsToUChars(compatTests[x][0]); 239 neededLen= unorm_normalize(source, u_strlen(source), UNORM_NFKC, 0, NULL, 0, &status); 240 if(status==U_BUFFER_OVERFLOW_ERROR) 241 { 242 status=U_ZERO_ERROR; 243 resLen=neededLen+1; 244 result=(UChar*)malloc(sizeof(UChar*) * resLen); 245 unorm_normalize(source, u_strlen(source), UNORM_NFKC, 0, result, resLen, &status); 246 } 247 if(U_FAILURE(status)){ 248 log_data_err("ERROR in unorm_normalize at %s: %s - (Are you missing data?)\n", austrdup(source), myErrorName(status) ); 249 } else { 250 assertEqual(result, compatTests[x][2], x); 251 } 252 free(result); 253 free(source); 254 } 255} 256 257 258/* 259static void assertEqual(const UChar* result, const UChar* expected, int32_t index) 260{ 261 if(u_strcmp(result, expected)!=0){ 262 log_err("ERROR in decomposition at index = %d. EXPECTED: %s , GOT: %s\n", index, austrdup(expected), 263 austrdup(result) ); 264 } 265} 266*/ 267 268static void assertEqual(const UChar* result, const char* expected, int32_t index) 269{ 270 UChar *expectedUni = CharsToUChars(expected); 271 if(u_strcmp(result, expectedUni)!=0){ 272 log_err("ERROR in decomposition at index = %d. EXPECTED: %s , GOT: %s\n", index, expected, 273 austrdup(result) ); 274 } 275 free(expectedUni); 276} 277 278static void TestNull_check(UChar *src, int32_t srcLen, 279 UChar *exp, int32_t expLen, 280 UNormalizationMode mode, 281 const char *name) 282{ 283 UErrorCode status = U_ZERO_ERROR; 284 int32_t len, i; 285 286 UChar result[50]; 287 288 289 status = U_ZERO_ERROR; 290 291 for(i=0;i<50;i++) 292 { 293 result[i] = 0xFFFD; 294 } 295 296 len = unorm_normalize(src, srcLen, mode, 0, result, 50, &status); 297 298 if(U_FAILURE(status)) { 299 log_data_err("unorm_normalize(%s) with 0x0000 failed: %s - (Are you missing data?)\n", name, u_errorName(status)); 300 } else if (len != expLen) { 301 log_err("unorm_normalize(%s) with 0x0000 failed: Expected len %d, got %d\n", name, expLen, len); 302 } 303 304 { 305 for(i=0;i<len;i++){ 306 if(exp[i] != result[i]) { 307 log_err("unorm_normalize(%s): @%d, expected \\u%04X got \\u%04X\n", 308 name, 309 i, 310 exp[i], 311 result[i]); 312 return; 313 } 314 log_verbose(" %d: \\u%04X\n", i, result[i]); 315 } 316 } 317 318 log_verbose("unorm_normalize(%s) with 0x0000: OK\n", name); 319} 320 321void TestNull() 322{ 323 324 UChar source_comp[] = { 0x0061, 0x0000, 0x0044, 0x0307 }; 325 int32_t source_comp_len = 4; 326 UChar expect_comp[] = { 0x0061, 0x0000, 0x1e0a }; 327 int32_t expect_comp_len = 3; 328 329 UChar source_dcmp[] = { 0x1e0A, 0x0000, 0x0929 }; 330 int32_t source_dcmp_len = 3; 331 UChar expect_dcmp[] = { 0x0044, 0x0307, 0x0000, 0x0928, 0x093C }; 332 int32_t expect_dcmp_len = 5; 333 334 TestNull_check(source_comp, 335 source_comp_len, 336 expect_comp, 337 expect_comp_len, 338 UNORM_NFC, 339 "UNORM_NFC"); 340 341 TestNull_check(source_dcmp, 342 source_dcmp_len, 343 expect_dcmp, 344 expect_dcmp_len, 345 UNORM_NFD, 346 "UNORM_NFD"); 347 348 TestNull_check(source_comp, 349 source_comp_len, 350 expect_comp, 351 expect_comp_len, 352 UNORM_NFKC, 353 "UNORM_NFKC"); 354 355 356} 357 358static void TestQuickCheckResultNO() 359{ 360 const UChar CPNFD[] = {0x00C5, 0x0407, 0x1E00, 0x1F57, 0x220C, 361 0x30AE, 0xAC00, 0xD7A3, 0xFB36, 0xFB4E}; 362 const UChar CPNFC[] = {0x0340, 0x0F93, 0x1F77, 0x1FBB, 0x1FEB, 363 0x2000, 0x232A, 0xF900, 0xFA1E, 0xFB4E}; 364 const UChar CPNFKD[] = {0x00A0, 0x02E4, 0x1FDB, 0x24EA, 0x32FE, 365 0xAC00, 0xFB4E, 0xFA10, 0xFF3F, 0xFA2D}; 366 const UChar CPNFKC[] = {0x00A0, 0x017F, 0x2000, 0x24EA, 0x32FE, 367 0x33FE, 0xFB4E, 0xFA10, 0xFF3F, 0xFA2D}; 368 369 370 const int SIZE = 10; 371 372 int count = 0; 373 UErrorCode error = U_ZERO_ERROR; 374 375 for (; count < SIZE; count ++) 376 { 377 if (unorm_quickCheck(&(CPNFD[count]), 1, UNORM_NFD, &error) != 378 UNORM_NO) 379 { 380 log_err("ERROR in NFD quick check at U+%04x\n", CPNFD[count]); 381 return; 382 } 383 if (unorm_quickCheck(&(CPNFC[count]), 1, UNORM_NFC, &error) != 384 UNORM_NO) 385 { 386 log_err("ERROR in NFC quick check at U+%04x\n", CPNFC[count]); 387 return; 388 } 389 if (unorm_quickCheck(&(CPNFKD[count]), 1, UNORM_NFKD, &error) != 390 UNORM_NO) 391 { 392 log_err("ERROR in NFKD quick check at U+%04x\n", CPNFKD[count]); 393 return; 394 } 395 if (unorm_quickCheck(&(CPNFKC[count]), 1, UNORM_NFKC, &error) != 396 UNORM_NO) 397 { 398 log_err("ERROR in NFKC quick check at U+%04x\n", CPNFKC[count]); 399 return; 400 } 401 } 402} 403 404 405static void TestQuickCheckResultYES() 406{ 407 const UChar CPNFD[] = {0x00C6, 0x017F, 0x0F74, 0x1000, 0x1E9A, 408 0x2261, 0x3075, 0x4000, 0x5000, 0xF000}; 409 const UChar CPNFC[] = {0x0400, 0x0540, 0x0901, 0x1000, 0x1500, 410 0x1E9A, 0x3000, 0x4000, 0x5000, 0xF000}; 411 const UChar CPNFKD[] = {0x00AB, 0x02A0, 0x1000, 0x1027, 0x2FFB, 412 0x3FFF, 0x4FFF, 0xA000, 0xF000, 0xFA27}; 413 const UChar CPNFKC[] = {0x00B0, 0x0100, 0x0200, 0x0A02, 0x1000, 414 0x2010, 0x3030, 0x4000, 0xA000, 0xFA0E}; 415 416 const int SIZE = 10; 417 int count = 0; 418 UErrorCode error = U_ZERO_ERROR; 419 420 UChar cp = 0; 421 while (cp < 0xA0) 422 { 423 if (unorm_quickCheck(&cp, 1, UNORM_NFD, &error) != UNORM_YES) 424 { 425 log_data_err("ERROR in NFD quick check at U+%04x - (Are you missing data?)\n", cp); 426 return; 427 } 428 if (unorm_quickCheck(&cp, 1, UNORM_NFC, &error) != 429 UNORM_YES) 430 { 431 log_err("ERROR in NFC quick check at U+%04x\n", cp); 432 return; 433 } 434 if (unorm_quickCheck(&cp, 1, UNORM_NFKD, &error) != UNORM_YES) 435 { 436 log_err("ERROR in NFKD quick check at U+%04x\n", cp); 437 return; 438 } 439 if (unorm_quickCheck(&cp, 1, UNORM_NFKC, &error) != 440 UNORM_YES) 441 { 442 log_err("ERROR in NFKC quick check at U+%04x\n", cp); 443 return; 444 } 445 cp ++; 446 } 447 448 for (; count < SIZE; count ++) 449 { 450 if (unorm_quickCheck(&(CPNFD[count]), 1, UNORM_NFD, &error) != 451 UNORM_YES) 452 { 453 log_err("ERROR in NFD quick check at U+%04x\n", CPNFD[count]); 454 return; 455 } 456 if (unorm_quickCheck(&(CPNFC[count]), 1, UNORM_NFC, &error) 457 != UNORM_YES) 458 { 459 log_err("ERROR in NFC quick check at U+%04x\n", CPNFC[count]); 460 return; 461 } 462 if (unorm_quickCheck(&(CPNFKD[count]), 1, UNORM_NFKD, &error) != 463 UNORM_YES) 464 { 465 log_err("ERROR in NFKD quick check at U+%04x\n", CPNFKD[count]); 466 return; 467 } 468 if (unorm_quickCheck(&(CPNFKC[count]), 1, UNORM_NFKC, &error) != 469 UNORM_YES) 470 { 471 log_err("ERROR in NFKC quick check at U+%04x\n", CPNFKC[count]); 472 return; 473 } 474 } 475} 476 477static void TestQuickCheckResultMAYBE() 478{ 479 const UChar CPNFC[] = {0x0306, 0x0654, 0x0BBE, 0x102E, 0x1161, 480 0x116A, 0x1173, 0x1175, 0x3099, 0x309A}; 481 const UChar CPNFKC[] = {0x0300, 0x0654, 0x0655, 0x09D7, 0x0B3E, 482 0x0DCF, 0xDDF, 0x102E, 0x11A8, 0x3099}; 483 484 485 const int SIZE = 10; 486 487 int count = 0; 488 UErrorCode error = U_ZERO_ERROR; 489 490 /* NFD and NFKD does not have any MAYBE codepoints */ 491 for (; count < SIZE; count ++) 492 { 493 if (unorm_quickCheck(&(CPNFC[count]), 1, UNORM_NFC, &error) != 494 UNORM_MAYBE) 495 { 496 log_data_err("ERROR in NFC quick check at U+%04x - (Are you missing data?)\n", CPNFC[count]); 497 return; 498 } 499 if (unorm_quickCheck(&(CPNFKC[count]), 1, UNORM_NFKC, &error) != 500 UNORM_MAYBE) 501 { 502 log_err("ERROR in NFKC quick check at U+%04x\n", CPNFKC[count]); 503 return; 504 } 505 } 506} 507 508static void TestQuickCheckStringResult() 509{ 510 int count; 511 UChar *d = NULL; 512 UChar *c = NULL; 513 UErrorCode error = U_ZERO_ERROR; 514 515 for (count = 0; count < LENGTHOF(canonTests); count ++) 516 { 517 d = CharsToUChars(canonTests[count][1]); 518 c = CharsToUChars(canonTests[count][2]); 519 if (unorm_quickCheck(d, u_strlen(d), UNORM_NFD, &error) != 520 UNORM_YES) 521 { 522 log_data_err("ERROR in NFD quick check for string at count %d - (Are you missing data?)\n", count); 523 return; 524 } 525 526 if (unorm_quickCheck(c, u_strlen(c), UNORM_NFC, &error) == 527 UNORM_NO) 528 { 529 log_err("ERROR in NFC quick check for string at count %d\n", count); 530 return; 531 } 532 533 free(d); 534 free(c); 535 } 536 537 for (count = 0; count < LENGTHOF(compatTests); count ++) 538 { 539 d = CharsToUChars(compatTests[count][1]); 540 c = CharsToUChars(compatTests[count][2]); 541 if (unorm_quickCheck(d, u_strlen(d), UNORM_NFKD, &error) != 542 UNORM_YES) 543 { 544 log_err("ERROR in NFKD quick check for string at count %d\n", count); 545 return; 546 } 547 548 if (unorm_quickCheck(c, u_strlen(c), UNORM_NFKC, &error) != 549 UNORM_YES) 550 { 551 log_err("ERROR in NFKC quick check for string at count %d\n", count); 552 return; 553 } 554 555 free(d); 556 free(c); 557 } 558} 559 560void TestQuickCheck() 561{ 562 TestQuickCheckResultNO(); 563 TestQuickCheckResultYES(); 564 TestQuickCheckResultMAYBE(); 565 TestQuickCheckStringResult(); 566} 567 568/* 569 * The intltest/NormalizerConformanceTest tests a lot of strings that _are_ 570 * normalized, and some that are not. 571 * Here we pick some specific cases and test the C API. 572 */ 573static void TestIsNormalized(void) { 574 static const UChar notNFC[][8]={ /* strings that are not in NFC */ 575 { 0x62, 0x61, 0x300, 0x63, 0 }, /* 0061 0300 compose */ 576 { 0xfb1d, 0 }, /* excluded from composition */ 577 { 0x0627, 0x0653, 0 }, /* 0627 0653 compose */ 578 { 0x3071, 0x306f, 0x309a, 0x3073, 0 } /* 306F 309A compose */ 579 }; 580 static const UChar notNFKC[][8]={ /* strings that are not in NFKC */ 581 { 0x1100, 0x1161, 0 }, /* Jamo compose */ 582 { 0x1100, 0x314f, 0 }, /* compatibility Jamo compose */ 583 { 0x03b1, 0x1f00, 0x0345, 0x03b3, 0 } /* 1F00 0345 compose */ 584 }; 585 586 int32_t i; 587 UErrorCode errorCode; 588 589 /* API test */ 590 591 /* normal case with length>=0 (length -1 used for special cases below) */ 592 errorCode=U_ZERO_ERROR; 593 if(!unorm_isNormalized(notNFC[0]+2, 1, UNORM_NFC, &errorCode) || U_FAILURE(errorCode)) { 594 log_data_err("error: !isNormalized(<U+0300>, NFC) (%s) - (Are you missing data?)\n", u_errorName(errorCode)); 595 } 596 597 /* incoming U_FAILURE */ 598 errorCode=U_TRUNCATED_CHAR_FOUND; 599 (void)unorm_isNormalized(notNFC[0]+2, 1, UNORM_NFC, &errorCode); 600 if(errorCode!=U_TRUNCATED_CHAR_FOUND) { 601 log_err("error: isNormalized(U_TRUNCATED_CHAR_FOUND) changed the error code to %s\n", u_errorName(errorCode)); 602 } 603 604 /* NULL source */ 605 errorCode=U_ZERO_ERROR; 606 (void)unorm_isNormalized(NULL, 1, UNORM_NFC, &errorCode); 607 if(errorCode!=U_ILLEGAL_ARGUMENT_ERROR) { 608 log_data_err("error: isNormalized(NULL) did not set U_ILLEGAL_ARGUMENT_ERROR but %s - (Are you missing data?)\n", u_errorName(errorCode)); 609 } 610 611 /* bad length */ 612 errorCode=U_ZERO_ERROR; 613 (void)unorm_isNormalized(notNFC[0]+2, -2, UNORM_NFC, &errorCode); 614 if(errorCode!=U_ILLEGAL_ARGUMENT_ERROR) { 615 log_data_err("error: isNormalized([-2]) did not set U_ILLEGAL_ARGUMENT_ERROR but %s - (Are you missing data?)\n", u_errorName(errorCode)); 616 } 617 618 /* specific cases */ 619 for(i=0; i<LENGTHOF(notNFC); ++i) { 620 errorCode=U_ZERO_ERROR; 621 if(unorm_isNormalized(notNFC[i], -1, UNORM_NFC, &errorCode) || U_FAILURE(errorCode)) { 622 log_data_err("error: isNormalized(notNFC[%d], NFC) is wrong (%s) - (Are you missing data?)\n", i, u_errorName(errorCode)); 623 } 624 errorCode=U_ZERO_ERROR; 625 if(unorm_isNormalized(notNFC[i], -1, UNORM_NFKC, &errorCode) || U_FAILURE(errorCode)) { 626 log_data_err("error: isNormalized(notNFC[%d], NFKC) is wrong (%s) - (Are you missing data?)\n", i, u_errorName(errorCode)); 627 } 628 } 629 for(i=0; i<LENGTHOF(notNFKC); ++i) { 630 errorCode=U_ZERO_ERROR; 631 if(unorm_isNormalized(notNFKC[i], -1, UNORM_NFKC, &errorCode) || U_FAILURE(errorCode)) { 632 log_data_err("error: isNormalized(notNFKC[%d], NFKC) is wrong (%s) - (Are you missing data?)\n", i, u_errorName(errorCode)); 633 } 634 } 635} 636 637void TestCheckFCD() 638{ 639 UErrorCode status = U_ZERO_ERROR; 640 static const UChar FAST_[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 641 0x0A}; 642 static const UChar FALSE_[] = {0x0001, 0x0002, 0x02EA, 0x03EB, 0x0300, 0x0301, 643 0x02B9, 0x0314, 0x0315, 0x0316}; 644 static const UChar TRUE_[] = {0x0030, 0x0040, 0x0440, 0x056D, 0x064F, 0x06E7, 645 0x0050, 0x0730, 0x09EE, 0x1E10}; 646 647 static const UChar datastr[][5] = 648 { {0x0061, 0x030A, 0x1E05, 0x0302, 0}, 649 {0x0061, 0x030A, 0x00E2, 0x0323, 0}, 650 {0x0061, 0x0323, 0x00E2, 0x0323, 0}, 651 {0x0061, 0x0323, 0x1E05, 0x0302, 0} }; 652 static const UBool result[] = {UNORM_YES, UNORM_NO, UNORM_NO, UNORM_YES}; 653 654 static const UChar datachar[] = {0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 655 0x6a, 656 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 657 0xea, 658 0x0300, 0x0301, 0x0302, 0x0303, 0x0304, 0x0305, 0x0306, 659 0x0307, 0x0308, 0x0309, 0x030a, 660 0x0320, 0x0321, 0x0322, 0x0323, 0x0324, 0x0325, 0x0326, 661 0x0327, 0x0328, 0x0329, 0x032a, 662 0x1e00, 0x1e01, 0x1e02, 0x1e03, 0x1e04, 0x1e05, 0x1e06, 663 0x1e07, 0x1e08, 0x1e09, 0x1e0a}; 664 665 int count = 0; 666 667 if (unorm_quickCheck(FAST_, 10, UNORM_FCD, &status) != UNORM_YES) 668 log_data_err("unorm_quickCheck(FCD) failed: expected value for fast unorm_quickCheck is UNORM_YES - (Are you missing data?)\n"); 669 if (unorm_quickCheck(FALSE_, 10, UNORM_FCD, &status) != UNORM_NO) 670 log_err("unorm_quickCheck(FCD) failed: expected value for error unorm_quickCheck is UNORM_NO\n"); 671 if (unorm_quickCheck(TRUE_, 10, UNORM_FCD, &status) != UNORM_YES) 672 log_data_err("unorm_quickCheck(FCD) failed: expected value for correct unorm_quickCheck is UNORM_YES - (Are you missing data?)\n"); 673 674 if (U_FAILURE(status)) 675 log_data_err("unorm_quickCheck(FCD) failed: %s - (Are you missing data?)\n", u_errorName(status)); 676 677 while (count < 4) 678 { 679 UBool fcdresult = unorm_quickCheck(datastr[count], 4, UNORM_FCD, &status); 680 if (U_FAILURE(status)) { 681 log_data_err("unorm_quickCheck(FCD) failed: exception occured at data set %d - (Are you missing data?)\n", count); 682 break; 683 } 684 else { 685 if (result[count] != fcdresult) { 686 log_err("unorm_quickCheck(FCD) failed: Data set %d expected value %d\n", count, 687 result[count]); 688 } 689 } 690 count ++; 691 } 692 693 /* random checks of long strings */ 694 status = U_ZERO_ERROR; 695 srand((unsigned)time( NULL )); 696 697 for (count = 0; count < 50; count ++) 698 { 699 int size = 0; 700 UBool testresult = UNORM_YES; 701 UChar data[20]; 702 UChar norm[100]; 703 UChar nfd[100]; 704 int normsize = 0; 705 int nfdsize = 0; 706 707 while (size != 19) { 708 data[size] = datachar[(rand() * 50) / RAND_MAX]; 709 log_verbose("0x%x", data[size]); 710 normsize += unorm_normalize(data + size, 1, UNORM_NFD, 0, 711 norm + normsize, 100 - normsize, &status); 712 if (U_FAILURE(status)) { 713 log_data_err("unorm_quickCheck(FCD) failed: exception occured at data generation - (Are you missing data?)\n"); 714 break; 715 } 716 size ++; 717 } 718 log_verbose("\n"); 719 720 nfdsize = unorm_normalize(data, size, UNORM_NFD, 0, 721 nfd, 100, &status); 722 if (U_FAILURE(status)) { 723 log_data_err("unorm_quickCheck(FCD) failed: exception occured at normalized data generation - (Are you missing data?)\n"); 724 } 725 726 if (nfdsize != normsize || u_memcmp(nfd, norm, nfdsize) != 0) { 727 testresult = UNORM_NO; 728 } 729 if (testresult == UNORM_YES) { 730 log_verbose("result UNORM_YES\n"); 731 } 732 else { 733 log_verbose("result UNORM_NO\n"); 734 } 735 736 if (unorm_quickCheck(data, size, UNORM_FCD, &status) != testresult || U_FAILURE(status)) { 737 log_data_err("unorm_quickCheck(FCD) failed: expected %d for random data - (Are you missing data?)\n", testresult); 738 } 739 } 740} 741 742static void 743TestAPI() { 744 static const UChar in[]={ 0x68, 0xe4 }; 745 UChar out[20]={ 0xffff, 0xffff, 0xffff, 0xffff }; 746 UErrorCode errorCode; 747 int32_t length; 748 749 /* try preflighting */ 750 errorCode=U_ZERO_ERROR; 751 length=unorm_normalize(in, 2, UNORM_NFD, 0, NULL, 0, &errorCode); 752 if(errorCode!=U_BUFFER_OVERFLOW_ERROR || length!=3) { 753 log_data_err("unorm_normalize(pure preflighting NFD)=%ld failed with %s - (Are you missing data?)\n", length, u_errorName(errorCode)); 754 return; 755 } 756 757 errorCode=U_ZERO_ERROR; 758 length=unorm_normalize(in, 2, UNORM_NFD, 0, out, 3, &errorCode); 759 if(U_FAILURE(errorCode)) { 760 log_err("unorm_normalize(NFD)=%ld failed with %s\n", length, u_errorName(errorCode)); 761 return; 762 } 763 if(length!=3 || out[2]!=0x308 || out[3]!=0xffff) { 764 log_err("unorm_normalize(NFD ma<umlaut>)=%ld failed with out[]=U+%04x U+%04x U+%04x U+%04x\n", length, out[0], out[1], out[2], out[3]); 765 return; 766 } 767} 768 769/* test cases to improve test code coverage */ 770enum { 771 HANGUL_K_KIYEOK=0x3131, /* NFKD->Jamo L U+1100 */ 772 HANGUL_K_WEO=0x315d, /* NFKD->Jamo V U+116f */ 773 HANGUL_K_KIYEOK_SIOS=0x3133, /* NFKD->Jamo T U+11aa */ 774 775 HANGUL_KIYEOK=0x1100, /* Jamo L U+1100 */ 776 HANGUL_WEO=0x116f, /* Jamo V U+116f */ 777 HANGUL_KIYEOK_SIOS=0x11aa, /* Jamo T U+11aa */ 778 779 HANGUL_AC00=0xac00, /* Hangul syllable = Jamo LV U+ac00 */ 780 HANGUL_SYLLABLE=0xac00+14*28+3, /* Hangul syllable = U+1100 * U+116f * U+11aa */ 781 782 MUSICAL_VOID_NOTEHEAD=0x1d157, 783 MUSICAL_HALF_NOTE=0x1d15e, /* NFC/NFD->Notehead+Stem */ 784 MUSICAL_STEM=0x1d165, /* cc=216 */ 785 MUSICAL_STACCATO=0x1d17c /* cc=220 */ 786}; 787 788static void 789TestNormCoverage() { 790 UChar input[1000], expect[1000], output[1000]; 791 UErrorCode errorCode; 792 int32_t i, length, inLength, expectLength, hangulPrefixLength, preflightLength; 793 794 /* create a long and nasty string with NFKC-unsafe characters */ 795 inLength=0; 796 797 /* 3 Jamos L/V/T, all 8 combinations normal/compatibility */ 798 input[inLength++]=HANGUL_KIYEOK; 799 input[inLength++]=HANGUL_WEO; 800 input[inLength++]=HANGUL_KIYEOK_SIOS; 801 802 input[inLength++]=HANGUL_KIYEOK; 803 input[inLength++]=HANGUL_WEO; 804 input[inLength++]=HANGUL_K_KIYEOK_SIOS; 805 806 input[inLength++]=HANGUL_KIYEOK; 807 input[inLength++]=HANGUL_K_WEO; 808 input[inLength++]=HANGUL_KIYEOK_SIOS; 809 810 input[inLength++]=HANGUL_KIYEOK; 811 input[inLength++]=HANGUL_K_WEO; 812 input[inLength++]=HANGUL_K_KIYEOK_SIOS; 813 814 input[inLength++]=HANGUL_K_KIYEOK; 815 input[inLength++]=HANGUL_WEO; 816 input[inLength++]=HANGUL_KIYEOK_SIOS; 817 818 input[inLength++]=HANGUL_K_KIYEOK; 819 input[inLength++]=HANGUL_WEO; 820 input[inLength++]=HANGUL_K_KIYEOK_SIOS; 821 822 input[inLength++]=HANGUL_K_KIYEOK; 823 input[inLength++]=HANGUL_K_WEO; 824 input[inLength++]=HANGUL_KIYEOK_SIOS; 825 826 input[inLength++]=HANGUL_K_KIYEOK; 827 input[inLength++]=HANGUL_K_WEO; 828 input[inLength++]=HANGUL_K_KIYEOK_SIOS; 829 830 /* Hangul LV with normal/compatibility Jamo T */ 831 input[inLength++]=HANGUL_AC00; 832 input[inLength++]=HANGUL_KIYEOK_SIOS; 833 834 input[inLength++]=HANGUL_AC00; 835 input[inLength++]=HANGUL_K_KIYEOK_SIOS; 836 837 /* compatibility Jamo L, V */ 838 input[inLength++]=HANGUL_K_KIYEOK; 839 input[inLength++]=HANGUL_K_WEO; 840 841 hangulPrefixLength=inLength; 842 843 input[inLength++]=UTF16_LEAD(MUSICAL_HALF_NOTE); 844 input[inLength++]=UTF16_TRAIL(MUSICAL_HALF_NOTE); 845 for(i=0; i<200; ++i) { 846 input[inLength++]=UTF16_LEAD(MUSICAL_STACCATO); 847 input[inLength++]=UTF16_TRAIL(MUSICAL_STACCATO); 848 input[inLength++]=UTF16_LEAD(MUSICAL_STEM); 849 input[inLength++]=UTF16_TRAIL(MUSICAL_STEM); 850 } 851 852 /* (compatibility) Jamo L, T do not compose */ 853 input[inLength++]=HANGUL_K_KIYEOK; 854 input[inLength++]=HANGUL_K_KIYEOK_SIOS; 855 856 /* quick checks */ 857 errorCode=U_ZERO_ERROR; 858 if(UNORM_NO!=unorm_quickCheck(input, inLength, UNORM_NFD, &errorCode) || U_FAILURE(errorCode)) { 859 log_data_err("error unorm_quickCheck(long input, UNORM_NFD)!=NO (%s) - (Are you missing data?)\n", u_errorName(errorCode)); 860 } 861 errorCode=U_ZERO_ERROR; 862 if(UNORM_NO!=unorm_quickCheck(input, inLength, UNORM_NFKD, &errorCode) || U_FAILURE(errorCode)) { 863 log_data_err("error unorm_quickCheck(long input, UNORM_NFKD)!=NO (%s) - (Are you missing data?)\n", u_errorName(errorCode)); 864 } 865 errorCode=U_ZERO_ERROR; 866 if(UNORM_NO!=unorm_quickCheck(input, inLength, UNORM_NFC, &errorCode) || U_FAILURE(errorCode)) { 867 log_data_err("error unorm_quickCheck(long input, UNORM_NFC)!=NO (%s) - (Are you missing data?)\n", u_errorName(errorCode)); 868 } 869 errorCode=U_ZERO_ERROR; 870 if(UNORM_NO!=unorm_quickCheck(input, inLength, UNORM_NFKC, &errorCode) || U_FAILURE(errorCode)) { 871 log_data_err("error unorm_quickCheck(long input, UNORM_NFKC)!=NO (%s) - (Are you missing data?)\n", u_errorName(errorCode)); 872 } 873 errorCode=U_ZERO_ERROR; 874 if(UNORM_NO!=unorm_quickCheck(input, inLength, UNORM_FCD, &errorCode) || U_FAILURE(errorCode)) { 875 log_data_err("error unorm_quickCheck(long input, UNORM_FCD)!=NO (%s) - (Are you missing data?)\n", u_errorName(errorCode)); 876 } 877 878 /* NFKC */ 879 expectLength=0; 880 expect[expectLength++]=HANGUL_SYLLABLE; 881 882 expect[expectLength++]=HANGUL_SYLLABLE; 883 884 expect[expectLength++]=HANGUL_SYLLABLE; 885 886 expect[expectLength++]=HANGUL_SYLLABLE; 887 888 expect[expectLength++]=HANGUL_SYLLABLE; 889 890 expect[expectLength++]=HANGUL_SYLLABLE; 891 892 expect[expectLength++]=HANGUL_SYLLABLE; 893 894 expect[expectLength++]=HANGUL_SYLLABLE; 895 896 expect[expectLength++]=HANGUL_AC00+3; 897 898 expect[expectLength++]=HANGUL_AC00+3; 899 900 expect[expectLength++]=HANGUL_AC00+14*28; 901 902 expect[expectLength++]=UTF16_LEAD(MUSICAL_VOID_NOTEHEAD); 903 expect[expectLength++]=UTF16_TRAIL(MUSICAL_VOID_NOTEHEAD); 904 expect[expectLength++]=UTF16_LEAD(MUSICAL_STEM); 905 expect[expectLength++]=UTF16_TRAIL(MUSICAL_STEM); 906 for(i=0; i<200; ++i) { 907 expect[expectLength++]=UTF16_LEAD(MUSICAL_STEM); 908 expect[expectLength++]=UTF16_TRAIL(MUSICAL_STEM); 909 } 910 for(i=0; i<200; ++i) { 911 expect[expectLength++]=UTF16_LEAD(MUSICAL_STACCATO); 912 expect[expectLength++]=UTF16_TRAIL(MUSICAL_STACCATO); 913 } 914 915 expect[expectLength++]=HANGUL_KIYEOK; 916 expect[expectLength++]=HANGUL_KIYEOK_SIOS; 917 918 /* try destination overflow first */ 919 errorCode=U_ZERO_ERROR; 920 preflightLength=unorm_normalize(input, inLength, 921 UNORM_NFKC, 0, 922 output, 100, /* too short */ 923 &errorCode); 924 if(errorCode!=U_BUFFER_OVERFLOW_ERROR) { 925 log_data_err("error unorm_normalize(long input, output too short, UNORM_NFKC) did not overflow but %s - (Are you missing data?)\n", u_errorName(errorCode)); 926 } 927 928 /* real NFKC */ 929 errorCode=U_ZERO_ERROR; 930 length=unorm_normalize(input, inLength, 931 UNORM_NFKC, 0, 932 output, sizeof(output)/U_SIZEOF_UCHAR, 933 &errorCode); 934 if(U_FAILURE(errorCode)) { 935 log_data_err("error unorm_normalize(long input, UNORM_NFKC) failed with %s - (Are you missing data?)\n", u_errorName(errorCode)); 936 } else if(length!=expectLength || u_memcmp(output, expect, length)!=0) { 937 log_err("error unorm_normalize(long input, UNORM_NFKC) produced wrong result\n"); 938 for(i=0; i<length; ++i) { 939 if(output[i]!=expect[i]) { 940 log_err(" NFKC[%d]==U+%04lx expected U+%04lx\n", i, output[i], expect[i]); 941 break; 942 } 943 } 944 } 945 if(length!=preflightLength) { 946 log_err("error unorm_normalize(long input, UNORM_NFKC)==%ld but preflightLength==%ld\n", length, preflightLength); 947 } 948 949 /* FCD */ 950 u_memcpy(expect, input, hangulPrefixLength); 951 expectLength=hangulPrefixLength; 952 953 expect[expectLength++]=UTF16_LEAD(MUSICAL_VOID_NOTEHEAD); 954 expect[expectLength++]=UTF16_TRAIL(MUSICAL_VOID_NOTEHEAD); 955 expect[expectLength++]=UTF16_LEAD(MUSICAL_STEM); 956 expect[expectLength++]=UTF16_TRAIL(MUSICAL_STEM); 957 for(i=0; i<200; ++i) { 958 expect[expectLength++]=UTF16_LEAD(MUSICAL_STEM); 959 expect[expectLength++]=UTF16_TRAIL(MUSICAL_STEM); 960 } 961 for(i=0; i<200; ++i) { 962 expect[expectLength++]=UTF16_LEAD(MUSICAL_STACCATO); 963 expect[expectLength++]=UTF16_TRAIL(MUSICAL_STACCATO); 964 } 965 966 expect[expectLength++]=HANGUL_K_KIYEOK; 967 expect[expectLength++]=HANGUL_K_KIYEOK_SIOS; 968 969 errorCode=U_ZERO_ERROR; 970 length=unorm_normalize(input, inLength, 971 UNORM_FCD, 0, 972 output, sizeof(output)/U_SIZEOF_UCHAR, 973 &errorCode); 974 if(U_FAILURE(errorCode)) { 975 log_data_err("error unorm_normalize(long input, UNORM_FCD) failed with %s - (Are you missing data?)\n", u_errorName(errorCode)); 976 } else if(length!=expectLength || u_memcmp(output, expect, length)!=0) { 977 log_err("error unorm_normalize(long input, UNORM_FCD) produced wrong result\n"); 978 for(i=0; i<length; ++i) { 979 if(output[i]!=expect[i]) { 980 log_err(" FCD[%d]==U+%04lx expected U+%04lx\n", i, output[i], expect[i]); 981 break; 982 } 983 } 984 } 985} 986 987/* API test for unorm_concatenate() - for real test strings see intltest/tstnorm.cpp */ 988static void 989TestConcatenate(void) { 990 /* "re + 'sume'" */ 991 static const UChar 992 left[]={ 993 0x72, 0x65, 0 994 }, 995 right[]={ 996 0x301, 0x73, 0x75, 0x6d, 0xe9, 0 997 }, 998 expect[]={ 999 0x72, 0xe9, 0x73, 0x75, 0x6d, 0xe9, 0 1000 }; 1001 1002 UChar buffer[100]; 1003 UErrorCode errorCode; 1004 int32_t length; 1005 1006 /* left with length, right NUL-terminated */ 1007 errorCode=U_ZERO_ERROR; 1008 length=unorm_concatenate(left, 2, right, -1, buffer, 100, UNORM_NFC, 0, &errorCode); 1009 if(U_FAILURE(errorCode) || length!=6 || 0!=u_memcmp(buffer, expect, length)) { 1010 log_data_err("error: unorm_concatenate()=%ld (expect 6) failed with %s - (Are you missing data?)\n", length, u_errorName(errorCode)); 1011 } 1012 1013 /* preflighting */ 1014 errorCode=U_ZERO_ERROR; 1015 length=unorm_concatenate(left, 2, right, -1, NULL, 0, UNORM_NFC, 0, &errorCode); 1016 if(errorCode!=U_BUFFER_OVERFLOW_ERROR || length!=6) { 1017 log_data_err("error: unorm_concatenate(preflighting)=%ld (expect 6) failed with %s - (Are you missing data?)\n", length, u_errorName(errorCode)); 1018 } 1019 1020 buffer[2]=0x5555; 1021 errorCode=U_ZERO_ERROR; 1022 length=unorm_concatenate(left, 2, right, -1, buffer, 1, UNORM_NFC, 0, &errorCode); 1023 if(errorCode!=U_BUFFER_OVERFLOW_ERROR || length!=6 || buffer[2]!=0x5555) { 1024 log_data_err("error: unorm_concatenate(preflighting 2)=%ld (expect 6) failed with %s - (Are you missing data?)\n", length, u_errorName(errorCode)); 1025 } 1026 1027 /* enter with U_FAILURE */ 1028 buffer[2]=0xaaaa; 1029 errorCode=U_UNEXPECTED_TOKEN; 1030 length=unorm_concatenate(left, 2, right, -1, buffer, 100, UNORM_NFC, 0, &errorCode); 1031 if(errorCode!=U_UNEXPECTED_TOKEN || buffer[2]!=0xaaaa) { 1032 log_err("error: unorm_concatenate(failure)=%ld failed with %s\n", length, u_errorName(errorCode)); 1033 } 1034 1035 /* illegal arguments */ 1036 buffer[2]=0xaaaa; 1037 errorCode=U_ZERO_ERROR; 1038 length=unorm_concatenate(NULL, 2, right, -1, buffer, 100, UNORM_NFC, 0, &errorCode); 1039 if(errorCode!=U_ILLEGAL_ARGUMENT_ERROR || buffer[2]!=0xaaaa) { 1040 log_data_err("error: unorm_concatenate(left=NULL)=%ld failed with %s - (Are you missing data?)\n", length, u_errorName(errorCode)); 1041 } 1042 1043 errorCode=U_ZERO_ERROR; 1044 length=unorm_concatenate(left, 2, right, -1, NULL, 100, UNORM_NFC, 0, &errorCode); 1045 if(errorCode!=U_ILLEGAL_ARGUMENT_ERROR) { 1046 log_data_err("error: unorm_concatenate(buffer=NULL)=%ld failed with %s - (Are you missing data?)\n", length, u_errorName(errorCode)); 1047 } 1048} 1049 1050enum { 1051 _PLUS=0x2b 1052}; 1053 1054static const char *const _modeString[UNORM_MODE_COUNT]={ 1055 "0", "NONE", "NFD", "NFKD", "NFC", "NFKC", "FCD" 1056}; 1057 1058static void 1059_testIter(const UChar *src, int32_t srcLength, 1060 UCharIterator *iter, UNormalizationMode mode, UBool forward, 1061 const UChar *out, int32_t outLength, 1062 const int32_t *srcIndexes, int32_t srcIndexesLength) { 1063 UChar buffer[4]; 1064 const UChar *expect, *outLimit, *in; 1065 int32_t length, i, expectLength, expectIndex, prevIndex, index, inLength; 1066 UErrorCode errorCode; 1067 UBool neededToNormalize, expectNeeded; 1068 1069 errorCode=U_ZERO_ERROR; 1070 outLimit=out+outLength; 1071 if(forward) { 1072 expect=out; 1073 i=index=0; 1074 } else { 1075 expect=outLimit; 1076 i=srcIndexesLength-2; 1077 index=srcLength; 1078 } 1079 1080 for(;;) { 1081 prevIndex=index; 1082 if(forward) { 1083 if(!iter->hasNext(iter)) { 1084 return; 1085 } 1086 length=unorm_next(iter, 1087 buffer, sizeof(buffer)/U_SIZEOF_UCHAR, 1088 mode, 0, 1089 (UBool)(out!=NULL), &neededToNormalize, 1090 &errorCode); 1091 expectIndex=srcIndexes[i+1]; 1092 in=src+prevIndex; 1093 inLength=expectIndex-prevIndex; 1094 1095 if(out!=NULL) { 1096 /* get output piece from between plus signs */ 1097 expectLength=0; 1098 while((expect+expectLength)!=outLimit && expect[expectLength]!=_PLUS) { 1099 ++expectLength; 1100 } 1101 expectNeeded=(UBool)(0!=u_memcmp(buffer, in, inLength)); 1102 } else { 1103 expect=in; 1104 expectLength=inLength; 1105 expectNeeded=FALSE; 1106 } 1107 } else { 1108 if(!iter->hasPrevious(iter)) { 1109 return; 1110 } 1111 length=unorm_previous(iter, 1112 buffer, sizeof(buffer)/U_SIZEOF_UCHAR, 1113 mode, 0, 1114 (UBool)(out!=NULL), &neededToNormalize, 1115 &errorCode); 1116 expectIndex=srcIndexes[i]; 1117 in=src+expectIndex; 1118 inLength=prevIndex-expectIndex; 1119 1120 if(out!=NULL) { 1121 /* get output piece from between plus signs */ 1122 expectLength=0; 1123 while(expect!=out && expect[-1]!=_PLUS) { 1124 ++expectLength; 1125 --expect; 1126 } 1127 expectNeeded=(UBool)(0!=u_memcmp(buffer, in, inLength)); 1128 } else { 1129 expect=in; 1130 expectLength=inLength; 1131 expectNeeded=FALSE; 1132 } 1133 } 1134 index=iter->getIndex(iter, UITER_CURRENT); 1135 1136 if(U_FAILURE(errorCode)) { 1137 log_data_err("error unorm iteration (next/previous %d %s)[%d]: %s - (Are you missing data?)\n", 1138 forward, _modeString[mode], i, u_errorName(errorCode)); 1139 return; 1140 } 1141 if(expectIndex!=index) { 1142 log_err("error unorm iteration (next/previous %d %s): index[%d] wrong, got %d expected %d\n", 1143 forward, _modeString[mode], i, index, expectIndex); 1144 return; 1145 } 1146 if(expectLength!=length) { 1147 log_err("error unorm iteration (next/previous %d %s): length[%d] wrong, got %d expected %d\n", 1148 forward, _modeString[mode], i, length, expectLength); 1149 return; 1150 } 1151 if(0!=u_memcmp(expect, buffer, length)) { 1152 log_err("error unorm iteration (next/previous %d %s): output string[%d] wrong\n", 1153 forward, _modeString[mode], i); 1154 return; 1155 } 1156 if(neededToNormalize!=expectNeeded) { 1157 } 1158 1159 if(forward) { 1160 expect+=expectLength+1; /* go after the + */ 1161 ++i; 1162 } else { 1163 --expect; /* go before the + */ 1164 --i; 1165 } 1166 } 1167} 1168 1169static void 1170TestNextPrevious() { 1171 static const UChar 1172 src[]={ /* input string */ 1173 0xa0, 0xe4, 0x63, 0x302, 0x327, 0xac00, 0x3133 1174 }, 1175 nfd[]={ /* + separates expected output pieces */ 1176 0xa0, _PLUS, 0x61, 0x308, _PLUS, 0x63, 0x327, 0x302, _PLUS, 0x1100, 0x1161, _PLUS, 0x3133 1177 }, 1178 nfkd[]={ 1179 0x20, _PLUS, 0x61, 0x308, _PLUS, 0x63, 0x327, 0x302, _PLUS, 0x1100, 0x1161, _PLUS, 0x11aa 1180 }, 1181 nfc[]={ 1182 0xa0, _PLUS, 0xe4, _PLUS, 0xe7, 0x302, _PLUS, 0xac00, _PLUS, 0x3133 1183 }, 1184 nfkc[]={ 1185 0x20, _PLUS, 0xe4, _PLUS, 0xe7, 0x302, _PLUS, 0xac03 1186 }, 1187 fcd[]={ 1188 0xa0, _PLUS, 0xe4, _PLUS, 0x63, 0x327, 0x302, _PLUS, 0xac00, _PLUS, 0x3133 1189 }; 1190 1191 /* expected iterator indexes in the source string for each iteration piece */ 1192 static const int32_t 1193 nfdIndexes[]={ 1194 0, 1, 2, 5, 6, 7 1195 }, 1196 nfkdIndexes[]={ 1197 0, 1, 2, 5, 6, 7 1198 }, 1199 nfcIndexes[]={ 1200 0, 1, 2, 5, 6, 7 1201 }, 1202 nfkcIndexes[]={ 1203 0, 1, 2, 5, 7 1204 }, 1205 fcdIndexes[]={ 1206 0, 1, 2, 5, 6, 7 1207 }; 1208 1209 UCharIterator iter; 1210 1211 UChar buffer[4]; 1212 int32_t length; 1213 1214 UBool neededToNormalize; 1215 UErrorCode errorCode; 1216 1217 uiter_setString(&iter, src, sizeof(src)/U_SIZEOF_UCHAR); 1218 1219 /* test iteration with doNormalize */ 1220 iter.index=0; 1221 _testIter(src, sizeof(src)/U_SIZEOF_UCHAR, &iter, UNORM_NFD, TRUE, nfd, sizeof(nfd)/U_SIZEOF_UCHAR, nfdIndexes, sizeof(nfdIndexes)/4); 1222 iter.index=0; 1223 _testIter(src, sizeof(src)/U_SIZEOF_UCHAR, &iter, UNORM_NFKD, TRUE, nfkd, sizeof(nfkd)/U_SIZEOF_UCHAR, nfkdIndexes, sizeof(nfkdIndexes)/4); 1224 iter.index=0; 1225 _testIter(src, sizeof(src)/U_SIZEOF_UCHAR, &iter, UNORM_NFC, TRUE, nfc, sizeof(nfc)/U_SIZEOF_UCHAR, nfcIndexes, sizeof(nfcIndexes)/4); 1226 iter.index=0; 1227 _testIter(src, sizeof(src)/U_SIZEOF_UCHAR, &iter, UNORM_NFKC, TRUE, nfkc, sizeof(nfkc)/U_SIZEOF_UCHAR, nfkcIndexes, sizeof(nfkcIndexes)/4); 1228 iter.index=0; 1229 _testIter(src, sizeof(src)/U_SIZEOF_UCHAR, &iter, UNORM_FCD, TRUE, fcd, sizeof(fcd)/U_SIZEOF_UCHAR, fcdIndexes, sizeof(fcdIndexes)/4); 1230 1231 iter.index=iter.length; 1232 _testIter(src, sizeof(src)/U_SIZEOF_UCHAR, &iter, UNORM_NFD, FALSE, nfd, sizeof(nfd)/U_SIZEOF_UCHAR, nfdIndexes, sizeof(nfdIndexes)/4); 1233 iter.index=iter.length; 1234 _testIter(src, sizeof(src)/U_SIZEOF_UCHAR, &iter, UNORM_NFKD, FALSE, nfkd, sizeof(nfkd)/U_SIZEOF_UCHAR, nfkdIndexes, sizeof(nfkdIndexes)/4); 1235 iter.index=iter.length; 1236 _testIter(src, sizeof(src)/U_SIZEOF_UCHAR, &iter, UNORM_NFC, FALSE, nfc, sizeof(nfc)/U_SIZEOF_UCHAR, nfcIndexes, sizeof(nfcIndexes)/4); 1237 iter.index=iter.length; 1238 _testIter(src, sizeof(src)/U_SIZEOF_UCHAR, &iter, UNORM_NFKC, FALSE, nfkc, sizeof(nfkc)/U_SIZEOF_UCHAR, nfkcIndexes, sizeof(nfkcIndexes)/4); 1239 iter.index=iter.length; 1240 _testIter(src, sizeof(src)/U_SIZEOF_UCHAR, &iter, UNORM_FCD, FALSE, fcd, sizeof(fcd)/U_SIZEOF_UCHAR, fcdIndexes, sizeof(fcdIndexes)/4); 1241 1242 /* test iteration without doNormalize */ 1243 iter.index=0; 1244 _testIter(src, sizeof(src)/U_SIZEOF_UCHAR, &iter, UNORM_NFD, TRUE, NULL, 0, nfdIndexes, sizeof(nfdIndexes)/4); 1245 iter.index=0; 1246 _testIter(src, sizeof(src)/U_SIZEOF_UCHAR, &iter, UNORM_NFKD, TRUE, NULL, 0, nfkdIndexes, sizeof(nfkdIndexes)/4); 1247 iter.index=0; 1248 _testIter(src, sizeof(src)/U_SIZEOF_UCHAR, &iter, UNORM_NFC, TRUE, NULL, 0, nfcIndexes, sizeof(nfcIndexes)/4); 1249 iter.index=0; 1250 _testIter(src, sizeof(src)/U_SIZEOF_UCHAR, &iter, UNORM_NFKC, TRUE, NULL, 0, nfkcIndexes, sizeof(nfkcIndexes)/4); 1251 iter.index=0; 1252 _testIter(src, sizeof(src)/U_SIZEOF_UCHAR, &iter, UNORM_FCD, TRUE, NULL, 0, fcdIndexes, sizeof(fcdIndexes)/4); 1253 1254 iter.index=iter.length; 1255 _testIter(src, sizeof(src)/U_SIZEOF_UCHAR, &iter, UNORM_NFD, FALSE, NULL, 0, nfdIndexes, sizeof(nfdIndexes)/4); 1256 iter.index=iter.length; 1257 _testIter(src, sizeof(src)/U_SIZEOF_UCHAR, &iter, UNORM_NFKD, FALSE, NULL, 0, nfkdIndexes, sizeof(nfkdIndexes)/4); 1258 iter.index=iter.length; 1259 _testIter(src, sizeof(src)/U_SIZEOF_UCHAR, &iter, UNORM_NFC, FALSE, NULL, 0, nfcIndexes, sizeof(nfcIndexes)/4); 1260 iter.index=iter.length; 1261 _testIter(src, sizeof(src)/U_SIZEOF_UCHAR, &iter, UNORM_NFKC, FALSE, NULL, 0, nfkcIndexes, sizeof(nfkcIndexes)/4); 1262 iter.index=iter.length; 1263 _testIter(src, sizeof(src)/U_SIZEOF_UCHAR, &iter, UNORM_FCD, FALSE, NULL, 0, fcdIndexes, sizeof(fcdIndexes)/4); 1264 1265 /* try without neededToNormalize */ 1266 errorCode=U_ZERO_ERROR; 1267 buffer[0]=5; 1268 iter.index=1; 1269 length=unorm_next(&iter, buffer, sizeof(buffer)/U_SIZEOF_UCHAR, 1270 UNORM_NFD, 0, TRUE, NULL, 1271 &errorCode); 1272 if(U_FAILURE(errorCode) || length!=2 || buffer[0]!=nfd[2] || buffer[1]!=nfd[3]) { 1273 log_data_err("error unorm_next(without needed) %s - (Are you missing data?)\n", u_errorName(errorCode)); 1274 return; 1275 } 1276 1277 /* preflight */ 1278 neededToNormalize=9; 1279 iter.index=1; 1280 length=unorm_next(&iter, NULL, 0, 1281 UNORM_NFD, 0, TRUE, &neededToNormalize, 1282 &errorCode); 1283 if(errorCode!=U_BUFFER_OVERFLOW_ERROR || neededToNormalize!=FALSE || length!=2) { 1284 log_err("error unorm_next(pure preflighting) %s\n", u_errorName(errorCode)); 1285 return; 1286 } 1287 1288 errorCode=U_ZERO_ERROR; 1289 buffer[0]=buffer[1]=5; 1290 neededToNormalize=9; 1291 iter.index=1; 1292 length=unorm_next(&iter, buffer, 1, 1293 UNORM_NFD, 0, TRUE, &neededToNormalize, 1294 &errorCode); 1295 if(errorCode!=U_BUFFER_OVERFLOW_ERROR || neededToNormalize!=FALSE || length!=2 || buffer[1]!=5) { 1296 log_err("error unorm_next(preflighting) %s\n", u_errorName(errorCode)); 1297 return; 1298 } 1299 1300 /* no iterator */ 1301 errorCode=U_ZERO_ERROR; 1302 buffer[0]=buffer[1]=5; 1303 neededToNormalize=9; 1304 iter.index=1; 1305 length=unorm_next(NULL, buffer, sizeof(buffer)/U_SIZEOF_UCHAR, 1306 UNORM_NFD, 0, TRUE, &neededToNormalize, 1307 &errorCode); 1308 if(errorCode!=U_ILLEGAL_ARGUMENT_ERROR) { 1309 log_err("error unorm_next(no iterator) %s\n", u_errorName(errorCode)); 1310 return; 1311 } 1312 1313 /* illegal mode */ 1314 buffer[0]=buffer[1]=5; 1315 neededToNormalize=9; 1316 iter.index=1; 1317 length=unorm_next(&iter, buffer, sizeof(buffer)/U_SIZEOF_UCHAR, 1318 (UNormalizationMode)0, 0, TRUE, &neededToNormalize, 1319 &errorCode); 1320 if(errorCode!=U_ILLEGAL_ARGUMENT_ERROR) { 1321 log_err("error unorm_next(illegal mode) %s\n", u_errorName(errorCode)); 1322 return; 1323 } 1324 1325 /* error coming in */ 1326 errorCode=U_MISPLACED_QUANTIFIER; 1327 buffer[0]=5; 1328 iter.index=1; 1329 length=unorm_next(&iter, buffer, sizeof(buffer)/U_SIZEOF_UCHAR, 1330 UNORM_NFD, 0, TRUE, NULL, 1331 &errorCode); 1332 if(errorCode!=U_MISPLACED_QUANTIFIER) { 1333 log_err("error unorm_next(U_MISPLACED_QUANTIFIER) %s\n", u_errorName(errorCode)); 1334 return; 1335 } 1336} 1337 1338static void 1339TestFCNFKCClosure(void) { 1340 static const struct { 1341 UChar32 c; 1342 const UChar s[6]; 1343 } tests[]={ 1344 { 0x00C4, { 0 } }, 1345 { 0x00E4, { 0 } }, 1346 { 0x037A, { 0x0020, 0x03B9, 0 } }, 1347 { 0x03D2, { 0x03C5, 0 } }, 1348 { 0x20A8, { 0x0072, 0x0073, 0 } }, 1349 { 0x210B, { 0x0068, 0 } }, 1350 { 0x210C, { 0x0068, 0 } }, 1351 { 0x2121, { 0x0074, 0x0065, 0x006C, 0 } }, 1352 { 0x2122, { 0x0074, 0x006D, 0 } }, 1353 { 0x2128, { 0x007A, 0 } }, 1354 { 0x1D5DB, { 0x0068, 0 } }, 1355 { 0x1D5ED, { 0x007A, 0 } }, 1356 { 0x0061, { 0 } } 1357 }; 1358 1359 UChar buffer[8]; 1360 UErrorCode errorCode; 1361 int32_t i, length; 1362 1363 for(i=0; i<LENGTHOF(tests); ++i) { 1364 errorCode=U_ZERO_ERROR; 1365 length=u_getFC_NFKC_Closure(tests[i].c, buffer, LENGTHOF(buffer), &errorCode); 1366 if(U_FAILURE(errorCode) || length!=u_strlen(buffer) || 0!=u_strcmp(tests[i].s, buffer)) { 1367 log_data_err("u_getFC_NFKC_Closure(U+%04lx) is wrong (%s) - (Are you missing data?)\n", tests[i].c, u_errorName(errorCode)); 1368 } 1369 } 1370 1371 /* error handling */ 1372 errorCode=U_ZERO_ERROR; 1373 length=u_getFC_NFKC_Closure(0x5c, NULL, LENGTHOF(buffer), &errorCode); 1374 if(errorCode!=U_ILLEGAL_ARGUMENT_ERROR) { 1375 log_err("u_getFC_NFKC_Closure(dest=NULL) is wrong (%s)\n", u_errorName(errorCode)); 1376 } 1377 1378 length=u_getFC_NFKC_Closure(0x5c, buffer, LENGTHOF(buffer), &errorCode); 1379 if(errorCode!=U_ILLEGAL_ARGUMENT_ERROR) { 1380 log_err("u_getFC_NFKC_Closure(U_FAILURE) is wrong (%s)\n", u_errorName(errorCode)); 1381 } 1382} 1383 1384static void 1385TestQuickCheckPerCP() { 1386 UErrorCode errorCode; 1387 UChar32 c, lead, trail; 1388 UChar s[U16_MAX_LENGTH], nfd[16]; 1389 int32_t length, lccc1, lccc2, tccc1, tccc2; 1390 int32_t qc1, qc2; 1391 1392 if( 1393 u_getIntPropertyMaxValue(UCHAR_NFD_QUICK_CHECK)!=(int32_t)UNORM_YES || 1394 u_getIntPropertyMaxValue(UCHAR_NFKD_QUICK_CHECK)!=(int32_t)UNORM_YES || 1395 u_getIntPropertyMaxValue(UCHAR_NFC_QUICK_CHECK)!=(int32_t)UNORM_MAYBE || 1396 u_getIntPropertyMaxValue(UCHAR_NFKC_QUICK_CHECK)!=(int32_t)UNORM_MAYBE || 1397 u_getIntPropertyMaxValue(UCHAR_LEAD_CANONICAL_COMBINING_CLASS)!=u_getIntPropertyMaxValue(UCHAR_CANONICAL_COMBINING_CLASS) || 1398 u_getIntPropertyMaxValue(UCHAR_TRAIL_CANONICAL_COMBINING_CLASS)!=u_getIntPropertyMaxValue(UCHAR_CANONICAL_COMBINING_CLASS) 1399 ) { 1400 log_err("wrong result from one of the u_getIntPropertyMaxValue(UCHAR_NF*_QUICK_CHECK) or UCHAR_*_CANONICAL_COMBINING_CLASS\n"); 1401 } 1402 1403 /* 1404 * compare the quick check property values for some code points 1405 * to the quick check results for checking same-code point strings 1406 */ 1407 errorCode=U_ZERO_ERROR; 1408 c=0; 1409 while(c<0x110000) { 1410 length=0; 1411 U16_APPEND_UNSAFE(s, length, c); 1412 1413 qc1=u_getIntPropertyValue(c, UCHAR_NFC_QUICK_CHECK); 1414 qc2=unorm_quickCheck(s, length, UNORM_NFC, &errorCode); 1415 if(qc1!=qc2) { 1416 log_data_err("u_getIntPropertyValue(NFC)=%d != %d=unorm_quickCheck(NFC) for U+%04x - (Are you missing data?)\n", qc1, qc2, c); 1417 } 1418 1419 qc1=u_getIntPropertyValue(c, UCHAR_NFD_QUICK_CHECK); 1420 qc2=unorm_quickCheck(s, length, UNORM_NFD, &errorCode); 1421 if(qc1!=qc2) { 1422 log_data_err("u_getIntPropertyValue(NFD)=%d != %d=unorm_quickCheck(NFD) for U+%04x - (Are you missing data?)\n", qc1, qc2, c); 1423 } 1424 1425 qc1=u_getIntPropertyValue(c, UCHAR_NFKC_QUICK_CHECK); 1426 qc2=unorm_quickCheck(s, length, UNORM_NFKC, &errorCode); 1427 if(qc1!=qc2) { 1428 log_data_err("u_getIntPropertyValue(NFKC)=%d != %d=unorm_quickCheck(NFKC) for U+%04x - (Are you missing data?)\n", qc1, qc2, c); 1429 } 1430 1431 qc1=u_getIntPropertyValue(c, UCHAR_NFKD_QUICK_CHECK); 1432 qc2=unorm_quickCheck(s, length, UNORM_NFKD, &errorCode); 1433 if(qc1!=qc2) { 1434 log_data_err("u_getIntPropertyValue(NFKD)=%d != %d=unorm_quickCheck(NFKD) for U+%04x - (Are you missing data?)\n", qc1, qc2, c); 1435 } 1436 1437 length=unorm_normalize(s, length, UNORM_NFD, 0, nfd, LENGTHOF(nfd), &errorCode); 1438 /* length-length == 0 is used to get around a compiler warning. */ 1439 U16_GET(nfd, 0, length-length, length, lead); 1440 U16_GET(nfd, 0, length-1, length, trail); 1441 1442 lccc1=u_getIntPropertyValue(c, UCHAR_LEAD_CANONICAL_COMBINING_CLASS); 1443 lccc2=u_getCombiningClass(lead); 1444 tccc1=u_getIntPropertyValue(c, UCHAR_TRAIL_CANONICAL_COMBINING_CLASS); 1445 tccc2=u_getCombiningClass(trail); 1446 1447 if(lccc1!=lccc2) { 1448 log_err("u_getIntPropertyValue(lccc)=%d != %d=u_getCombiningClass(lead) for U+%04x\n", 1449 lccc1, lccc2, c); 1450 } 1451 if(tccc1!=tccc2) { 1452 log_err("u_getIntPropertyValue(tccc)=%d != %d=u_getCombiningClass(trail) for U+%04x\n", 1453 tccc1, tccc2, c); 1454 } 1455 1456 /* skip some code points */ 1457 c=(20*c)/19+1; 1458 } 1459} 1460 1461static void 1462TestComposition(void) { 1463 static const struct { 1464 UNormalizationMode mode; 1465 uint32_t options; 1466 UChar input[12]; 1467 UChar expect[12]; 1468 } cases[]={ 1469 /* 1470 * special cases for UAX #15 bug 1471 * see Unicode Corrigendum #5: Normalization Idempotency 1472 * at http://unicode.org/versions/corrigendum5.html 1473 * (was Public Review Issue #29) 1474 */ 1475 { UNORM_NFC, 0, { 0x1100, 0x0300, 0x1161, 0x0327 }, { 0x1100, 0x0300, 0x1161, 0x0327 } }, 1476 { UNORM_NFC, 0, { 0x1100, 0x0300, 0x1161, 0x0327, 0x11a8 }, { 0x1100, 0x0300, 0x1161, 0x0327, 0x11a8 } }, 1477 { UNORM_NFC, 0, { 0xac00, 0x0300, 0x0327, 0x11a8 }, { 0xac00, 0x0327, 0x0300, 0x11a8 } }, 1478 { UNORM_NFC, 0, { 0x0b47, 0x0300, 0x0b3e }, { 0x0b47, 0x0300, 0x0b3e } }, 1479 1480 /* TODO: add test cases for UNORM_FCC here (j2151) */ 1481 }; 1482 1483 UChar output[16]; 1484 UErrorCode errorCode; 1485 int32_t i, length; 1486 1487 for(i=0; i<LENGTHOF(cases); ++i) { 1488 errorCode=U_ZERO_ERROR; 1489 length=unorm_normalize( 1490 cases[i].input, -1, 1491 cases[i].mode, cases[i].options, 1492 output, LENGTHOF(output), 1493 &errorCode); 1494 if( U_FAILURE(errorCode) || 1495 length!=u_strlen(cases[i].expect) || 1496 0!=u_memcmp(output, cases[i].expect, length) 1497 ) { 1498 log_data_err("unexpected result for case %d - (Are you missing data?)\n", i); 1499 } 1500 } 1501} 1502 1503#endif /* #if !UCONFIG_NO_NORMALIZATION */ 1504