X-Git-Url: https://git.saurik.com/apple/icu.git/blobdiff_plain/374ca955a76ecab1204ca8bfa63ff9238d998416..729e4ab9bc6618bc3d8a898e575df7f4019e29ca:/icuSources/test/cintltst/cnormtst.c diff --git a/icuSources/test/cintltst/cnormtst.c b/icuSources/test/cintltst/cnormtst.c index 91d21421..baa12051 100644 --- a/icuSources/test/cintltst/cnormtst.c +++ b/icuSources/test/cintltst/cnormtst.c @@ -1,6 +1,6 @@ /******************************************************************** * COPYRIGHT: - * Copyright (c) 1997-2004, International Business Machines Corporation and + * Copyright (c) 1997-2010, International Business Machines Corporation and * others. All Rights Reserved. ********************************************************************/ /******************************************************************************** @@ -16,7 +16,6 @@ /*tests for u_normalization*/ #include "unicode/utypes.h" #include "unicode/unorm.h" -#include "unormimp.h" #include "cintltst.h" #if UCONFIG_NO_NORMALIZATION @@ -59,7 +58,13 @@ TestQuickCheckPerCP(void); static void TestComposition(void); -const static char* canonTests[][3] = { +static void +TestFCD(void); + +static void +TestGetDecomposition(void); + +static const char* const canonTests[][3] = { /* Input*/ /*Decomposed*/ /*Composed*/ { "cat", "cat", "cat" }, { "\\u00e0ardvark", "a\\u0300ardvark", "\\u00e0ardvark", }, @@ -92,10 +97,11 @@ const static char* canonTests[][3] = { { "\\uFF76\\uFF9E", "\\uFF76\\uFF9E", "\\uFF76\\uFF9E" }, /* hw_ka + hw_ten*/ { "\\u30AB\\uFF9E", "\\u30AB\\uFF9E", "\\u30AB\\uFF9E" }, /* ka + hw_ten*/ { "\\uFF76\\u3099", "\\uFF76\\u3099", "\\uFF76\\u3099" }, /* hw_ka + ten*/ - { "A\\u0300\\u0316", "A\\u0316\\u0300", "\\u00C0\\u0316" } /* hw_ka + ten*/ + { "A\\u0300\\u0316", "A\\u0316\\u0300", "\\u00C0\\u0316" }, /* hw_ka + ten*/ + { "", "", "" } }; -const static char* compatTests[][3] = { +static const char* const compatTests[][3] = { /* Input*/ /*Decomposed */ /*Composed*/ { "cat", "cat", "cat" }, @@ -114,157 +120,108 @@ const static char* compatTests[][3] = { /*These two are broken in Unicode 2.1.2 but fixed in 2.1.5 and later*/ { "\\uFF76\\uFF9E", "\\u30AB\\u3099", "\\u30AC" }, /* hw_ka + hw_ten*/ - { "\\u30AB\\uFF9E", "\\u30AB\\u3099", "\\u30AC" } /* ka + hw_ten*/ - + { "\\u30AB\\uFF9E", "\\u30AB\\u3099", "\\u30AC" }, /* ka + hw_ten*/ + { "", "", "" } +}; + +static const char* const fcdTests[][3] = { + /* Added for testing the below-U+0300 prefix of a NUL-terminated string. */ + { "\\u010e\\u0327", "D\\u0327\\u030c", NULL }, /* D-caron + cedilla */ + { "\\u010e", "\\u010e", NULL } /* D-caron */ }; void addNormTest(TestNode** root); void addNormTest(TestNode** root) { - addTest(root, &TestAPI, "tscoll/cnormtst/TestAPI"); - addTest(root, &TestDecomp, "tscoll/cnormtst/TestDecomp"); - addTest(root, &TestCompatDecomp, "tscoll/cnormtst/TestCompatDecomp"); - addTest(root, &TestCanonDecompCompose, "tscoll/cnormtst/TestCanonDecompCompose"); - addTest(root, &TestCompatDecompCompose, "tscoll/cnormtst/CompatDecompCompose"); - addTest(root, &TestNull, "tscoll/cnormtst/TestNull"); - addTest(root, &TestQuickCheck, "tscoll/cnormtst/TestQuickCheck"); - addTest(root, &TestQuickCheckPerCP, "tscoll/cnormtst/TestQuickCheckPerCP"); - addTest(root, &TestIsNormalized, "tscoll/cnormtst/TestIsNormalized"); - addTest(root, &TestCheckFCD, "tscoll/cnormtst/TestCheckFCD"); - addTest(root, &TestNormCoverage, "tscoll/cnormtst/TestNormCoverage"); - addTest(root, &TestConcatenate, "tscoll/cnormtst/TestConcatenate"); - addTest(root, &TestNextPrevious, "tscoll/cnormtst/TestNextPrevious"); - addTest(root, &TestFCNFKCClosure, "tscoll/cnormtst/TestFCNFKCClosure"); - addTest(root, &TestComposition, "tscoll/cnormtst/TestComposition"); + addTest(root, &TestAPI, "tsnorm/cnormtst/TestAPI"); + addTest(root, &TestDecomp, "tsnorm/cnormtst/TestDecomp"); + addTest(root, &TestCompatDecomp, "tsnorm/cnormtst/TestCompatDecomp"); + addTest(root, &TestCanonDecompCompose, "tsnorm/cnormtst/TestCanonDecompCompose"); + addTest(root, &TestCompatDecompCompose, "tsnorm/cnormtst/TestCompatDecompCompose"); + addTest(root, &TestFCD, "tsnorm/cnormtst/TestFCD"); + addTest(root, &TestNull, "tsnorm/cnormtst/TestNull"); + addTest(root, &TestQuickCheck, "tsnorm/cnormtst/TestQuickCheck"); + addTest(root, &TestQuickCheckPerCP, "tsnorm/cnormtst/TestQuickCheckPerCP"); + addTest(root, &TestIsNormalized, "tsnorm/cnormtst/TestIsNormalized"); + addTest(root, &TestCheckFCD, "tsnorm/cnormtst/TestCheckFCD"); + addTest(root, &TestNormCoverage, "tsnorm/cnormtst/TestNormCoverage"); + addTest(root, &TestConcatenate, "tsnorm/cnormtst/TestConcatenate"); + addTest(root, &TestNextPrevious, "tsnorm/cnormtst/TestNextPrevious"); + addTest(root, &TestFCNFKCClosure, "tsnorm/cnormtst/TestFCNFKCClosure"); + addTest(root, &TestComposition, "tsnorm/cnormtst/TestComposition"); + addTest(root, &TestGetDecomposition, "tsnorm/cnormtst/TestGetDecomposition"); } -void TestDecomp() -{ - UErrorCode status = U_ZERO_ERROR; - int32_t x, neededLen, resLen; - UChar *source=NULL, *result=NULL; - status = U_ZERO_ERROR; - resLen=0; - log_verbose("Testing unorm_normalize with Decomp canonical\n"); - for(x=0; x < LENGTHOF(canonTests); x++) +static const char* const modeStrings[]={ + "UNORM_NONE", + "UNORM_NFD", + "UNORM_NFKD", + "UNORM_NFC", + "UNORM_NFKC", + "UNORM_FCD", + "UNORM_MODE_COUNT" +}; + +static void TestNormCases(UNormalizationMode mode, + const char* const cases[][3], int32_t lengthOfCases) { + int32_t x, neededLen, length2; + int32_t expIndex= (mode==UNORM_NFC || mode==UNORM_NFKC) ? 2 : 1; + UChar *source=NULL; + UChar result[16]; + log_verbose("Testing unorm_normalize(%s)\n", modeStrings[mode]); + for(x=0; x < lengthOfCases; x++) { - source=CharsToUChars(canonTests[x][0]); - neededLen= unorm_normalize(source, u_strlen(source), UNORM_NFD, 0, NULL, 0, &status); + UErrorCode status = U_ZERO_ERROR, status2 = U_ZERO_ERROR; + source=CharsToUChars(cases[x][0]); + neededLen= unorm_normalize(source, u_strlen(source), mode, 0, NULL, 0, &status); + length2= unorm_normalize(source, -1, mode, 0, NULL, 0, &status2); + if(neededLen!=length2) { + log_err("ERROR in unorm_normalize(%s)[%d]: " + "preflight length/NUL %d!=%d preflight length/srcLength\n", + modeStrings[mode], (int)x, (int)neededLen, (int)length2); + } if(status==U_BUFFER_OVERFLOW_ERROR) { status=U_ZERO_ERROR; - resLen=neededLen+1; - result=(UChar*)malloc(sizeof(UChar*) * resLen); - unorm_normalize(source, u_strlen(source), UNORM_NFD, 0, result, resLen, &status); } - if(U_FAILURE(status)){ - log_err("ERROR in unorm_normalize at %s: %s\n", austrdup(source), myErrorName(status) ); + length2=unorm_normalize(source, u_strlen(source), mode, 0, result, LENGTHOF(result), &status); + if(U_FAILURE(status) || neededLen!=length2) { + log_data_err("ERROR in unorm_normalize(%s/NUL) at %s: %s - (Are you missing data?)\n", + modeStrings[mode], austrdup(source), myErrorName(status)); } else { - assertEqual(result, canonTests[x][1], x); + assertEqual(result, cases[x][expIndex], x); } - free(result); - free(source); - } -} - -void TestCompatDecomp() -{ - UErrorCode status = U_ZERO_ERROR; - int32_t x, neededLen, resLen; - UChar *source=NULL, *result=NULL; - status = U_ZERO_ERROR; - resLen=0; - log_verbose("Testing unorm_normalize with Decomp compat\n"); - for(x=0; x < LENGTHOF(compatTests); x++) - { - source=CharsToUChars(compatTests[x][0]); - neededLen= unorm_normalize(source, u_strlen(source), UNORM_NFKD, 0, NULL, 0, &status); - if(status==U_BUFFER_OVERFLOW_ERROR) - { - status=U_ZERO_ERROR; - resLen=neededLen+1; - result=(UChar*)malloc(sizeof(UChar*) * resLen); - unorm_normalize(source, u_strlen(source), UNORM_NFKD, 0, result, resLen, &status); - } - if(U_FAILURE(status)){ - log_err("ERROR in unorm_normalize at %s: %s\n", austrdup(source), myErrorName(status) ); + length2=unorm_normalize(source, -1, mode, 0, result, LENGTHOF(result), &status); + if(U_FAILURE(status) || neededLen!=length2) { + log_data_err("ERROR in unorm_normalize(%s/srcLength) at %s: %s - (Are you missing data?)\n", + modeStrings[mode], austrdup(source), myErrorName(status)); } else { - assertEqual(result, compatTests[x][1], x); + assertEqual(result, cases[x][expIndex], x); } - free(result); free(source); } } -void TestCanonDecompCompose() -{ - UErrorCode status = U_ZERO_ERROR; - int32_t x, neededLen, resLen; - UChar *source=NULL, *result=NULL; - status = U_ZERO_ERROR; - resLen=0; - log_verbose("Testing unorm_normalize with Decomp can compose compat\n"); - for(x=0; x < LENGTHOF(canonTests); x++) - { - source=CharsToUChars(canonTests[x][0]); - neededLen= unorm_normalize(source, u_strlen(source), UNORM_NFC, 0, NULL, 0, &status); - if(status==U_BUFFER_OVERFLOW_ERROR) - { - status=U_ZERO_ERROR; - resLen=neededLen+1; - result=(UChar*)malloc(sizeof(UChar*) * resLen); - unorm_normalize(source, u_strlen(source), UNORM_NFC, 0, result, resLen, &status); - } - if(U_FAILURE(status)){ - log_err("ERROR in unorm_normalize at %s: %s\n", austrdup(source),myErrorName(status) ); - } else { - assertEqual(result, canonTests[x][2], x); - } - free(result); - free(source); - } +void TestDecomp() { + TestNormCases(UNORM_NFD, canonTests, LENGTHOF(canonTests)); } -void TestCompatDecompCompose() -{ - UErrorCode status = U_ZERO_ERROR; - int32_t x, neededLen, resLen; - UChar *source=NULL, *result=NULL; - status = U_ZERO_ERROR; - resLen=0; - log_verbose("Testing unorm_normalize with compat decomp compose can\n"); - for(x=0; x < LENGTHOF(compatTests); x++) - { - source=CharsToUChars(compatTests[x][0]); - neededLen= unorm_normalize(source, u_strlen(source), UNORM_NFKC, 0, NULL, 0, &status); - if(status==U_BUFFER_OVERFLOW_ERROR) - { - status=U_ZERO_ERROR; - resLen=neededLen+1; - result=(UChar*)malloc(sizeof(UChar*) * resLen); - unorm_normalize(source, u_strlen(source), UNORM_NFKC, 0, result, resLen, &status); - } - if(U_FAILURE(status)){ - log_err("ERROR in unorm_normalize at %s: %s\n", austrdup(source), myErrorName(status) ); - } else { - assertEqual(result, compatTests[x][2], x); - } - free(result); - free(source); - } +void TestCompatDecomp() { + TestNormCases(UNORM_NFKD, compatTests, LENGTHOF(compatTests)); } +void TestCanonDecompCompose() { + TestNormCases(UNORM_NFC, canonTests, LENGTHOF(canonTests)); +} -/* -static void assertEqual(const UChar* result, const UChar* expected, int32_t index) -{ - if(u_strcmp(result, expected)!=0){ - log_err("ERROR in decomposition at index = %d. EXPECTED: %s , GOT: %s\n", index, austrdup(expected), - austrdup(result) ); - } +void TestCompatDecompCompose() { + TestNormCases(UNORM_NFKC, compatTests, LENGTHOF(compatTests)); +} + +void TestFCD() { + TestNormCases(UNORM_FCD, fcdTests, LENGTHOF(fcdTests)); } -*/ static void assertEqual(const UChar* result, const char* expected, int32_t index) { @@ -297,7 +254,7 @@ static void TestNull_check(UChar *src, int32_t srcLen, len = unorm_normalize(src, srcLen, mode, 0, result, 50, &status); if(U_FAILURE(status)) { - log_err("unorm_normalize(%s) with 0x0000 failed: %s\n", name, u_errorName(status)); + log_data_err("unorm_normalize(%s) with 0x0000 failed: %s - (Are you missing data?)\n", name, u_errorName(status)); } else if (len != expLen) { log_err("unorm_normalize(%s) with 0x0000 failed: Expected len %d, got %d\n", name, expLen, len); } @@ -423,7 +380,7 @@ static void TestQuickCheckResultYES() { if (unorm_quickCheck(&cp, 1, UNORM_NFD, &error) != UNORM_YES) { - log_err("ERROR in NFD quick check at U+%04x\n", cp); + log_data_err("ERROR in NFD quick check at U+%04x - (Are you missing data?)\n", cp); return; } if (unorm_quickCheck(&cp, 1, UNORM_NFC, &error) != @@ -494,7 +451,7 @@ static void TestQuickCheckResultMAYBE() if (unorm_quickCheck(&(CPNFC[count]), 1, UNORM_NFC, &error) != UNORM_MAYBE) { - log_err("ERROR in NFC quick check at U+%04x\n", CPNFC[count]); + log_data_err("ERROR in NFC quick check at U+%04x - (Are you missing data?)\n", CPNFC[count]); return; } if (unorm_quickCheck(&(CPNFKC[count]), 1, UNORM_NFKC, &error) != @@ -520,7 +477,7 @@ static void TestQuickCheckStringResult() if (unorm_quickCheck(d, u_strlen(d), UNORM_NFD, &error) != UNORM_YES) { - log_err("ERROR in NFD quick check for string at count %d\n", count); + log_data_err("ERROR in NFD quick check for string at count %d - (Are you missing data?)\n", count); return; } @@ -592,7 +549,7 @@ static void TestIsNormalized(void) { /* normal case with length>=0 (length -1 used for special cases below) */ errorCode=U_ZERO_ERROR; if(!unorm_isNormalized(notNFC[0]+2, 1, UNORM_NFC, &errorCode) || U_FAILURE(errorCode)) { - log_err("error: !isNormalized(, NFC) (%s)\n", u_errorName(errorCode)); + log_data_err("error: !isNormalized(, NFC) (%s) - (Are you missing data?)\n", u_errorName(errorCode)); } /* incoming U_FAILURE */ @@ -606,31 +563,31 @@ static void TestIsNormalized(void) { errorCode=U_ZERO_ERROR; (void)unorm_isNormalized(NULL, 1, UNORM_NFC, &errorCode); if(errorCode!=U_ILLEGAL_ARGUMENT_ERROR) { - log_err("error: isNormalized(NULL) did not set U_ILLEGAL_ARGUMENT_ERROR but %s\n", u_errorName(errorCode)); + log_data_err("error: isNormalized(NULL) did not set U_ILLEGAL_ARGUMENT_ERROR but %s - (Are you missing data?)\n", u_errorName(errorCode)); } /* bad length */ errorCode=U_ZERO_ERROR; (void)unorm_isNormalized(notNFC[0]+2, -2, UNORM_NFC, &errorCode); if(errorCode!=U_ILLEGAL_ARGUMENT_ERROR) { - log_err("error: isNormalized([-2]) did not set U_ILLEGAL_ARGUMENT_ERROR but %s\n", u_errorName(errorCode)); + log_data_err("error: isNormalized([-2]) did not set U_ILLEGAL_ARGUMENT_ERROR but %s - (Are you missing data?)\n", u_errorName(errorCode)); } /* specific cases */ for(i=0; i)=%ld failed with out[]=U+%04x U+%04x U+%04x U+%04x\n", length, out[0], out[1], out[2], out[3]); return; } + length=unorm_normalize(NULL, 0, UNORM_NFC, 0, NULL, 0, &errorCode); + if(U_FAILURE(errorCode)) { + log_err("unorm_normalize(src NULL[0], NFC, dest NULL[0])=%ld failed with %s\n", (long)length, u_errorName(errorCode)); + return; + } + length=unorm_normalize(NULL, 0, UNORM_NFC, 0, out, 20, &errorCode); + if(U_FAILURE(errorCode)) { + log_err("unorm_normalize(src NULL[0], NFC, dest out[20])=%ld failed with %s\n", (long)length, u_errorName(errorCode)); + return; + } } /* test cases to improve test code coverage */ @@ -788,7 +755,7 @@ enum { static void TestNormCoverage() { - static UChar input[2000], expect[3000], output[3000]; + UChar input[1000], expect[1000], output[1000]; UErrorCode errorCode; int32_t i, length, inLength, expectLength, hangulPrefixLength, preflightLength; @@ -857,23 +824,23 @@ TestNormCoverage() { /* quick checks */ errorCode=U_ZERO_ERROR; if(UNORM_NO!=unorm_quickCheck(input, inLength, UNORM_NFD, &errorCode) || U_FAILURE(errorCode)) { - log_err("error unorm_quickCheck(long input, UNORM_NFD)!=NO (%s)\n", u_errorName(errorCode)); + log_data_err("error unorm_quickCheck(long input, UNORM_NFD)!=NO (%s) - (Are you missing data?)\n", u_errorName(errorCode)); } errorCode=U_ZERO_ERROR; if(UNORM_NO!=unorm_quickCheck(input, inLength, UNORM_NFKD, &errorCode) || U_FAILURE(errorCode)) { - log_err("error unorm_quickCheck(long input, UNORM_NFKD)!=NO (%s)\n", u_errorName(errorCode)); + log_data_err("error unorm_quickCheck(long input, UNORM_NFKD)!=NO (%s) - (Are you missing data?)\n", u_errorName(errorCode)); } errorCode=U_ZERO_ERROR; if(UNORM_NO!=unorm_quickCheck(input, inLength, UNORM_NFC, &errorCode) || U_FAILURE(errorCode)) { - log_err("error unorm_quickCheck(long input, UNORM_NFC)!=NO (%s)\n", u_errorName(errorCode)); + log_data_err("error unorm_quickCheck(long input, UNORM_NFC)!=NO (%s) - (Are you missing data?)\n", u_errorName(errorCode)); } errorCode=U_ZERO_ERROR; if(UNORM_NO!=unorm_quickCheck(input, inLength, UNORM_NFKC, &errorCode) || U_FAILURE(errorCode)) { - log_err("error unorm_quickCheck(long input, UNORM_NFKC)!=NO (%s)\n", u_errorName(errorCode)); + log_data_err("error unorm_quickCheck(long input, UNORM_NFKC)!=NO (%s) - (Are you missing data?)\n", u_errorName(errorCode)); } errorCode=U_ZERO_ERROR; if(UNORM_NO!=unorm_quickCheck(input, inLength, UNORM_FCD, &errorCode) || U_FAILURE(errorCode)) { - log_err("error unorm_quickCheck(long input, UNORM_FCD)!=NO (%s)\n", u_errorName(errorCode)); + log_data_err("error unorm_quickCheck(long input, UNORM_FCD)!=NO (%s) - (Are you missing data?)\n", u_errorName(errorCode)); } /* NFKC */ @@ -923,7 +890,7 @@ TestNormCoverage() { output, 100, /* too short */ &errorCode); if(errorCode!=U_BUFFER_OVERFLOW_ERROR) { - log_err("error unorm_normalize(long input, output too short, UNORM_NFKC) did not overflow but %s\n", u_errorName(errorCode)); + 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)); } /* real NFKC */ @@ -933,7 +900,7 @@ TestNormCoverage() { output, sizeof(output)/U_SIZEOF_UCHAR, &errorCode); if(U_FAILURE(errorCode)) { - log_err("error unorm_normalize(long input, UNORM_NFKC) failed with %s\n", u_errorName(errorCode)); + log_data_err("error unorm_normalize(long input, UNORM_NFKC) failed with %s - (Are you missing data?)\n", u_errorName(errorCode)); } else if(length!=expectLength || u_memcmp(output, expect, length)!=0) { log_err("error unorm_normalize(long input, UNORM_NFKC) produced wrong result\n"); for(i=0; igetIndex(iter, UITER_CURRENT); if(U_FAILURE(errorCode)) { - log_err("error unorm iteration (next/previous %d %s)[%d]: %s\n", + log_data_err("error unorm iteration (next/previous %d %s)[%d]: %s - (Are you missing data?)\n", forward, _modeString[mode], i, u_errorName(errorCode)); return; } @@ -1271,7 +1238,7 @@ TestNextPrevious() { UNORM_NFD, 0, TRUE, NULL, &errorCode); if(U_FAILURE(errorCode) || length!=2 || buffer[0]!=nfd[2] || buffer[1]!=nfd[3]) { - log_err("error unorm_next(without needed) %s\n", u_errorName(errorCode)); + log_data_err("error unorm_next(without needed) %s - (Are you missing data?)\n", u_errorName(errorCode)); return; } @@ -1334,17 +1301,6 @@ TestNextPrevious() { log_err("error unorm_next(U_MISPLACED_QUANTIFIER) %s\n", u_errorName(errorCode)); return; } - - /* missing pErrorCode */ - buffer[0]=5; - iter.index=1; - length=unorm_next(&iter, buffer, sizeof(buffer)/U_SIZEOF_UCHAR, - UNORM_NFD, 0, TRUE, NULL, - NULL); - if(iter.index!=1 || buffer[0]!=5) { - log_err("error unorm_next(pErrorCode==NULL) %s\n", u_errorName(errorCode)); - return; - } } static void @@ -1353,6 +1309,8 @@ TestFCNFKCClosure(void) { UChar32 c; const UChar s[6]; } tests[]={ + { 0x00C4, { 0 } }, + { 0x00E4, { 0 } }, { 0x037A, { 0x0020, 0x03B9, 0 } }, { 0x03D2, { 0x03C5, 0 } }, { 0x20A8, { 0x0072, 0x0073, 0 } }, @@ -1374,7 +1332,7 @@ TestFCNFKCClosure(void) { errorCode=U_ZERO_ERROR; length=u_getFC_NFKC_Closure(tests[i].c, buffer, LENGTHOF(buffer), &errorCode); if(U_FAILURE(errorCode) || length!=u_strlen(buffer) || 0!=u_strcmp(tests[i].s, buffer)) { - log_err("u_getFC_NFKC_Closure(U+%04lx) is wrong (%s)\n", tests[i].c, u_errorName(errorCode)); + log_data_err("u_getFC_NFKC_Closure(U+%04lx) is wrong (%s) - (Are you missing data?)\n", tests[i].c, u_errorName(errorCode)); } } @@ -1397,7 +1355,7 @@ TestQuickCheckPerCP() { UChar32 c, lead, trail; UChar s[U16_MAX_LENGTH], nfd[16]; int32_t length, lccc1, lccc2, tccc1, tccc2; - UNormalizationCheckResult qc1, qc2; + int32_t qc1, qc2; if( u_getIntPropertyMaxValue(UCHAR_NFD_QUICK_CHECK)!=(int32_t)UNORM_YES || @@ -1423,29 +1381,30 @@ TestQuickCheckPerCP() { qc1=u_getIntPropertyValue(c, UCHAR_NFC_QUICK_CHECK); qc2=unorm_quickCheck(s, length, UNORM_NFC, &errorCode); if(qc1!=qc2) { - log_err("u_getIntPropertyValue(NFC)=%d != %d=unorm_quickCheck(NFC) for U+%04x\n", qc1, qc2, c); + log_data_err("u_getIntPropertyValue(NFC)=%d != %d=unorm_quickCheck(NFC) for U+%04x - (Are you missing data?)\n", qc1, qc2, c); } qc1=u_getIntPropertyValue(c, UCHAR_NFD_QUICK_CHECK); qc2=unorm_quickCheck(s, length, UNORM_NFD, &errorCode); if(qc1!=qc2) { - log_err("u_getIntPropertyValue(NFD)=%d != %d=unorm_quickCheck(NFD) for U+%04x\n", qc1, qc2, c); + log_data_err("u_getIntPropertyValue(NFD)=%d != %d=unorm_quickCheck(NFD) for U+%04x - (Are you missing data?)\n", qc1, qc2, c); } qc1=u_getIntPropertyValue(c, UCHAR_NFKC_QUICK_CHECK); qc2=unorm_quickCheck(s, length, UNORM_NFKC, &errorCode); if(qc1!=qc2) { - log_err("u_getIntPropertyValue(NFKC)=%d != %d=unorm_quickCheck(NFKC) for U+%04x\n", qc1, qc2, c); + log_data_err("u_getIntPropertyValue(NFKC)=%d != %d=unorm_quickCheck(NFKC) for U+%04x - (Are you missing data?)\n", qc1, qc2, c); } qc1=u_getIntPropertyValue(c, UCHAR_NFKD_QUICK_CHECK); qc2=unorm_quickCheck(s, length, UNORM_NFKD, &errorCode); if(qc1!=qc2) { - log_err("u_getIntPropertyValue(NFKD)=%d != %d=unorm_quickCheck(NFKD) for U+%04x\n", qc1, qc2, c); + log_data_err("u_getIntPropertyValue(NFKD)=%d != %d=unorm_quickCheck(NFKD) for U+%04x - (Are you missing data?)\n", qc1, qc2, c); } length=unorm_normalize(s, length, UNORM_NFD, 0, nfd, LENGTHOF(nfd), &errorCode); - U16_GET(nfd, 0, 0, length, lead); + /* length-length == 0 is used to get around a compiler warning. */ + U16_GET(nfd, 0, length-length, length, lead); U16_GET(nfd, 0, length-1, length, trail); lccc1=u_getIntPropertyValue(c, UCHAR_LEAD_CANONICAL_COMBINING_CLASS); @@ -1477,19 +1436,15 @@ TestComposition(void) { } cases[]={ /* * special cases for UAX #15 bug - * see Unicode Public Review Issue #29 - * at http://www.unicode.org/review/resolved-pri.html#pri29 + * see Unicode Corrigendum #5: Normalization Idempotency + * at http://unicode.org/versions/corrigendum5.html + * (was Public Review Issue #29) */ { UNORM_NFC, 0, { 0x1100, 0x0300, 0x1161, 0x0327 }, { 0x1100, 0x0300, 0x1161, 0x0327 } }, { UNORM_NFC, 0, { 0x1100, 0x0300, 0x1161, 0x0327, 0x11a8 }, { 0x1100, 0x0300, 0x1161, 0x0327, 0x11a8 } }, { UNORM_NFC, 0, { 0xac00, 0x0300, 0x0327, 0x11a8 }, { 0xac00, 0x0327, 0x0300, 0x11a8 } }, { UNORM_NFC, 0, { 0x0b47, 0x0300, 0x0b3e }, { 0x0b47, 0x0300, 0x0b3e } }, - { UNORM_NFC, UNORM_BEFORE_PRI_29, { 0x1100, 0x0300, 0x1161, 0x0327 }, { 0xac00, 0x0300, 0x0327 } }, - { UNORM_NFC, UNORM_BEFORE_PRI_29, { 0x1100, 0x0300, 0x1161, 0x0327, 0x11a8 }, { 0xac01, 0x0300, 0x0327 } }, - { UNORM_NFC, UNORM_BEFORE_PRI_29, { 0xac00, 0x0300, 0x0327, 0x11a8 }, { 0xac01, 0x0327, 0x0300 } }, - { UNORM_NFC, UNORM_BEFORE_PRI_29, { 0x0b47, 0x0300, 0x0b3e }, { 0x0b4b, 0x0300 } } - /* TODO: add test cases for UNORM_FCC here (j2151) */ }; @@ -1508,9 +1463,52 @@ TestComposition(void) { length!=u_strlen(cases[i].expect) || 0!=u_memcmp(output, cases[i].expect, length) ) { - log_err("unexpected result for case %d\n", i); + log_data_err("unexpected result for case %d - (Are you missing data?)\n", i); } } } +static void +TestGetDecomposition() { + UChar decomp[32]; + int32_t length; + + UErrorCode errorCode=U_ZERO_ERROR; + const UNormalizer2 *n2=unorm2_getInstance(NULL, "nfc", UNORM2_COMPOSE_CONTIGUOUS, &errorCode); + if(U_FAILURE(errorCode)) { + log_err_status(errorCode, "unorm2_getInstance(nfc/FCC) failed: %s\n", u_errorName(errorCode)); + return; + } + + length=unorm2_getDecomposition(n2, 0x20, decomp, LENGTHOF(decomp), &errorCode); + if(U_FAILURE(errorCode) || length>=0) { + log_err("unorm2_getDecomposition(space) failed\n"); + } + errorCode=U_ZERO_ERROR; + length=unorm2_getDecomposition(n2, 0xe4, decomp, LENGTHOF(decomp), &errorCode); + if(U_FAILURE(errorCode) || length!=2 || decomp[0]!=0x61 || decomp[1]!=0x308 || decomp[2]!=0) { + log_err("unorm2_getDecomposition(a-umlaut) failed\n"); + } + errorCode=U_ZERO_ERROR; + length=unorm2_getDecomposition(n2, 0xac01, decomp, LENGTHOF(decomp), &errorCode); + if(U_FAILURE(errorCode) || length!=3 || decomp[0]!=0x1100 || decomp[1]!=0x1161 || decomp[2]!=0x11a8 || decomp[3]!=0) { + log_err("unorm2_getDecomposition(Hangul syllable U+AC01) failed\n"); + } + errorCode=U_ZERO_ERROR; + length=unorm2_getDecomposition(n2, 0xac01, NULL, 0, &errorCode); + if(errorCode!=U_BUFFER_OVERFLOW_ERROR || length!=3) { + log_err("unorm2_getDecomposition(Hangul syllable U+AC01) overflow failed\n"); + } + errorCode=U_ZERO_ERROR; + length=unorm2_getDecomposition(n2, 0xac01, decomp, -1, &errorCode); + if(errorCode!=U_ILLEGAL_ARGUMENT_ERROR) { + log_err("unorm2_getDecomposition(capacity<0) failed\n"); + } + errorCode=U_ZERO_ERROR; + length=unorm2_getDecomposition(n2, 0xac01, NULL, 4, &errorCode); + if(errorCode!=U_ILLEGAL_ARGUMENT_ERROR) { + log_err("unorm2_getDecomposition(decomposition=NULL) failed\n"); + } +} + #endif /* #if !UCONFIG_NO_NORMALIZATION */