ICU-7703 fix unorm_normalize(src, length=-1) bug and allow src=NULL if length=0
X-SVN-Rev: 28115
This commit is contained in:
parent
eb3c9d6b4d
commit
77543b3e58
@ -630,22 +630,28 @@ unorm2_normalize(const UNormalizer2 *norm2,
|
|||||||
if(U_FAILURE(*pErrorCode)) {
|
if(U_FAILURE(*pErrorCode)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if(src==NULL || length<-1 || capacity<0 || (dest==NULL && capacity>0) || src==dest) {
|
if( (src==NULL && length!=0) || length<-1 ||
|
||||||
|
capacity<0 || (dest==NULL && capacity>0) ||
|
||||||
|
(src==dest && src!=NULL)
|
||||||
|
) {
|
||||||
*pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
|
*pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
UnicodeString destString(dest, 0, capacity);
|
UnicodeString destString(dest, 0, capacity);
|
||||||
const Normalizer2 *n2=(const Normalizer2 *)norm2;
|
// length==0: Nothing to do, and n2wi->normalize(NULL, NULL, buffer, ...) would crash.
|
||||||
const Normalizer2WithImpl *n2wi=dynamic_cast<const Normalizer2WithImpl *>(n2);
|
if(length!=0) {
|
||||||
if(n2wi!=NULL) {
|
const Normalizer2 *n2=(const Normalizer2 *)norm2;
|
||||||
// Avoid duplicate argument checking and support NUL-terminated src.
|
const Normalizer2WithImpl *n2wi=dynamic_cast<const Normalizer2WithImpl *>(n2);
|
||||||
ReorderingBuffer buffer(n2wi->impl, destString);
|
if(n2wi!=NULL) {
|
||||||
if(buffer.init(length, *pErrorCode)) {
|
// Avoid duplicate argument checking and support NUL-terminated src.
|
||||||
n2wi->normalize(src, length>=0 ? src+length : NULL, buffer, *pErrorCode);
|
ReorderingBuffer buffer(n2wi->impl, destString);
|
||||||
|
if(buffer.init(length, *pErrorCode)) {
|
||||||
|
n2wi->normalize(src, length>=0 ? src+length : NULL, buffer, *pErrorCode);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
UnicodeString srcString(length<0, src, length);
|
||||||
|
n2->normalize(srcString, destString, *pErrorCode);
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
UnicodeString srcString(length<0, src, length);
|
|
||||||
n2->normalize(srcString, destString, *pErrorCode);
|
|
||||||
}
|
}
|
||||||
return destString.extract(dest, capacity, *pErrorCode);
|
return destString.extract(dest, capacity, *pErrorCode);
|
||||||
}
|
}
|
||||||
@ -659,29 +665,32 @@ normalizeSecondAndAppend(const UNormalizer2 *norm2,
|
|||||||
if(U_FAILURE(*pErrorCode)) {
|
if(U_FAILURE(*pErrorCode)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if( second==NULL || secondLength<-1 ||
|
if( (second==NULL && secondLength!=0) || secondLength<-1 ||
|
||||||
firstCapacity<0 || (first==NULL && firstCapacity>0) || firstLength<-1 ||
|
firstCapacity<0 || (first==NULL && firstCapacity>0) || firstLength<-1 ||
|
||||||
first==second
|
(first==second && first!=NULL)
|
||||||
) {
|
) {
|
||||||
*pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
|
*pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
UnicodeString firstString(first, firstLength, firstCapacity);
|
UnicodeString firstString(first, firstLength, firstCapacity);
|
||||||
const Normalizer2 *n2=(const Normalizer2 *)norm2;
|
// secondLength==0: Nothing to do, and n2wi->normalizeAndAppend(NULL, NULL, buffer, ...) would crash.
|
||||||
const Normalizer2WithImpl *n2wi=dynamic_cast<const Normalizer2WithImpl *>(n2);
|
if(secondLength!=0) {
|
||||||
if(n2wi!=NULL) {
|
const Normalizer2 *n2=(const Normalizer2 *)norm2;
|
||||||
// Avoid duplicate argument checking and support NUL-terminated src.
|
const Normalizer2WithImpl *n2wi=dynamic_cast<const Normalizer2WithImpl *>(n2);
|
||||||
ReorderingBuffer buffer(n2wi->impl, firstString);
|
if(n2wi!=NULL) {
|
||||||
if(buffer.init(firstLength+secondLength+1, *pErrorCode)) { // destCapacity>=-1
|
// Avoid duplicate argument checking and support NUL-terminated src.
|
||||||
n2wi->normalizeAndAppend(second, secondLength>=0 ? second+secondLength : NULL,
|
ReorderingBuffer buffer(n2wi->impl, firstString);
|
||||||
doNormalize, buffer, *pErrorCode);
|
if(buffer.init(firstLength+secondLength+1, *pErrorCode)) { // destCapacity>=-1
|
||||||
}
|
n2wi->normalizeAndAppend(second, secondLength>=0 ? second+secondLength : NULL,
|
||||||
} else {
|
doNormalize, buffer, *pErrorCode);
|
||||||
UnicodeString secondString(secondLength<0, second, secondLength);
|
}
|
||||||
if(doNormalize) {
|
|
||||||
n2->normalizeSecondAndAppend(firstString, secondString, *pErrorCode);
|
|
||||||
} else {
|
} else {
|
||||||
n2->append(firstString, secondString, *pErrorCode);
|
UnicodeString secondString(secondLength<0, second, secondLength);
|
||||||
|
if(doNormalize) {
|
||||||
|
n2->normalizeSecondAndAppend(firstString, secondString, *pErrorCode);
|
||||||
|
} else {
|
||||||
|
n2->append(firstString, secondString, *pErrorCode);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return firstString.extract(first, firstCapacity, *pErrorCode);
|
return firstString.extract(first, firstCapacity, *pErrorCode);
|
||||||
@ -716,7 +725,7 @@ unorm2_isNormalized(const UNormalizer2 *norm2,
|
|||||||
if(U_FAILURE(*pErrorCode)) {
|
if(U_FAILURE(*pErrorCode)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if(s==NULL || length<-1) {
|
if((s==NULL && length!=0) || length<-1) {
|
||||||
*pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
|
*pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -731,7 +740,7 @@ unorm2_quickCheck(const UNormalizer2 *norm2,
|
|||||||
if(U_FAILURE(*pErrorCode)) {
|
if(U_FAILURE(*pErrorCode)) {
|
||||||
return UNORM_NO;
|
return UNORM_NO;
|
||||||
}
|
}
|
||||||
if(s==NULL || length<-1) {
|
if((s==NULL && length!=0) || length<-1) {
|
||||||
*pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
|
*pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
|
||||||
return UNORM_NO;
|
return UNORM_NO;
|
||||||
}
|
}
|
||||||
@ -746,7 +755,7 @@ unorm2_spanQuickCheckYes(const UNormalizer2 *norm2,
|
|||||||
if(U_FAILURE(*pErrorCode)) {
|
if(U_FAILURE(*pErrorCode)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if(s==NULL || length<-1) {
|
if((s==NULL && length!=0) || length<-1) {
|
||||||
*pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
|
*pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -643,8 +643,8 @@ int32_t Normalizer2Impl::combine(const uint16_t *list, UChar32 trail) {
|
|||||||
// trail character is 3400..10FFFF
|
// trail character is 3400..10FFFF
|
||||||
// result entry has 3 units
|
// result entry has 3 units
|
||||||
key1=(uint16_t)(COMP_1_TRAIL_LIMIT+
|
key1=(uint16_t)(COMP_1_TRAIL_LIMIT+
|
||||||
((trail>>COMP_1_TRAIL_SHIFT))&
|
(((trail>>COMP_1_TRAIL_SHIFT))&
|
||||||
~COMP_1_TRIPLE);
|
~COMP_1_TRIPLE));
|
||||||
uint16_t key2=(uint16_t)(trail<<COMP_2_TRAIL_SHIFT);
|
uint16_t key2=(uint16_t)(trail<<COMP_2_TRAIL_SHIFT);
|
||||||
uint16_t secondUnit;
|
uint16_t secondUnit;
|
||||||
for(;;) {
|
for(;;) {
|
||||||
@ -854,17 +854,6 @@ Normalizer2Impl::compose(const UChar *src, const UChar *limit,
|
|||||||
UBool doCompose,
|
UBool doCompose,
|
||||||
ReorderingBuffer &buffer,
|
ReorderingBuffer &buffer,
|
||||||
UErrorCode &errorCode) const {
|
UErrorCode &errorCode) const {
|
||||||
UChar32 minNoMaybeCP=minCompNoMaybeCP;
|
|
||||||
if(limit==NULL) {
|
|
||||||
src=copyLowPrefixFromNulTerminated(src, minNoMaybeCP,
|
|
||||||
doCompose ? &buffer : NULL,
|
|
||||||
errorCode);
|
|
||||||
if(U_FAILURE(errorCode)) {
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
limit=u_strchr(src, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* prevBoundary points to the last character before the current one
|
* prevBoundary points to the last character before the current one
|
||||||
* that has a composition boundary before it with ccc==0 and quick check "yes".
|
* that has a composition boundary before it with ccc==0 and quick check "yes".
|
||||||
@ -878,6 +867,21 @@ Normalizer2Impl::compose(const UChar *src, const UChar *limit,
|
|||||||
* must correspond 1:1 to destination units at the end of the destination buffer.
|
* must correspond 1:1 to destination units at the end of the destination buffer.
|
||||||
*/
|
*/
|
||||||
const UChar *prevBoundary=src;
|
const UChar *prevBoundary=src;
|
||||||
|
UChar32 minNoMaybeCP=minCompNoMaybeCP;
|
||||||
|
if(limit==NULL) {
|
||||||
|
src=copyLowPrefixFromNulTerminated(src, minNoMaybeCP,
|
||||||
|
doCompose ? &buffer : NULL,
|
||||||
|
errorCode);
|
||||||
|
if(U_FAILURE(errorCode)) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
if(prevBoundary<src) {
|
||||||
|
// Set prevBoundary to the last character in the prefix.
|
||||||
|
prevBoundary=src-1;
|
||||||
|
}
|
||||||
|
limit=u_strchr(src, 0);
|
||||||
|
}
|
||||||
|
|
||||||
const UChar *prevSrc;
|
const UChar *prevSrc;
|
||||||
UChar32 c=0;
|
UChar32 c=0;
|
||||||
uint16_t norm16=0;
|
uint16_t norm16=0;
|
||||||
@ -1108,18 +1112,22 @@ const UChar *
|
|||||||
Normalizer2Impl::composeQuickCheck(const UChar *src, const UChar *limit,
|
Normalizer2Impl::composeQuickCheck(const UChar *src, const UChar *limit,
|
||||||
UBool onlyContiguous,
|
UBool onlyContiguous,
|
||||||
UNormalizationCheckResult *pQCResult) const {
|
UNormalizationCheckResult *pQCResult) const {
|
||||||
UChar32 minNoMaybeCP=minCompNoMaybeCP;
|
|
||||||
if(limit==NULL) {
|
|
||||||
UErrorCode errorCode=U_ZERO_ERROR;
|
|
||||||
src=copyLowPrefixFromNulTerminated(src, minNoMaybeCP, NULL, errorCode);
|
|
||||||
limit=u_strchr(src, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* prevBoundary points to the last character before the current one
|
* prevBoundary points to the last character before the current one
|
||||||
* that has a composition boundary before it with ccc==0 and quick check "yes".
|
* that has a composition boundary before it with ccc==0 and quick check "yes".
|
||||||
*/
|
*/
|
||||||
const UChar *prevBoundary=src;
|
const UChar *prevBoundary=src;
|
||||||
|
UChar32 minNoMaybeCP=minCompNoMaybeCP;
|
||||||
|
if(limit==NULL) {
|
||||||
|
UErrorCode errorCode=U_ZERO_ERROR;
|
||||||
|
src=copyLowPrefixFromNulTerminated(src, minNoMaybeCP, NULL, errorCode);
|
||||||
|
if(prevBoundary<src) {
|
||||||
|
// Set prevBoundary to the last character in the prefix.
|
||||||
|
prevBoundary=src-1;
|
||||||
|
}
|
||||||
|
limit=u_strchr(src, 0);
|
||||||
|
}
|
||||||
|
|
||||||
const UChar *prevSrc;
|
const UChar *prevSrc;
|
||||||
UChar32 c=0;
|
UChar32 c=0;
|
||||||
uint16_t norm16=0;
|
uint16_t norm16=0;
|
||||||
@ -1450,11 +1458,24 @@ const UChar *
|
|||||||
Normalizer2Impl::makeFCD(const UChar *src, const UChar *limit,
|
Normalizer2Impl::makeFCD(const UChar *src, const UChar *limit,
|
||||||
ReorderingBuffer *buffer,
|
ReorderingBuffer *buffer,
|
||||||
UErrorCode &errorCode) const {
|
UErrorCode &errorCode) const {
|
||||||
|
// Tracks the last FCD-safe boundary, before lccc=0 or after properly-ordered tccc<=1.
|
||||||
|
// Similar to the prevBoundary in the compose() implementation.
|
||||||
|
const UChar *prevBoundary=src;
|
||||||
|
int32_t prevFCD16=0;
|
||||||
if(limit==NULL) {
|
if(limit==NULL) {
|
||||||
src=copyLowPrefixFromNulTerminated(src, MIN_CCC_LCCC_CP, buffer, errorCode);
|
src=copyLowPrefixFromNulTerminated(src, MIN_CCC_LCCC_CP, buffer, errorCode);
|
||||||
if(U_FAILURE(errorCode)) {
|
if(U_FAILURE(errorCode)) {
|
||||||
return src;
|
return src;
|
||||||
}
|
}
|
||||||
|
if(prevBoundary<src) {
|
||||||
|
prevBoundary=src;
|
||||||
|
// We know that the previous character's lccc==0.
|
||||||
|
// Fetching the fcd16 value was deferred for this below-U+0300 code point.
|
||||||
|
prevFCD16=getFCD16FromSingleLead(*(src-1));
|
||||||
|
if(prevFCD16>1) {
|
||||||
|
--prevBoundary;
|
||||||
|
}
|
||||||
|
}
|
||||||
limit=u_strchr(src, 0);
|
limit=u_strchr(src, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1466,12 +1487,8 @@ Normalizer2Impl::makeFCD(const UChar *src, const UChar *limit,
|
|||||||
|
|
||||||
const UTrie2 *trie=fcdTrie();
|
const UTrie2 *trie=fcdTrie();
|
||||||
|
|
||||||
// Tracks the last FCD-safe boundary, before lccc=0 or after properly-ordered tccc<=1.
|
|
||||||
// Similar to the prevBoundary in the compose() implementation.
|
|
||||||
const UChar *prevBoundary=src;
|
|
||||||
const UChar *prevSrc;
|
const UChar *prevSrc;
|
||||||
UChar32 c=0;
|
UChar32 c=0;
|
||||||
int32_t prevFCD16=0;
|
|
||||||
uint16_t fcd16=0;
|
uint16_t fcd16=0;
|
||||||
|
|
||||||
for(;;) {
|
for(;;) {
|
||||||
|
@ -58,7 +58,10 @@ TestQuickCheckPerCP(void);
|
|||||||
static void
|
static void
|
||||||
TestComposition(void);
|
TestComposition(void);
|
||||||
|
|
||||||
const static char* canonTests[][3] = {
|
static void
|
||||||
|
TestFCD(void);
|
||||||
|
|
||||||
|
static const char* const canonTests[][3] = {
|
||||||
/* Input*/ /*Decomposed*/ /*Composed*/
|
/* Input*/ /*Decomposed*/ /*Composed*/
|
||||||
{ "cat", "cat", "cat" },
|
{ "cat", "cat", "cat" },
|
||||||
{ "\\u00e0ardvark", "a\\u0300ardvark", "\\u00e0ardvark", },
|
{ "\\u00e0ardvark", "a\\u0300ardvark", "\\u00e0ardvark", },
|
||||||
@ -91,10 +94,11 @@ const static char* canonTests[][3] = {
|
|||||||
{ "\\uFF76\\uFF9E", "\\uFF76\\uFF9E", "\\uFF76\\uFF9E" }, /* hw_ka + hw_ten*/
|
{ "\\uFF76\\uFF9E", "\\uFF76\\uFF9E", "\\uFF76\\uFF9E" }, /* hw_ka + hw_ten*/
|
||||||
{ "\\u30AB\\uFF9E", "\\u30AB\\uFF9E", "\\u30AB\\uFF9E" }, /* ka + hw_ten*/
|
{ "\\u30AB\\uFF9E", "\\u30AB\\uFF9E", "\\u30AB\\uFF9E" }, /* ka + hw_ten*/
|
||||||
{ "\\uFF76\\u3099", "\\uFF76\\u3099", "\\uFF76\\u3099" }, /* hw_ka + 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*/
|
/* Input*/ /*Decomposed */ /*Composed*/
|
||||||
{ "cat", "cat", "cat" },
|
{ "cat", "cat", "cat" },
|
||||||
|
|
||||||
@ -113,8 +117,14 @@ const static char* compatTests[][3] = {
|
|||||||
|
|
||||||
/*These two are broken in Unicode 2.1.2 but fixed in 2.1.5 and later*/
|
/*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*/
|
{ "\\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);
|
||||||
@ -125,7 +135,8 @@ void addNormTest(TestNode** root)
|
|||||||
addTest(root, &TestDecomp, "tsnorm/cnormtst/TestDecomp");
|
addTest(root, &TestDecomp, "tsnorm/cnormtst/TestDecomp");
|
||||||
addTest(root, &TestCompatDecomp, "tsnorm/cnormtst/TestCompatDecomp");
|
addTest(root, &TestCompatDecomp, "tsnorm/cnormtst/TestCompatDecomp");
|
||||||
addTest(root, &TestCanonDecompCompose, "tsnorm/cnormtst/TestCanonDecompCompose");
|
addTest(root, &TestCanonDecompCompose, "tsnorm/cnormtst/TestCanonDecompCompose");
|
||||||
addTest(root, &TestCompatDecompCompose, "tsnorm/cnormtst/CompatDecompCompose");
|
addTest(root, &TestCompatDecompCompose, "tsnorm/cnormtst/TestCompatDecompCompose");
|
||||||
|
addTest(root, &TestFCD, "tsnorm/cnormtst/TestFCD");
|
||||||
addTest(root, &TestNull, "tsnorm/cnormtst/TestNull");
|
addTest(root, &TestNull, "tsnorm/cnormtst/TestNull");
|
||||||
addTest(root, &TestQuickCheck, "tsnorm/cnormtst/TestQuickCheck");
|
addTest(root, &TestQuickCheck, "tsnorm/cnormtst/TestQuickCheck");
|
||||||
addTest(root, &TestQuickCheckPerCP, "tsnorm/cnormtst/TestQuickCheckPerCP");
|
addTest(root, &TestQuickCheckPerCP, "tsnorm/cnormtst/TestQuickCheckPerCP");
|
||||||
@ -138,132 +149,75 @@ void addNormTest(TestNode** root)
|
|||||||
addTest(root, &TestComposition, "tsnorm/cnormtst/TestComposition");
|
addTest(root, &TestComposition, "tsnorm/cnormtst/TestComposition");
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestDecomp()
|
static const char* const modeStrings[]={
|
||||||
{
|
"UNORM_NONE",
|
||||||
UErrorCode status = U_ZERO_ERROR;
|
"UNORM_NFD",
|
||||||
int32_t x, neededLen, resLen;
|
"UNORM_NFKD",
|
||||||
UChar *source=NULL, *result=NULL;
|
"UNORM_NFC",
|
||||||
status = U_ZERO_ERROR;
|
"UNORM_NFKC",
|
||||||
resLen=0;
|
"UNORM_FCD",
|
||||||
log_verbose("Testing unorm_normalize with Decomp canonical\n");
|
"UNORM_MODE_COUNT"
|
||||||
for(x=0; x < LENGTHOF(canonTests); x++)
|
};
|
||||||
|
|
||||||
|
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]);
|
UErrorCode status = U_ZERO_ERROR, status2 = U_ZERO_ERROR;
|
||||||
neededLen= unorm_normalize(source, u_strlen(source), UNORM_NFD, 0, NULL, 0, &status);
|
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)
|
if(status==U_BUFFER_OVERFLOW_ERROR)
|
||||||
{
|
{
|
||||||
status=U_ZERO_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)){
|
length2=unorm_normalize(source, u_strlen(source), mode, 0, result, LENGTHOF(result), &status);
|
||||||
log_data_err("ERROR in unorm_normalize at %s: %s - (Are you missing data?)\n", austrdup(source), myErrorName(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 {
|
} else {
|
||||||
assertEqual(result, canonTests[x][1], x);
|
assertEqual(result, cases[x][expIndex], x);
|
||||||
|
}
|
||||||
|
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, cases[x][expIndex], x);
|
||||||
}
|
}
|
||||||
free(result);
|
|
||||||
free(source);
|
free(source);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestCompatDecomp()
|
void TestDecomp() {
|
||||||
{
|
TestNormCases(UNORM_NFD, canonTests, LENGTHOF(canonTests));
|
||||||
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_data_err("ERROR in unorm_normalize at %s: %s - (Are you missing data?)\n", austrdup(source), myErrorName(status) );
|
|
||||||
} else {
|
|
||||||
assertEqual(result, compatTests[x][1], x);
|
|
||||||
}
|
|
||||||
free(result);
|
|
||||||
free(source);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestCanonDecompCompose()
|
void TestCompatDecomp() {
|
||||||
{
|
TestNormCases(UNORM_NFKD, compatTests, LENGTHOF(compatTests));
|
||||||
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_data_err("ERROR in unorm_normalize at %s: %s - (Are you missing data?)\n", austrdup(source),myErrorName(status) );
|
|
||||||
} else {
|
|
||||||
assertEqual(result, canonTests[x][2], x);
|
|
||||||
}
|
|
||||||
free(result);
|
|
||||||
free(source);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestCompatDecompCompose()
|
void TestCanonDecompCompose() {
|
||||||
{
|
TestNormCases(UNORM_NFC, canonTests, LENGTHOF(canonTests));
|
||||||
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_data_err("ERROR in unorm_normalize at %s: %s - (Are you missing data?)\n", austrdup(source), myErrorName(status) );
|
|
||||||
} else {
|
|
||||||
assertEqual(result, compatTests[x][2], x);
|
|
||||||
}
|
|
||||||
free(result);
|
|
||||||
free(source);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TestCompatDecompCompose() {
|
||||||
/*
|
TestNormCases(UNORM_NFKC, compatTests, LENGTHOF(compatTests));
|
||||||
static void assertEqual(const UChar* result, const UChar* expected, int32_t index)
|
}
|
||||||
{
|
|
||||||
if(u_strcmp(result, expected)!=0){
|
void TestFCD() {
|
||||||
log_err("ERROR in decomposition at index = %d. EXPECTED: %s , GOT: %s\n", index, austrdup(expected),
|
TestNormCases(UNORM_FCD, fcdTests, LENGTHOF(fcdTests));
|
||||||
austrdup(result) );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
static void assertEqual(const UChar* result, const char* expected, int32_t index)
|
static void assertEqual(const UChar* result, const char* expected, int32_t index)
|
||||||
{
|
{
|
||||||
@ -764,6 +718,16 @@ TestAPI() {
|
|||||||
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]);
|
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]);
|
||||||
return;
|
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 */
|
/* test cases to improve test code coverage */
|
||||||
|
Loading…
Reference in New Issue
Block a user