ICU-10815 Fix for uregex_findNext() not setting U_REGEX_STOPPED_BY_CALLER
X-SVN-Rev: 36260
This commit is contained in:
parent
d29271fcce
commit
f2dfa7422e
@ -33,26 +33,6 @@
|
|||||||
|
|
||||||
// #include <malloc.h> // Needed for heapcheck testing
|
// #include <malloc.h> // Needed for heapcheck testing
|
||||||
|
|
||||||
|
|
||||||
// Find progress callback
|
|
||||||
// ----------------------
|
|
||||||
// Macro to inline test & call to ReportFindProgress(). Eliminates unnecessary function call.
|
|
||||||
//
|
|
||||||
#define REGEXFINDPROGRESS_INTERRUPT(pos, status) \
|
|
||||||
(fFindProgressCallbackFn != NULL) && (ReportFindProgress(pos, status) == FALSE)
|
|
||||||
|
|
||||||
|
|
||||||
// Smart Backtracking
|
|
||||||
// ------------------
|
|
||||||
// When a failure would go back to a LOOP_C instruction,
|
|
||||||
// strings, characters, and setrefs scan backwards for a valid start
|
|
||||||
// character themselves, pop the stack, and save state, emulating the
|
|
||||||
// LOOP_C's effect but assured that the next character of input is a
|
|
||||||
// possible matching character.
|
|
||||||
//
|
|
||||||
// Good idea in theory; unfortunately it only helps out a few specific
|
|
||||||
// cases and slows the engine down a little in the rest.
|
|
||||||
|
|
||||||
U_NAMESPACE_BEGIN
|
U_NAMESPACE_BEGIN
|
||||||
|
|
||||||
// Default limit for the size of the back track stack, to avoid system
|
// Default limit for the size of the back track stack, to avoid system
|
||||||
@ -584,15 +564,33 @@ int32_t RegexMatcher::end(int32_t group, UErrorCode &err) const {
|
|||||||
//
|
//
|
||||||
//--------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------
|
||||||
UBool RegexMatcher::find() {
|
UBool RegexMatcher::find() {
|
||||||
|
if (U_FAILURE(fDeferredStatus)) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
UErrorCode status = U_ZERO_ERROR;
|
||||||
|
UBool result = find(status);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// find()
|
||||||
|
//
|
||||||
|
//--------------------------------------------------------------------------------
|
||||||
|
UBool RegexMatcher::find(UErrorCode &status) {
|
||||||
// Start at the position of the last match end. (Will be zero if the
|
// Start at the position of the last match end. (Will be zero if the
|
||||||
// matcher has been reset.)
|
// matcher has been reset.)
|
||||||
//
|
//
|
||||||
|
if (U_FAILURE(status)) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
if (U_FAILURE(fDeferredStatus)) {
|
if (U_FAILURE(fDeferredStatus)) {
|
||||||
|
status = fDeferredStatus;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (UTEXT_FULL_TEXT_IN_CHUNK(fInputText, fInputLength)) {
|
if (UTEXT_FULL_TEXT_IN_CHUNK(fInputText, fInputLength)) {
|
||||||
return findUsingChunk();
|
return findUsingChunk(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t startPos = fMatchEnd;
|
int64_t startPos = fMatchEnd;
|
||||||
@ -653,8 +651,8 @@ UBool RegexMatcher::find() {
|
|||||||
// No optimization was found.
|
// No optimization was found.
|
||||||
// Try a match at each input position.
|
// Try a match at each input position.
|
||||||
for (;;) {
|
for (;;) {
|
||||||
MatchAt(startPos, FALSE, fDeferredStatus);
|
MatchAt(startPos, FALSE, status);
|
||||||
if (U_FAILURE(fDeferredStatus)) {
|
if (U_FAILURE(status)) {
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
if (fMatch) {
|
if (fMatch) {
|
||||||
@ -670,7 +668,7 @@ UBool RegexMatcher::find() {
|
|||||||
// Note that it's perfectly OK for a pattern to have a zero-length
|
// Note that it's perfectly OK for a pattern to have a zero-length
|
||||||
// match at the end of a string, so we must make sure that the loop
|
// match at the end of a string, so we must make sure that the loop
|
||||||
// runs with startPos == testStartLimit the last time through.
|
// runs with startPos == testStartLimit the last time through.
|
||||||
if (REGEXFINDPROGRESS_INTERRUPT(startPos, fDeferredStatus))
|
if (findProgressInterrupt(startPos, status))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
U_ASSERT(FALSE);
|
U_ASSERT(FALSE);
|
||||||
@ -682,8 +680,8 @@ UBool RegexMatcher::find() {
|
|||||||
fMatch = FALSE;
|
fMatch = FALSE;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
MatchAt(startPos, FALSE, fDeferredStatus);
|
MatchAt(startPos, FALSE, status);
|
||||||
if (U_FAILURE(fDeferredStatus)) {
|
if (U_FAILURE(status)) {
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
return fMatch;
|
return fMatch;
|
||||||
@ -703,8 +701,8 @@ UBool RegexMatcher::find() {
|
|||||||
// and handle end of text in the following block.
|
// and handle end of text in the following block.
|
||||||
if (c >= 0 && ((c<256 && fPattern->fInitialChars8->contains(c)) ||
|
if (c >= 0 && ((c<256 && fPattern->fInitialChars8->contains(c)) ||
|
||||||
(c>=256 && fPattern->fInitialChars->contains(c)))) {
|
(c>=256 && fPattern->fInitialChars->contains(c)))) {
|
||||||
MatchAt(pos, FALSE, fDeferredStatus);
|
MatchAt(pos, FALSE, status);
|
||||||
if (U_FAILURE(fDeferredStatus)) {
|
if (U_FAILURE(status)) {
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
if (fMatch) {
|
if (fMatch) {
|
||||||
@ -717,7 +715,7 @@ UBool RegexMatcher::find() {
|
|||||||
fHitEnd = TRUE;
|
fHitEnd = TRUE;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
if (REGEXFINDPROGRESS_INTERRUPT(startPos, fDeferredStatus))
|
if (findProgressInterrupt(startPos, status))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -735,8 +733,8 @@ UBool RegexMatcher::find() {
|
|||||||
c = UTEXT_NEXT32(fInputText);
|
c = UTEXT_NEXT32(fInputText);
|
||||||
startPos = UTEXT_GETNATIVEINDEX(fInputText);
|
startPos = UTEXT_GETNATIVEINDEX(fInputText);
|
||||||
if (c == theChar) {
|
if (c == theChar) {
|
||||||
MatchAt(pos, FALSE, fDeferredStatus);
|
MatchAt(pos, FALSE, status);
|
||||||
if (U_FAILURE(fDeferredStatus)) {
|
if (U_FAILURE(status)) {
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
if (fMatch) {
|
if (fMatch) {
|
||||||
@ -749,7 +747,7 @@ UBool RegexMatcher::find() {
|
|||||||
fHitEnd = TRUE;
|
fHitEnd = TRUE;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
if (REGEXFINDPROGRESS_INTERRUPT(startPos, fDeferredStatus))
|
if (findProgressInterrupt(startPos, status))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -759,8 +757,8 @@ UBool RegexMatcher::find() {
|
|||||||
{
|
{
|
||||||
UChar32 c;
|
UChar32 c;
|
||||||
if (startPos == fAnchorStart) {
|
if (startPos == fAnchorStart) {
|
||||||
MatchAt(startPos, FALSE, fDeferredStatus);
|
MatchAt(startPos, FALSE, status);
|
||||||
if (U_FAILURE(fDeferredStatus)) {
|
if (U_FAILURE(status)) {
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
if (fMatch) {
|
if (fMatch) {
|
||||||
@ -778,8 +776,8 @@ UBool RegexMatcher::find() {
|
|||||||
if (fPattern->fFlags & UREGEX_UNIX_LINES) {
|
if (fPattern->fFlags & UREGEX_UNIX_LINES) {
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (c == 0x0a) {
|
if (c == 0x0a) {
|
||||||
MatchAt(startPos, FALSE, fDeferredStatus);
|
MatchAt(startPos, FALSE, status);
|
||||||
if (U_FAILURE(fDeferredStatus)) {
|
if (U_FAILURE(status)) {
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
if (fMatch) {
|
if (fMatch) {
|
||||||
@ -797,7 +795,7 @@ UBool RegexMatcher::find() {
|
|||||||
// Note that it's perfectly OK for a pattern to have a zero-length
|
// Note that it's perfectly OK for a pattern to have a zero-length
|
||||||
// match at the end of a string, so we must make sure that the loop
|
// match at the end of a string, so we must make sure that the loop
|
||||||
// runs with startPos == testStartLimit the last time through.
|
// runs with startPos == testStartLimit the last time through.
|
||||||
if (REGEXFINDPROGRESS_INTERRUPT(startPos, fDeferredStatus))
|
if (findProgressInterrupt(startPos, status))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -808,8 +806,8 @@ UBool RegexMatcher::find() {
|
|||||||
(void)UTEXT_NEXT32(fInputText);
|
(void)UTEXT_NEXT32(fInputText);
|
||||||
startPos = UTEXT_GETNATIVEINDEX(fInputText);
|
startPos = UTEXT_GETNATIVEINDEX(fInputText);
|
||||||
}
|
}
|
||||||
MatchAt(startPos, FALSE, fDeferredStatus);
|
MatchAt(startPos, FALSE, status);
|
||||||
if (U_FAILURE(fDeferredStatus)) {
|
if (U_FAILURE(status)) {
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
if (fMatch) {
|
if (fMatch) {
|
||||||
@ -827,7 +825,7 @@ UBool RegexMatcher::find() {
|
|||||||
// Note that it's perfectly OK for a pattern to have a zero-length
|
// Note that it's perfectly OK for a pattern to have a zero-length
|
||||||
// match at the end of a string, so we must make sure that the loop
|
// match at the end of a string, so we must make sure that the loop
|
||||||
// runs with startPos == testStartLimit the last time through.
|
// runs with startPos == testStartLimit the last time through.
|
||||||
if (REGEXFINDPROGRESS_INTERRUPT(startPos, fDeferredStatus))
|
if (findProgressInterrupt(startPos, status))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -864,7 +862,7 @@ UBool RegexMatcher::find(int64_t start, UErrorCode &status) {
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
fMatchEnd = nativeStart;
|
fMatchEnd = nativeStart;
|
||||||
return find();
|
return find(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -874,7 +872,7 @@ UBool RegexMatcher::find(int64_t start, UErrorCode &status) {
|
|||||||
// entire string is available in the UText's chunk buffer.
|
// entire string is available in the UText's chunk buffer.
|
||||||
//
|
//
|
||||||
//--------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------
|
||||||
UBool RegexMatcher::findUsingChunk() {
|
UBool RegexMatcher::findUsingChunk(UErrorCode &status) {
|
||||||
// Start at the position of the last match end. (Will be zero if the
|
// Start at the position of the last match end. (Will be zero if the
|
||||||
// matcher has been reset.
|
// matcher has been reset.
|
||||||
//
|
//
|
||||||
@ -931,8 +929,8 @@ UBool RegexMatcher::findUsingChunk() {
|
|||||||
// No optimization was found.
|
// No optimization was found.
|
||||||
// Try a match at each input position.
|
// Try a match at each input position.
|
||||||
for (;;) {
|
for (;;) {
|
||||||
MatchChunkAt(startPos, FALSE, fDeferredStatus);
|
MatchChunkAt(startPos, FALSE, status);
|
||||||
if (U_FAILURE(fDeferredStatus)) {
|
if (U_FAILURE(status)) {
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
if (fMatch) {
|
if (fMatch) {
|
||||||
@ -946,7 +944,7 @@ UBool RegexMatcher::findUsingChunk() {
|
|||||||
// Note that it's perfectly OK for a pattern to have a zero-length
|
// Note that it's perfectly OK for a pattern to have a zero-length
|
||||||
// match at the end of a string, so we must make sure that the loop
|
// match at the end of a string, so we must make sure that the loop
|
||||||
// runs with startPos == testLen the last time through.
|
// runs with startPos == testLen the last time through.
|
||||||
if (REGEXFINDPROGRESS_INTERRUPT(startPos, fDeferredStatus))
|
if (findProgressInterrupt(startPos, status))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
U_ASSERT(FALSE);
|
U_ASSERT(FALSE);
|
||||||
@ -958,8 +956,8 @@ UBool RegexMatcher::findUsingChunk() {
|
|||||||
fMatch = FALSE;
|
fMatch = FALSE;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
MatchChunkAt(startPos, FALSE, fDeferredStatus);
|
MatchChunkAt(startPos, FALSE, status);
|
||||||
if (U_FAILURE(fDeferredStatus)) {
|
if (U_FAILURE(status)) {
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
return fMatch;
|
return fMatch;
|
||||||
@ -974,8 +972,8 @@ UBool RegexMatcher::findUsingChunk() {
|
|||||||
U16_NEXT(inputBuf, startPos, fActiveLimit, c); // like c = inputBuf[startPos++];
|
U16_NEXT(inputBuf, startPos, fActiveLimit, c); // like c = inputBuf[startPos++];
|
||||||
if ((c<256 && fPattern->fInitialChars8->contains(c)) ||
|
if ((c<256 && fPattern->fInitialChars8->contains(c)) ||
|
||||||
(c>=256 && fPattern->fInitialChars->contains(c))) {
|
(c>=256 && fPattern->fInitialChars->contains(c))) {
|
||||||
MatchChunkAt(pos, FALSE, fDeferredStatus);
|
MatchChunkAt(pos, FALSE, status);
|
||||||
if (U_FAILURE(fDeferredStatus)) {
|
if (U_FAILURE(status)) {
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
if (fMatch) {
|
if (fMatch) {
|
||||||
@ -987,7 +985,7 @@ UBool RegexMatcher::findUsingChunk() {
|
|||||||
fHitEnd = TRUE;
|
fHitEnd = TRUE;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
if (REGEXFINDPROGRESS_INTERRUPT(startPos, fDeferredStatus))
|
if (findProgressInterrupt(startPos, status))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1003,8 +1001,8 @@ UBool RegexMatcher::findUsingChunk() {
|
|||||||
int32_t pos = startPos;
|
int32_t pos = startPos;
|
||||||
U16_NEXT(inputBuf, startPos, fActiveLimit, c); // like c = inputBuf[startPos++];
|
U16_NEXT(inputBuf, startPos, fActiveLimit, c); // like c = inputBuf[startPos++];
|
||||||
if (c == theChar) {
|
if (c == theChar) {
|
||||||
MatchChunkAt(pos, FALSE, fDeferredStatus);
|
MatchChunkAt(pos, FALSE, status);
|
||||||
if (U_FAILURE(fDeferredStatus)) {
|
if (U_FAILURE(status)) {
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
if (fMatch) {
|
if (fMatch) {
|
||||||
@ -1016,7 +1014,7 @@ UBool RegexMatcher::findUsingChunk() {
|
|||||||
fHitEnd = TRUE;
|
fHitEnd = TRUE;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
if (REGEXFINDPROGRESS_INTERRUPT(startPos, fDeferredStatus))
|
if (findProgressInterrupt(startPos, status))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1026,8 +1024,8 @@ UBool RegexMatcher::findUsingChunk() {
|
|||||||
{
|
{
|
||||||
UChar32 c;
|
UChar32 c;
|
||||||
if (startPos == fAnchorStart) {
|
if (startPos == fAnchorStart) {
|
||||||
MatchChunkAt(startPos, FALSE, fDeferredStatus);
|
MatchChunkAt(startPos, FALSE, status);
|
||||||
if (U_FAILURE(fDeferredStatus)) {
|
if (U_FAILURE(status)) {
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
if (fMatch) {
|
if (fMatch) {
|
||||||
@ -1040,8 +1038,8 @@ UBool RegexMatcher::findUsingChunk() {
|
|||||||
for (;;) {
|
for (;;) {
|
||||||
c = inputBuf[startPos-1];
|
c = inputBuf[startPos-1];
|
||||||
if (c == 0x0a) {
|
if (c == 0x0a) {
|
||||||
MatchChunkAt(startPos, FALSE, fDeferredStatus);
|
MatchChunkAt(startPos, FALSE, status);
|
||||||
if (U_FAILURE(fDeferredStatus)) {
|
if (U_FAILURE(status)) {
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
if (fMatch) {
|
if (fMatch) {
|
||||||
@ -1057,7 +1055,7 @@ UBool RegexMatcher::findUsingChunk() {
|
|||||||
// Note that it's perfectly OK for a pattern to have a zero-length
|
// Note that it's perfectly OK for a pattern to have a zero-length
|
||||||
// match at the end of a string, so we must make sure that the loop
|
// match at the end of a string, so we must make sure that the loop
|
||||||
// runs with startPos == testLen the last time through.
|
// runs with startPos == testLen the last time through.
|
||||||
if (REGEXFINDPROGRESS_INTERRUPT(startPos, fDeferredStatus))
|
if (findProgressInterrupt(startPos, status))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -1068,8 +1066,8 @@ UBool RegexMatcher::findUsingChunk() {
|
|||||||
if (c == 0x0d && startPos < fActiveLimit && inputBuf[startPos] == 0x0a) {
|
if (c == 0x0d && startPos < fActiveLimit && inputBuf[startPos] == 0x0a) {
|
||||||
startPos++;
|
startPos++;
|
||||||
}
|
}
|
||||||
MatchChunkAt(startPos, FALSE, fDeferredStatus);
|
MatchChunkAt(startPos, FALSE, status);
|
||||||
if (U_FAILURE(fDeferredStatus)) {
|
if (U_FAILURE(status)) {
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
if (fMatch) {
|
if (fMatch) {
|
||||||
@ -1085,7 +1083,7 @@ UBool RegexMatcher::findUsingChunk() {
|
|||||||
// Note that it's perfectly OK for a pattern to have a zero-length
|
// Note that it's perfectly OK for a pattern to have a zero-length
|
||||||
// match at the end of a string, so we must make sure that the loop
|
// match at the end of a string, so we must make sure that the loop
|
||||||
// runs with startPos == testLen the last time through.
|
// runs with startPos == testLen the last time through.
|
||||||
if (REGEXFINDPROGRESS_INTERRUPT(startPos, fDeferredStatus))
|
if (findProgressInterrupt(startPos, status))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1172,8 +1170,8 @@ UnicodeString RegexMatcher::group(int32_t groupNum, UErrorCode &status) const {
|
|||||||
|
|
||||||
|
|
||||||
// Return deep (mutable) clone
|
// Return deep (mutable) clone
|
||||||
// Technology Preview (as an API), but note that the UnicodeString API is implemented
|
// Technology Preview (as an API), but note that the UnicodeString API is implemented
|
||||||
// using this function.
|
// using this function.
|
||||||
UText *RegexMatcher::group(int32_t groupNum, UText *dest, UErrorCode &status) const {
|
UText *RegexMatcher::group(int32_t groupNum, UText *dest, UErrorCode &status) const {
|
||||||
if (U_FAILURE(status)) {
|
if (U_FAILURE(status)) {
|
||||||
return dest;
|
return dest;
|
||||||
@ -2625,25 +2623,20 @@ void RegexMatcher::IncrementTime(UErrorCode &status) {
|
|||||||
|
|
||||||
//--------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// ReportFindProgress This function is called once for each advance in the target
|
// findProgressInterrupt This function is called once for each advance in the target
|
||||||
// string from the find() function, and calls the user progress callback
|
// string from the find() function, and calls the user progress callback
|
||||||
// function if there is one installed.
|
// function if there is one installed.
|
||||||
//
|
//
|
||||||
// NOTE:
|
// Return: TRUE if the find operation is to be terminated.
|
||||||
//
|
// FALSE if the find operation is to continue running.
|
||||||
// If the match operation needs to be aborted because the user
|
|
||||||
// callback asked for it, just set an error status.
|
|
||||||
// The engine will pick that up and stop in its outer loop.
|
|
||||||
//
|
//
|
||||||
//--------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------
|
||||||
UBool RegexMatcher::ReportFindProgress(int64_t matchIndex, UErrorCode &status) {
|
UBool RegexMatcher::findProgressInterrupt(int64_t pos, UErrorCode &status) {
|
||||||
if (fFindProgressCallbackFn != NULL) {
|
if (fFindProgressCallbackFn && !(*fFindProgressCallbackFn)(fFindProgressCallbackContext, pos)) {
|
||||||
if ((*fFindProgressCallbackFn)(fFindProgressCallbackContext, matchIndex) == FALSE) {
|
status = U_REGEX_STOPPED_BY_CALLER;
|
||||||
status = U_ZERO_ERROR /*U_REGEX_STOPPED_BY_CALLER*/;
|
return TRUE;
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return TRUE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------
|
||||||
|
@ -801,6 +801,21 @@ public:
|
|||||||
virtual UBool find();
|
virtual UBool find();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find the next pattern match in the input string.
|
||||||
|
* The find begins searching the input at the location following the end of
|
||||||
|
* the previous match, or at the start of the string if there is no previous match.
|
||||||
|
* If a match is found, <code>start(), end()</code> and <code>group()</code>
|
||||||
|
* will provide more information regarding the match.
|
||||||
|
* <p>Note that if the input string is changed by the application,
|
||||||
|
* use find(startPos, status) instead of find(), because the saved starting
|
||||||
|
* position may not be valid with the altered input string.</p>
|
||||||
|
* @param status A reference to a UErrorCode to receive any errors.
|
||||||
|
* @return TRUE if a match is found.
|
||||||
|
* @stable @internal
|
||||||
|
*/
|
||||||
|
virtual UBool find(UErrorCode &status);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resets this RegexMatcher and then attempts to find the next substring of the
|
* Resets this RegexMatcher and then attempts to find the next substring of the
|
||||||
* input string that matches the pattern, starting at the specified index.
|
* input string that matches the pattern, starting at the specified index.
|
||||||
@ -1744,11 +1759,13 @@ private:
|
|||||||
REStackFrame *resetStack();
|
REStackFrame *resetStack();
|
||||||
inline REStackFrame *StateSave(REStackFrame *fp, int64_t savePatIdx, UErrorCode &status);
|
inline REStackFrame *StateSave(REStackFrame *fp, int64_t savePatIdx, UErrorCode &status);
|
||||||
void IncrementTime(UErrorCode &status);
|
void IncrementTime(UErrorCode &status);
|
||||||
UBool ReportFindProgress(int64_t matchIndex, UErrorCode &status);
|
|
||||||
|
// Call user find callback function, if set. Return TRUE if operation should be interrupted.
|
||||||
|
inline UBool findProgressInterrupt(int64_t matchIndex, UErrorCode &status);
|
||||||
|
|
||||||
int64_t appendGroup(int32_t groupNum, UText *dest, UErrorCode &status) const;
|
int64_t appendGroup(int32_t groupNum, UText *dest, UErrorCode &status) const;
|
||||||
|
|
||||||
UBool findUsingChunk();
|
UBool findUsingChunk(UErrorCode &status);
|
||||||
void MatchChunkAt(int32_t startIdx, UBool toEnd, UErrorCode &status);
|
void MatchChunkAt(int32_t startIdx, UBool toEnd, UErrorCode &status);
|
||||||
UBool isChunkWordBoundary(int32_t pos);
|
UBool isChunkWordBoundary(int32_t pos);
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
*******************************************************************************
|
*******************************************************************************
|
||||||
* Copyright (C) 2004-2013, International Business Machines
|
* Copyright (C) 2004-2014, International Business Machines
|
||||||
* Corporation and others. All Rights Reserved.
|
* Corporation and others. All Rights Reserved.
|
||||||
*******************************************************************************
|
*******************************************************************************
|
||||||
* file name: uregex.cpp
|
* file name: uregex.cpp
|
||||||
@ -584,7 +584,7 @@ uregex_find64(URegularExpression *regexp2,
|
|||||||
}
|
}
|
||||||
if (startIndex == -1) {
|
if (startIndex == -1) {
|
||||||
regexp->fMatcher->resetPreserveRegion();
|
regexp->fMatcher->resetPreserveRegion();
|
||||||
result = regexp->fMatcher->find();
|
result = regexp->fMatcher->find(*status);
|
||||||
} else {
|
} else {
|
||||||
result = regexp->fMatcher->find(startIndex, *status);
|
result = regexp->fMatcher->find(startIndex, *status);
|
||||||
}
|
}
|
||||||
@ -604,7 +604,7 @@ uregex_findNext(URegularExpression *regexp2,
|
|||||||
if (validateRE(regexp, TRUE, status) == FALSE) {
|
if (validateRE(regexp, TRUE, status) == FALSE) {
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
UBool result = regexp->fMatcher->find();
|
UBool result = regexp->fMatcher->find(*status);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/********************************************************************
|
/********************************************************************
|
||||||
* COPYRIGHT:
|
* COPYRIGHT:
|
||||||
* Copyright (c) 2004-2013, International Business Machines Corporation and
|
* Copyright (c) 2004-2014, International Business Machines Corporation and
|
||||||
* others. All Rights Reserved.
|
* others. All Rights Reserved.
|
||||||
********************************************************************/
|
********************************************************************/
|
||||||
/********************************************************************************
|
/********************************************************************************
|
||||||
@ -29,11 +29,13 @@
|
|||||||
#include "unicode/utext.h"
|
#include "unicode/utext.h"
|
||||||
#include "cintltst.h"
|
#include "cintltst.h"
|
||||||
|
|
||||||
|
#define LENGTHOF(array) (int32_t)(sizeof(array)/sizeof((array)[0]))
|
||||||
|
|
||||||
#define TEST_ASSERT_SUCCESS(status) {if (U_FAILURE(status)) { \
|
#define TEST_ASSERT_SUCCESS(status) {if (U_FAILURE(status)) { \
|
||||||
log_data_err("Failure at file %s, line %d, error = %s (Are you missing data?)\n", __FILE__, __LINE__, u_errorName(status));}}
|
log_data_err("Failure at file %s:%d - error = %s (Are you missing data?)\n", __FILE__, __LINE__, u_errorName(status));}}
|
||||||
|
|
||||||
#define TEST_ASSERT(expr) {if ((expr)==FALSE) { \
|
#define TEST_ASSERT(expr) {if ((expr)==FALSE) { \
|
||||||
log_data_err("Test Failure at file %s, line %d (Are you missing data?)\n", __FILE__, __LINE__);}}
|
log_err("Test Failure at file %s:%d - ASSERT(%s) failed.\n", __FILE__, __LINE__, #expr);}}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* TEST_SETUP and TEST_TEARDOWN
|
* TEST_SETUP and TEST_TEARDOWN
|
||||||
@ -158,6 +160,7 @@ static void TestBug4315(void);
|
|||||||
static void TestUTextAPI(void);
|
static void TestUTextAPI(void);
|
||||||
static void TestRefreshInput(void);
|
static void TestRefreshInput(void);
|
||||||
static void TestBug8421(void);
|
static void TestBug8421(void);
|
||||||
|
static void TestBug10815(void);
|
||||||
|
|
||||||
void addURegexTest(TestNode** root);
|
void addURegexTest(TestNode** root);
|
||||||
|
|
||||||
@ -168,6 +171,7 @@ void addURegexTest(TestNode** root)
|
|||||||
addTest(root, &TestUTextAPI, "regex/TestUTextAPI");
|
addTest(root, &TestUTextAPI, "regex/TestUTextAPI");
|
||||||
addTest(root, &TestRefreshInput, "regex/TestRefreshInput");
|
addTest(root, &TestRefreshInput, "regex/TestRefreshInput");
|
||||||
addTest(root, &TestBug8421, "regex/TestBug8421");
|
addTest(root, &TestBug8421, "regex/TestBug8421");
|
||||||
|
addTest(root, &TestBug10815, "regex/TestBug10815");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -204,7 +208,7 @@ static void TestRegexCAPI(void) {
|
|||||||
memset(&minus1, -1, sizeof(minus1));
|
memset(&minus1, -1, sizeof(minus1));
|
||||||
|
|
||||||
/* Mimimalist open/close */
|
/* Mimimalist open/close */
|
||||||
u_uastrncpy(pat, "abc*", sizeof(pat)/2);
|
u_uastrncpy(pat, "abc*", LENGTHOF(pat));
|
||||||
re = uregex_open(pat, -1, 0, 0, &status);
|
re = uregex_open(pat, -1, 0, 0, &status);
|
||||||
if (U_FAILURE(status)) {
|
if (U_FAILURE(status)) {
|
||||||
log_data_err("Failed to open regular expression, %s:%d, error is \"%s\" (Are you missing data?)\n", __FILE__, __LINE__, u_errorName(status));
|
log_data_err("Failed to open regular expression, %s:%d, error is \"%s\" (Are you missing data?)\n", __FILE__, __LINE__, u_errorName(status));
|
||||||
@ -256,7 +260,7 @@ static void TestRegexCAPI(void) {
|
|||||||
|
|
||||||
/* The TEST_ASSERT_SUCCESS above should change too... */
|
/* The TEST_ASSERT_SUCCESS above should change too... */
|
||||||
if(U_SUCCESS(status)) {
|
if(U_SUCCESS(status)) {
|
||||||
u_uastrncpy(pat, "abc*", sizeof(pat)/2);
|
u_uastrncpy(pat, "abc*", LENGTHOF(pat));
|
||||||
TEST_ASSERT(u_strcmp(pat, p) == 0);
|
TEST_ASSERT(u_strcmp(pat, p) == 0);
|
||||||
TEST_ASSERT(len==(int32_t)strlen("abc*"));
|
TEST_ASSERT(len==(int32_t)strlen("abc*"));
|
||||||
}
|
}
|
||||||
@ -296,8 +300,8 @@ static void TestRegexCAPI(void) {
|
|||||||
TEST_ASSERT_SUCCESS(status);
|
TEST_ASSERT_SUCCESS(status);
|
||||||
TEST_ASSERT(clone3 != NULL);
|
TEST_ASSERT(clone3 != NULL);
|
||||||
|
|
||||||
u_uastrncpy(testString1, "abcccd", sizeof(pat)/2);
|
u_uastrncpy(testString1, "abcccd", LENGTHOF(pat));
|
||||||
u_uastrncpy(testString2, "xxxabcccd", sizeof(pat)/2);
|
u_uastrncpy(testString2, "xxxabcccd", LENGTHOF(pat));
|
||||||
|
|
||||||
status = U_ZERO_ERROR;
|
status = U_ZERO_ERROR;
|
||||||
uregex_setText(clone1, testString1, -1, &status);
|
uregex_setText(clone1, testString1, -1, &status);
|
||||||
@ -328,7 +332,7 @@ static void TestRegexCAPI(void) {
|
|||||||
{
|
{
|
||||||
const UChar *resultPat;
|
const UChar *resultPat;
|
||||||
int32_t resultLen;
|
int32_t resultLen;
|
||||||
u_uastrncpy(pat, "hello", sizeof(pat)/2);
|
u_uastrncpy(pat, "hello", LENGTHOF(pat));
|
||||||
status = U_ZERO_ERROR;
|
status = U_ZERO_ERROR;
|
||||||
re = uregex_open(pat, -1, 0, NULL, &status);
|
re = uregex_open(pat, -1, 0, NULL, &status);
|
||||||
resultPat = uregex_pattern(re, &resultLen, &status);
|
resultPat = uregex_pattern(re, &resultLen, &status);
|
||||||
@ -394,10 +398,10 @@ static void TestRegexCAPI(void) {
|
|||||||
UChar text2[50];
|
UChar text2[50];
|
||||||
UBool result;
|
UBool result;
|
||||||
|
|
||||||
u_uastrncpy(text1, "abcccd", sizeof(text1)/2);
|
u_uastrncpy(text1, "abcccd", LENGTHOF(text1));
|
||||||
u_uastrncpy(text2, "abcccxd", sizeof(text2)/2);
|
u_uastrncpy(text2, "abcccxd", LENGTHOF(text2));
|
||||||
status = U_ZERO_ERROR;
|
status = U_ZERO_ERROR;
|
||||||
u_uastrncpy(pat, "abc*d", sizeof(pat)/2);
|
u_uastrncpy(pat, "abc*d", LENGTHOF(pat));
|
||||||
re = uregex_open(pat, -1, 0, NULL, &status);
|
re = uregex_open(pat, -1, 0, NULL, &status);
|
||||||
TEST_ASSERT_SUCCESS(status);
|
TEST_ASSERT_SUCCESS(status);
|
||||||
|
|
||||||
@ -449,10 +453,10 @@ static void TestRegexCAPI(void) {
|
|||||||
const UChar *result;
|
const UChar *result;
|
||||||
int32_t textLength;
|
int32_t textLength;
|
||||||
|
|
||||||
u_uastrncpy(text1, "abcccd", sizeof(text1)/2);
|
u_uastrncpy(text1, "abcccd", LENGTHOF(text1));
|
||||||
u_uastrncpy(text2, "abcccxd", sizeof(text2)/2);
|
u_uastrncpy(text2, "abcccxd", LENGTHOF(text2));
|
||||||
status = U_ZERO_ERROR;
|
status = U_ZERO_ERROR;
|
||||||
u_uastrncpy(pat, "abc*d", sizeof(pat)/2);
|
u_uastrncpy(pat, "abc*d", LENGTHOF(pat));
|
||||||
re = uregex_open(pat, -1, 0, NULL, &status);
|
re = uregex_open(pat, -1, 0, NULL, &status);
|
||||||
|
|
||||||
uregex_setText(re, text1, -1, &status);
|
uregex_setText(re, text1, -1, &status);
|
||||||
@ -486,9 +490,9 @@ static void TestRegexCAPI(void) {
|
|||||||
int len;
|
int len;
|
||||||
UChar nullString[] = {0,0,0};
|
UChar nullString[] = {0,0,0};
|
||||||
|
|
||||||
u_uastrncpy(text1, "abcccde", sizeof(text1)/2);
|
u_uastrncpy(text1, "abcccde", LENGTHOF(text1));
|
||||||
status = U_ZERO_ERROR;
|
status = U_ZERO_ERROR;
|
||||||
u_uastrncpy(pat, "abc*d", sizeof(pat)/2);
|
u_uastrncpy(pat, "abc*d", LENGTHOF(pat));
|
||||||
re = uregex_open(pat, -1, 0, NULL, &status);
|
re = uregex_open(pat, -1, 0, NULL, &status);
|
||||||
|
|
||||||
uregex_setText(re, text1, -1, &status);
|
uregex_setText(re, text1, -1, &status);
|
||||||
@ -538,7 +542,7 @@ static void TestRegexCAPI(void) {
|
|||||||
{
|
{
|
||||||
UChar text1[50];
|
UChar text1[50];
|
||||||
UBool result;
|
UBool result;
|
||||||
u_uastrncpy(text1, "012rx5rx890rxrx...", sizeof(text1)/2);
|
u_uastrncpy(text1, "012rx5rx890rxrx...", LENGTHOF(text1));
|
||||||
status = U_ZERO_ERROR;
|
status = U_ZERO_ERROR;
|
||||||
re = uregex_openC("rx", 0, NULL, &status);
|
re = uregex_openC("rx", 0, NULL, &status);
|
||||||
|
|
||||||
@ -621,7 +625,7 @@ static void TestRegexCAPI(void) {
|
|||||||
UChar buf[80];
|
UChar buf[80];
|
||||||
UBool result;
|
UBool result;
|
||||||
int32_t resultSz;
|
int32_t resultSz;
|
||||||
u_uastrncpy(text1, "noise abc interior def, and this is off the end", sizeof(text1)/2);
|
u_uastrncpy(text1, "noise abc interior def, and this is off the end", LENGTHOF(text1));
|
||||||
|
|
||||||
status = U_ZERO_ERROR;
|
status = U_ZERO_ERROR;
|
||||||
re = uregex_openC("abc(.*?)def", 0, NULL, &status);
|
re = uregex_openC("abc(.*?)def", 0, NULL, &status);
|
||||||
@ -634,21 +638,21 @@ static void TestRegexCAPI(void) {
|
|||||||
|
|
||||||
/* Capture Group 0, the full match. Should succeed. */
|
/* Capture Group 0, the full match. Should succeed. */
|
||||||
status = U_ZERO_ERROR;
|
status = U_ZERO_ERROR;
|
||||||
resultSz = uregex_group(re, 0, buf, sizeof(buf)/2, &status);
|
resultSz = uregex_group(re, 0, buf, LENGTHOF(buf), &status);
|
||||||
TEST_ASSERT_SUCCESS(status);
|
TEST_ASSERT_SUCCESS(status);
|
||||||
TEST_ASSERT_STRING("abc interior def", buf, TRUE);
|
TEST_ASSERT_STRING("abc interior def", buf, TRUE);
|
||||||
TEST_ASSERT(resultSz == (int32_t)strlen("abc interior def"));
|
TEST_ASSERT(resultSz == (int32_t)strlen("abc interior def"));
|
||||||
|
|
||||||
/* Capture group #1. Should succeed. */
|
/* Capture group #1. Should succeed. */
|
||||||
status = U_ZERO_ERROR;
|
status = U_ZERO_ERROR;
|
||||||
resultSz = uregex_group(re, 1, buf, sizeof(buf)/2, &status);
|
resultSz = uregex_group(re, 1, buf, LENGTHOF(buf), &status);
|
||||||
TEST_ASSERT_SUCCESS(status);
|
TEST_ASSERT_SUCCESS(status);
|
||||||
TEST_ASSERT_STRING(" interior ", buf, TRUE);
|
TEST_ASSERT_STRING(" interior ", buf, TRUE);
|
||||||
TEST_ASSERT(resultSz == (int32_t)strlen(" interior "));
|
TEST_ASSERT(resultSz == (int32_t)strlen(" interior "));
|
||||||
|
|
||||||
/* Capture group out of range. Error. */
|
/* Capture group out of range. Error. */
|
||||||
status = U_ZERO_ERROR;
|
status = U_ZERO_ERROR;
|
||||||
uregex_group(re, 2, buf, sizeof(buf)/2, &status);
|
uregex_group(re, 2, buf, LENGTHOF(buf), &status);
|
||||||
TEST_ASSERT(status == U_INDEX_OUTOFBOUNDS_ERROR);
|
TEST_ASSERT(status == U_INDEX_OUTOFBOUNDS_ERROR);
|
||||||
|
|
||||||
/* NULL buffer, pure pre-flight */
|
/* NULL buffer, pure pre-flight */
|
||||||
@ -692,7 +696,7 @@ static void TestRegexCAPI(void) {
|
|||||||
TEST_ASSERT(uregex_regionStart(re, &status) == 3);
|
TEST_ASSERT(uregex_regionStart(re, &status) == 3);
|
||||||
TEST_ASSERT(uregex_regionEnd(re, &status) == 6);
|
TEST_ASSERT(uregex_regionEnd(re, &status) == 6);
|
||||||
TEST_ASSERT(uregex_findNext(re, &status));
|
TEST_ASSERT(uregex_findNext(re, &status));
|
||||||
TEST_ASSERT(uregex_group(re, 0, resultString, sizeof(resultString)/2, &status) == 3)
|
TEST_ASSERT(uregex_group(re, 0, resultString, LENGTHOF(resultString), &status) == 3)
|
||||||
TEST_ASSERT_STRING("345", resultString, TRUE);
|
TEST_ASSERT_STRING("345", resultString, TRUE);
|
||||||
TEST_TEARDOWN;
|
TEST_TEARDOWN;
|
||||||
|
|
||||||
@ -816,9 +820,9 @@ static void TestRegexCAPI(void) {
|
|||||||
UChar replText[80];
|
UChar replText[80];
|
||||||
UChar buf[80];
|
UChar buf[80];
|
||||||
int32_t resultSz;
|
int32_t resultSz;
|
||||||
u_uastrncpy(text1, "Replace xaax x1x x...x.", sizeof(text1)/2);
|
u_uastrncpy(text1, "Replace xaax x1x x...x.", LENGTHOF(text1));
|
||||||
u_uastrncpy(text2, "No match here.", sizeof(text2)/2);
|
u_uastrncpy(text2, "No match here.", LENGTHOF(text2));
|
||||||
u_uastrncpy(replText, "<$1>", sizeof(replText)/2);
|
u_uastrncpy(replText, "<$1>", LENGTHOF(replText));
|
||||||
|
|
||||||
status = U_ZERO_ERROR;
|
status = U_ZERO_ERROR;
|
||||||
re = uregex_openC("x(.*?)x", 0, NULL, &status);
|
re = uregex_openC("x(.*?)x", 0, NULL, &status);
|
||||||
@ -826,7 +830,7 @@ static void TestRegexCAPI(void) {
|
|||||||
|
|
||||||
/* Normal case, with match */
|
/* Normal case, with match */
|
||||||
uregex_setText(re, text1, -1, &status);
|
uregex_setText(re, text1, -1, &status);
|
||||||
resultSz = uregex_replaceFirst(re, replText, -1, buf, sizeof(buf)/2, &status);
|
resultSz = uregex_replaceFirst(re, replText, -1, buf, LENGTHOF(buf), &status);
|
||||||
TEST_ASSERT_SUCCESS(status);
|
TEST_ASSERT_SUCCESS(status);
|
||||||
TEST_ASSERT_STRING("Replace <aa> x1x x...x.", buf, TRUE);
|
TEST_ASSERT_STRING("Replace <aa> x1x x...x.", buf, TRUE);
|
||||||
TEST_ASSERT(resultSz == (int32_t)strlen("Replace xaax x1x x...x."));
|
TEST_ASSERT(resultSz == (int32_t)strlen("Replace xaax x1x x...x."));
|
||||||
@ -834,7 +838,7 @@ static void TestRegexCAPI(void) {
|
|||||||
/* No match. Text should copy to output with no changes. */
|
/* No match. Text should copy to output with no changes. */
|
||||||
status = U_ZERO_ERROR;
|
status = U_ZERO_ERROR;
|
||||||
uregex_setText(re, text2, -1, &status);
|
uregex_setText(re, text2, -1, &status);
|
||||||
resultSz = uregex_replaceFirst(re, replText, -1, buf, sizeof(buf)/2, &status);
|
resultSz = uregex_replaceFirst(re, replText, -1, buf, LENGTHOF(buf), &status);
|
||||||
TEST_ASSERT_SUCCESS(status);
|
TEST_ASSERT_SUCCESS(status);
|
||||||
TEST_ASSERT_STRING("No match here.", buf, TRUE);
|
TEST_ASSERT_STRING("No match here.", buf, TRUE);
|
||||||
TEST_ASSERT(resultSz == (int32_t)strlen("No match here."));
|
TEST_ASSERT(resultSz == (int32_t)strlen("No match here."));
|
||||||
@ -896,10 +900,10 @@ static void TestRegexCAPI(void) {
|
|||||||
int32_t expectedResultSize2;
|
int32_t expectedResultSize2;
|
||||||
int32_t i;
|
int32_t i;
|
||||||
|
|
||||||
u_uastrncpy(text1, "Replace xaax x1x x...x.", sizeof(text1)/2);
|
u_uastrncpy(text1, "Replace xaax x1x x...x.", LENGTHOF(text1));
|
||||||
u_uastrncpy(text2, "No match here.", sizeof(text2)/2);
|
u_uastrncpy(text2, "No match here.", LENGTHOF(text2));
|
||||||
u_uastrncpy(replText, "<$1>", sizeof(replText)/2);
|
u_uastrncpy(replText, "<$1>", LENGTHOF(replText));
|
||||||
u_uastrncpy(replText2, "<<$1>>", sizeof(replText2)/2);
|
u_uastrncpy(replText2, "<<$1>>", LENGTHOF(replText2));
|
||||||
expectedResultSize = strlen(expectedResult);
|
expectedResultSize = strlen(expectedResult);
|
||||||
expectedResultSize2 = strlen(expectedResult2);
|
expectedResultSize2 = strlen(expectedResult2);
|
||||||
|
|
||||||
@ -909,7 +913,7 @@ static void TestRegexCAPI(void) {
|
|||||||
|
|
||||||
/* Normal case, with match */
|
/* Normal case, with match */
|
||||||
uregex_setText(re, text1, -1, &status);
|
uregex_setText(re, text1, -1, &status);
|
||||||
resultSize = uregex_replaceAll(re, replText, -1, buf, sizeof(buf)/2, &status);
|
resultSize = uregex_replaceAll(re, replText, -1, buf, LENGTHOF(buf), &status);
|
||||||
TEST_ASSERT_SUCCESS(status);
|
TEST_ASSERT_SUCCESS(status);
|
||||||
TEST_ASSERT_STRING(expectedResult, buf, TRUE);
|
TEST_ASSERT_STRING(expectedResult, buf, TRUE);
|
||||||
TEST_ASSERT(resultSize == expectedResultSize);
|
TEST_ASSERT(resultSize == expectedResultSize);
|
||||||
@ -917,7 +921,7 @@ static void TestRegexCAPI(void) {
|
|||||||
/* No match. Text should copy to output with no changes. */
|
/* No match. Text should copy to output with no changes. */
|
||||||
status = U_ZERO_ERROR;
|
status = U_ZERO_ERROR;
|
||||||
uregex_setText(re, text2, -1, &status);
|
uregex_setText(re, text2, -1, &status);
|
||||||
resultSize = uregex_replaceAll(re, replText, -1, buf, sizeof(buf)/2, &status);
|
resultSize = uregex_replaceAll(re, replText, -1, buf, LENGTHOF(buf), &status);
|
||||||
TEST_ASSERT_SUCCESS(status);
|
TEST_ASSERT_SUCCESS(status);
|
||||||
TEST_ASSERT_STRING("No match here.", buf, TRUE);
|
TEST_ASSERT_STRING("No match here.", buf, TRUE);
|
||||||
TEST_ASSERT(resultSize == u_strlen(text2));
|
TEST_ASSERT(resultSize == u_strlen(text2));
|
||||||
@ -1001,15 +1005,15 @@ static void TestRegexCAPI(void) {
|
|||||||
re = uregex_openC(".*", 0, 0, &status);
|
re = uregex_openC(".*", 0, 0, &status);
|
||||||
TEST_ASSERT_SUCCESS(status);
|
TEST_ASSERT_SUCCESS(status);
|
||||||
|
|
||||||
u_uastrncpy(text, "whatever", sizeof(text)/2);
|
u_uastrncpy(text, "whatever", LENGTHOF(text));
|
||||||
u_uastrncpy(repl, "some other", sizeof(repl)/2);
|
u_uastrncpy(repl, "some other", LENGTHOF(repl));
|
||||||
uregex_setText(re, text, -1, &status);
|
uregex_setText(re, text, -1, &status);
|
||||||
|
|
||||||
/* match covers whole target string */
|
/* match covers whole target string */
|
||||||
uregex_find(re, 0, &status);
|
uregex_find(re, 0, &status);
|
||||||
TEST_ASSERT_SUCCESS(status);
|
TEST_ASSERT_SUCCESS(status);
|
||||||
bufPtr = buf;
|
bufPtr = buf;
|
||||||
bufCap = sizeof(buf) / 2;
|
bufCap = LENGTHOF(buf);
|
||||||
uregex_appendReplacement(re, repl, -1, &bufPtr, &bufCap, &status);
|
uregex_appendReplacement(re, repl, -1, &bufPtr, &bufCap, &status);
|
||||||
TEST_ASSERT_SUCCESS(status);
|
TEST_ASSERT_SUCCESS(status);
|
||||||
TEST_ASSERT_STRING("some other", buf, TRUE);
|
TEST_ASSERT_STRING("some other", buf, TRUE);
|
||||||
@ -1018,8 +1022,8 @@ static void TestRegexCAPI(void) {
|
|||||||
uregex_find(re, 0, &status);
|
uregex_find(re, 0, &status);
|
||||||
TEST_ASSERT_SUCCESS(status);
|
TEST_ASSERT_SUCCESS(status);
|
||||||
bufPtr = buf;
|
bufPtr = buf;
|
||||||
bufCap = sizeof(buf) / 2;
|
bufCap = LENGTHOF(buf);
|
||||||
u_uastrncpy(repl, "abc\\u0041\\U00000042 \\\\ $ \\abc", sizeof(repl)/2);
|
u_uastrncpy(repl, "abc\\u0041\\U00000042 \\\\ $ \\abc", LENGTHOF(repl));
|
||||||
uregex_appendReplacement(re, repl, -1, &bufPtr, &bufCap, &status);
|
uregex_appendReplacement(re, repl, -1, &bufPtr, &bufCap, &status);
|
||||||
TEST_ASSERT_SUCCESS(status);
|
TEST_ASSERT_SUCCESS(status);
|
||||||
TEST_ASSERT_STRING("abcAB \\ $ abc", buf, TRUE);
|
TEST_ASSERT_STRING("abcAB \\ $ abc", buf, TRUE);
|
||||||
@ -1054,8 +1058,8 @@ static void TestRegexCAPI(void) {
|
|||||||
int32_t spaceNeeded;
|
int32_t spaceNeeded;
|
||||||
int32_t sz;
|
int32_t sz;
|
||||||
|
|
||||||
u_uastrncpy(textToSplit, "first : second: third", sizeof(textToSplit)/2);
|
u_uastrncpy(textToSplit, "first : second: third", LENGTHOF(textToSplit));
|
||||||
u_uastrncpy(text2, "No match here.", sizeof(text2)/2);
|
u_uastrncpy(text2, "No match here.", LENGTHOF(text2));
|
||||||
|
|
||||||
status = U_ZERO_ERROR;
|
status = U_ZERO_ERROR;
|
||||||
re = uregex_openC(":", 0, NULL, &status);
|
re = uregex_openC(":", 0, NULL, &status);
|
||||||
@ -1070,7 +1074,7 @@ static void TestRegexCAPI(void) {
|
|||||||
if (U_SUCCESS(status)) {
|
if (U_SUCCESS(status)) {
|
||||||
memset(fields, -1, sizeof(fields));
|
memset(fields, -1, sizeof(fields));
|
||||||
numFields =
|
numFields =
|
||||||
uregex_split(re, buf, sizeof(buf)/2, &requiredCapacity, fields, 10, &status);
|
uregex_split(re, buf, LENGTHOF(buf), &requiredCapacity, fields, 10, &status);
|
||||||
TEST_ASSERT_SUCCESS(status);
|
TEST_ASSERT_SUCCESS(status);
|
||||||
|
|
||||||
/* The TEST_ASSERT_SUCCESS call above should change too... */
|
/* The TEST_ASSERT_SUCCESS call above should change too... */
|
||||||
@ -1102,7 +1106,7 @@ static void TestRegexCAPI(void) {
|
|||||||
if(U_SUCCESS(status)) {
|
if(U_SUCCESS(status)) {
|
||||||
memset(fields, -1, sizeof(fields));
|
memset(fields, -1, sizeof(fields));
|
||||||
numFields =
|
numFields =
|
||||||
uregex_split(re, buf, sizeof(buf)/2, &requiredCapacity, fields, 2, &status);
|
uregex_split(re, buf, LENGTHOF(buf), &requiredCapacity, fields, 2, &status);
|
||||||
TEST_ASSERT_SUCCESS(status);
|
TEST_ASSERT_SUCCESS(status);
|
||||||
|
|
||||||
/* The TEST_ASSERT_SUCCESS call above should change too... */
|
/* The TEST_ASSERT_SUCCESS call above should change too... */
|
||||||
@ -1160,7 +1164,7 @@ static void TestRegexCAPI(void) {
|
|||||||
int32_t spaceNeeded;
|
int32_t spaceNeeded;
|
||||||
int32_t sz;
|
int32_t sz;
|
||||||
|
|
||||||
u_uastrncpy(textToSplit, "first <tag-a> second<tag-b> third", sizeof(textToSplit)/2);
|
u_uastrncpy(textToSplit, "first <tag-a> second<tag-b> third", LENGTHOF(textToSplit));
|
||||||
|
|
||||||
status = U_ZERO_ERROR;
|
status = U_ZERO_ERROR;
|
||||||
re = uregex_openC("<(.*?)>", 0, NULL, &status);
|
re = uregex_openC("<(.*?)>", 0, NULL, &status);
|
||||||
@ -1172,7 +1176,7 @@ static void TestRegexCAPI(void) {
|
|||||||
if(U_SUCCESS(status)) {
|
if(U_SUCCESS(status)) {
|
||||||
memset(fields, -1, sizeof(fields));
|
memset(fields, -1, sizeof(fields));
|
||||||
numFields =
|
numFields =
|
||||||
uregex_split(re, buf, sizeof(buf)/2, &requiredCapacity, fields, 10, &status);
|
uregex_split(re, buf, LENGTHOF(buf), &requiredCapacity, fields, 10, &status);
|
||||||
TEST_ASSERT_SUCCESS(status);
|
TEST_ASSERT_SUCCESS(status);
|
||||||
|
|
||||||
/* The TEST_ASSERT_SUCCESS call above should change too... */
|
/* The TEST_ASSERT_SUCCESS call above should change too... */
|
||||||
@ -1193,7 +1197,7 @@ static void TestRegexCAPI(void) {
|
|||||||
status = U_ZERO_ERROR;
|
status = U_ZERO_ERROR;
|
||||||
memset(fields, -1, sizeof(fields));
|
memset(fields, -1, sizeof(fields));
|
||||||
numFields =
|
numFields =
|
||||||
uregex_split(re, buf, sizeof(buf)/2, &requiredCapacity, fields, 2, &status);
|
uregex_split(re, buf, LENGTHOF(buf), &requiredCapacity, fields, 2, &status);
|
||||||
TEST_ASSERT_SUCCESS(status);
|
TEST_ASSERT_SUCCESS(status);
|
||||||
|
|
||||||
/* The TEST_ASSERT_SUCCESS call above should change too... */
|
/* The TEST_ASSERT_SUCCESS call above should change too... */
|
||||||
@ -1211,7 +1215,7 @@ static void TestRegexCAPI(void) {
|
|||||||
status = U_ZERO_ERROR;
|
status = U_ZERO_ERROR;
|
||||||
memset(fields, -1, sizeof(fields));
|
memset(fields, -1, sizeof(fields));
|
||||||
numFields =
|
numFields =
|
||||||
uregex_split(re, buf, sizeof(buf)/2, &requiredCapacity, fields, 3, &status);
|
uregex_split(re, buf, LENGTHOF(buf), &requiredCapacity, fields, 3, &status);
|
||||||
TEST_ASSERT_SUCCESS(status);
|
TEST_ASSERT_SUCCESS(status);
|
||||||
|
|
||||||
/* The TEST_ASSERT_SUCCESS call above should change too... */
|
/* The TEST_ASSERT_SUCCESS call above should change too... */
|
||||||
@ -1230,7 +1234,7 @@ static void TestRegexCAPI(void) {
|
|||||||
status = U_ZERO_ERROR;
|
status = U_ZERO_ERROR;
|
||||||
memset(fields, -1, sizeof(fields));
|
memset(fields, -1, sizeof(fields));
|
||||||
numFields =
|
numFields =
|
||||||
uregex_split(re, buf, sizeof(buf)/2, &requiredCapacity, fields, 5, &status);
|
uregex_split(re, buf, LENGTHOF(buf), &requiredCapacity, fields, 5, &status);
|
||||||
TEST_ASSERT_SUCCESS(status);
|
TEST_ASSERT_SUCCESS(status);
|
||||||
|
|
||||||
/* The TEST_ASSERT_SUCCESS call above should change too... */
|
/* The TEST_ASSERT_SUCCESS call above should change too... */
|
||||||
@ -1257,7 +1261,7 @@ static void TestRegexCAPI(void) {
|
|||||||
if(U_SUCCESS(status)) {
|
if(U_SUCCESS(status)) {
|
||||||
memset(fields, -1, sizeof(fields));
|
memset(fields, -1, sizeof(fields));
|
||||||
numFields =
|
numFields =
|
||||||
uregex_split(re, buf, sizeof(buf)/2, &requiredCapacity, fields, 9, &status);
|
uregex_split(re, buf, LENGTHOF(buf), &requiredCapacity, fields, 9, &status);
|
||||||
TEST_ASSERT_SUCCESS(status);
|
TEST_ASSERT_SUCCESS(status);
|
||||||
|
|
||||||
/* The TEST_ASSERT_SUCCESS call above should change too... */
|
/* The TEST_ASSERT_SUCCESS call above should change too... */
|
||||||
@ -1464,8 +1468,8 @@ static void TestUTextAPI(void) {
|
|||||||
TEST_ASSERT_SUCCESS(status);
|
TEST_ASSERT_SUCCESS(status);
|
||||||
TEST_ASSERT(clone3 != NULL);
|
TEST_ASSERT(clone3 != NULL);
|
||||||
|
|
||||||
u_uastrncpy(testString1, "abcccd", sizeof(pat)/2);
|
u_uastrncpy(testString1, "abcccd", LENGTHOF(pat));
|
||||||
u_uastrncpy(testString2, "xxxabcccd", sizeof(pat)/2);
|
u_uastrncpy(testString2, "xxxabcccd", LENGTHOF(pat));
|
||||||
|
|
||||||
status = U_ZERO_ERROR;
|
status = U_ZERO_ERROR;
|
||||||
uregex_setText(clone1, testString1, -1, &status);
|
uregex_setText(clone1, testString1, -1, &status);
|
||||||
@ -1499,7 +1503,7 @@ static void TestUTextAPI(void) {
|
|||||||
UText *resultText;
|
UText *resultText;
|
||||||
const char str_hello[] = { 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x00 }; /* hello */
|
const char str_hello[] = { 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x00 }; /* hello */
|
||||||
const char str_hel[] = { 0x68, 0x65, 0x6c, 0x00 }; /* hel */
|
const char str_hel[] = { 0x68, 0x65, 0x6c, 0x00 }; /* hel */
|
||||||
u_uastrncpy(pat, "hello", sizeof(pat)/2); /* for comparison */
|
u_uastrncpy(pat, "hello", LENGTHOF(pat)); /* for comparison */
|
||||||
status = U_ZERO_ERROR;
|
status = U_ZERO_ERROR;
|
||||||
|
|
||||||
utext_openUTF8(&patternText, str_hello, -1, &status);
|
utext_openUTF8(&patternText, str_hello, -1, &status);
|
||||||
@ -1602,7 +1606,7 @@ static void TestUTextAPI(void) {
|
|||||||
|
|
||||||
status = U_ZERO_ERROR;
|
status = U_ZERO_ERROR;
|
||||||
utext_openUTF8(&text1, str_abcccd, -1, &status);
|
utext_openUTF8(&text1, str_abcccd, -1, &status);
|
||||||
u_uastrncpy(text2Chars, str_abcccxd, sizeof(text2)/2);
|
u_uastrncpy(text2Chars, str_abcccxd, LENGTHOF(text2Chars));
|
||||||
utext_openUChars(&text2, text2Chars, -1, &status);
|
utext_openUChars(&text2, text2Chars, -1, &status);
|
||||||
|
|
||||||
utext_openUTF8(&patternText, str_abcd, -1, &status);
|
utext_openUTF8(&patternText, str_abcd, -1, &status);
|
||||||
@ -1698,7 +1702,7 @@ static void TestUTextAPI(void) {
|
|||||||
{
|
{
|
||||||
UChar text1[50];
|
UChar text1[50];
|
||||||
UBool result;
|
UBool result;
|
||||||
u_uastrncpy(text1, "012rx5rx890rxrx...", sizeof(text1)/2);
|
u_uastrncpy(text1, "012rx5rx890rxrx...", LENGTHOF(text1));
|
||||||
status = U_ZERO_ERROR;
|
status = U_ZERO_ERROR;
|
||||||
re = uregex_openC("rx", 0, NULL, &status);
|
re = uregex_openC("rx", 0, NULL, &status);
|
||||||
|
|
||||||
@ -1762,7 +1766,7 @@ static void TestUTextAPI(void) {
|
|||||||
const char str_interior[] = { 0x20, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x69, 0x6f, 0x72, 0x20, 0x00 }; /* ' interior ' */
|
const char str_interior[] = { 0x20, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x69, 0x6f, 0x72, 0x20, 0x00 }; /* ' interior ' */
|
||||||
|
|
||||||
|
|
||||||
u_uastrncpy(text1, "noise abc interior def, and this is off the end", sizeof(text1)/2);
|
u_uastrncpy(text1, "noise abc interior def, and this is off the end", LENGTHOF(text1));
|
||||||
|
|
||||||
status = U_ZERO_ERROR;
|
status = U_ZERO_ERROR;
|
||||||
re = uregex_openC("abc(.*?)def", 0, NULL, &status);
|
re = uregex_openC("abc(.*?)def", 0, NULL, &status);
|
||||||
@ -1840,8 +1844,8 @@ static void TestUTextAPI(void) {
|
|||||||
const char str_1x[] = { 0x3c, 0x24, 0x31, 0x3e, 0x00 }; /* <$1> */
|
const char str_1x[] = { 0x3c, 0x24, 0x31, 0x3e, 0x00 }; /* <$1> */
|
||||||
const char str_ReplaceAaaBax1xxx[] = { 0x52, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x20, 0x5c, 0x41, 0x61, 0x61, 0x42, 0x24, 0x61, 0x20, 0x78, 0x31, 0x78, 0x20, 0x78, 0x2e, 0x2e, 0x2e, 0x78, 0x2e, 0x00 }; /* Replace \AaaB$a x1x x...x. */
|
const char str_ReplaceAaaBax1xxx[] = { 0x52, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x20, 0x5c, 0x41, 0x61, 0x61, 0x42, 0x24, 0x61, 0x20, 0x78, 0x31, 0x78, 0x20, 0x78, 0x2e, 0x2e, 0x2e, 0x78, 0x2e, 0x00 }; /* Replace \AaaB$a x1x x...x. */
|
||||||
status = U_ZERO_ERROR;
|
status = U_ZERO_ERROR;
|
||||||
u_uastrncpy(text1, "Replace xaax x1x x...x.", sizeof(text1)/2);
|
u_uastrncpy(text1, "Replace xaax x1x x...x.", LENGTHOF(text1));
|
||||||
u_uastrncpy(text2, "No match here.", sizeof(text2)/2);
|
u_uastrncpy(text2, "No match here.", LENGTHOF(text2));
|
||||||
utext_openUTF8(&replText, str_1x, -1, &status);
|
utext_openUTF8(&replText, str_1x, -1, &status);
|
||||||
|
|
||||||
re = uregex_openC("x(.*?)x", 0, NULL, &status);
|
re = uregex_openC("x(.*?)x", 0, NULL, &status);
|
||||||
@ -1886,8 +1890,8 @@ static void TestUTextAPI(void) {
|
|||||||
const char str_Replaceaa1[] = { 0x52, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x20, 0x3c, 0x61, 0x61, 0x3e, 0x20, 0x3c, 0x31, 0x3e, 0x20, 0x3c, 0x2e, 0x2e, 0x2e, 0x3e, 0x2e, 0x00 }; /* Replace <aa> <1> <...>. */
|
const char str_Replaceaa1[] = { 0x52, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x20, 0x3c, 0x61, 0x61, 0x3e, 0x20, 0x3c, 0x31, 0x3e, 0x20, 0x3c, 0x2e, 0x2e, 0x2e, 0x3e, 0x2e, 0x00 }; /* Replace <aa> <1> <...>. */
|
||||||
const char str_Nomatchhere[] = { 0x4e, 0x6f, 0x20, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x20, 0x68, 0x65, 0x72, 0x65, 0x2e, 0x00 }; /* No match here. */
|
const char str_Nomatchhere[] = { 0x4e, 0x6f, 0x20, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x20, 0x68, 0x65, 0x72, 0x65, 0x2e, 0x00 }; /* No match here. */
|
||||||
status = U_ZERO_ERROR;
|
status = U_ZERO_ERROR;
|
||||||
u_uastrncpy(text1, "Replace xaax x1x x...x.", sizeof(text1)/2);
|
u_uastrncpy(text1, "Replace xaax x1x x...x.", LENGTHOF(text1));
|
||||||
u_uastrncpy(text2, "No match here.", sizeof(text2)/2);
|
u_uastrncpy(text2, "No match here.", LENGTHOF(text2));
|
||||||
utext_openUTF8(&replText, str_1, -1, &status);
|
utext_openUTF8(&replText, str_1, -1, &status);
|
||||||
|
|
||||||
re = uregex_openC("x(.*?)x", 0, NULL, &status);
|
re = uregex_openC("x(.*?)x", 0, NULL, &status);
|
||||||
@ -1926,15 +1930,15 @@ static void TestUTextAPI(void) {
|
|||||||
re = uregex_openC(".*", 0, 0, &status);
|
re = uregex_openC(".*", 0, 0, &status);
|
||||||
TEST_ASSERT_SUCCESS(status);
|
TEST_ASSERT_SUCCESS(status);
|
||||||
|
|
||||||
u_uastrncpy(text, "whatever", sizeof(text)/2);
|
u_uastrncpy(text, "whatever", LENGTHOF(text));
|
||||||
u_uastrncpy(repl, "some other", sizeof(repl)/2);
|
u_uastrncpy(repl, "some other", LENGTHOF(repl));
|
||||||
uregex_setText(re, text, -1, &status);
|
uregex_setText(re, text, -1, &status);
|
||||||
|
|
||||||
/* match covers whole target string */
|
/* match covers whole target string */
|
||||||
uregex_find(re, 0, &status);
|
uregex_find(re, 0, &status);
|
||||||
TEST_ASSERT_SUCCESS(status);
|
TEST_ASSERT_SUCCESS(status);
|
||||||
bufPtr = buf;
|
bufPtr = buf;
|
||||||
bufCap = sizeof(buf) / 2;
|
bufCap = LENGTHOF(buf);
|
||||||
uregex_appendReplacement(re, repl, -1, &bufPtr, &bufCap, &status);
|
uregex_appendReplacement(re, repl, -1, &bufPtr, &bufCap, &status);
|
||||||
TEST_ASSERT_SUCCESS(status);
|
TEST_ASSERT_SUCCESS(status);
|
||||||
TEST_ASSERT_STRING("some other", buf, TRUE);
|
TEST_ASSERT_STRING("some other", buf, TRUE);
|
||||||
@ -1943,8 +1947,8 @@ static void TestUTextAPI(void) {
|
|||||||
uregex_find(re, 0, &status);
|
uregex_find(re, 0, &status);
|
||||||
TEST_ASSERT_SUCCESS(status);
|
TEST_ASSERT_SUCCESS(status);
|
||||||
bufPtr = buf;
|
bufPtr = buf;
|
||||||
bufCap = sizeof(buf) / 2;
|
bufCap = LENGTHOF(buf);
|
||||||
u_uastrncpy(repl, "abc\\u0041\\U00000042 \\\\ $ \\abc", sizeof(repl)/2);
|
u_uastrncpy(repl, "abc\\u0041\\U00000042 \\\\ $ \\abc", LENGTHOF(repl));
|
||||||
uregex_appendReplacement(re, repl, -1, &bufPtr, &bufCap, &status);
|
uregex_appendReplacement(re, repl, -1, &bufPtr, &bufCap, &status);
|
||||||
TEST_ASSERT_SUCCESS(status);
|
TEST_ASSERT_SUCCESS(status);
|
||||||
TEST_ASSERT_STRING("abcAB \\ $ abc", buf, TRUE);
|
TEST_ASSERT_STRING("abcAB \\ $ abc", buf, TRUE);
|
||||||
@ -1967,8 +1971,8 @@ static void TestUTextAPI(void) {
|
|||||||
int32_t numFields;
|
int32_t numFields;
|
||||||
int32_t i;
|
int32_t i;
|
||||||
|
|
||||||
u_uastrncpy(textToSplit, "first : second: third", sizeof(textToSplit)/2);
|
u_uastrncpy(textToSplit, "first : second: third", LENGTHOF(textToSplit));
|
||||||
u_uastrncpy(text2, "No match here.", sizeof(text2)/2);
|
u_uastrncpy(text2, "No match here.", LENGTHOF(text2));
|
||||||
|
|
||||||
status = U_ZERO_ERROR;
|
status = U_ZERO_ERROR;
|
||||||
re = uregex_openC(":", 0, NULL, &status);
|
re = uregex_openC(":", 0, NULL, &status);
|
||||||
@ -2043,7 +2047,7 @@ static void TestUTextAPI(void) {
|
|||||||
int32_t numFields;
|
int32_t numFields;
|
||||||
int32_t i;
|
int32_t i;
|
||||||
|
|
||||||
u_uastrncpy(textToSplit, "first <tag-a> second<tag-b> third", sizeof(textToSplit)/2);
|
u_uastrncpy(textToSplit, "first <tag-a> second<tag-b> third", LENGTHOF(textToSplit));
|
||||||
|
|
||||||
status = U_ZERO_ERROR;
|
status = U_ZERO_ERROR;
|
||||||
re = uregex_openC("<(.*?)>", 0, NULL, &status);
|
re = uregex_openC("<(.*?)>", 0, NULL, &status);
|
||||||
@ -2266,5 +2270,60 @@ static void TestBug8421(void) {
|
|||||||
uregex_close(re);
|
uregex_close(re);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static UBool U_CALLCONV FindCallback(const void* context , int64_t matchIndex) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static UBool U_CALLCONV MatchCallback(const void *context, int32_t steps) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void TestBug10815() {
|
||||||
|
/* Bug 10815: uregex_findNext() does not set U_REGEX_STOPPED_BY_CALLER
|
||||||
|
* when the callback function specified by uregex_setMatchCallback() returns FALSE
|
||||||
|
*/
|
||||||
|
URegularExpression *re;
|
||||||
|
UErrorCode status = U_ZERO_ERROR;
|
||||||
|
UChar text[100];
|
||||||
|
|
||||||
|
|
||||||
|
// findNext() with a find progress callback function.
|
||||||
|
|
||||||
|
re = uregex_openC(".z", 0, 0, &status);
|
||||||
|
TEST_ASSERT_SUCCESS(status);
|
||||||
|
|
||||||
|
u_uastrncpy(text, "Hello, World.", LENGTHOF(text));
|
||||||
|
uregex_setText(re, text, -1, &status);
|
||||||
|
TEST_ASSERT_SUCCESS(status);
|
||||||
|
|
||||||
|
uregex_setFindProgressCallback(re, FindCallback, NULL, &status);
|
||||||
|
TEST_ASSERT_SUCCESS(status);
|
||||||
|
|
||||||
|
uregex_findNext(re, &status);
|
||||||
|
TEST_ASSERT(status == U_REGEX_STOPPED_BY_CALLER);
|
||||||
|
|
||||||
|
uregex_close(re);
|
||||||
|
|
||||||
|
// findNext() with a match progress callback function.
|
||||||
|
|
||||||
|
status = U_ZERO_ERROR;
|
||||||
|
re = uregex_openC("((xxx)*)*y", 0, 0, &status);
|
||||||
|
TEST_ASSERT_SUCCESS(status);
|
||||||
|
|
||||||
|
// Pattern + this text gives an exponential time match. Without the callback to stop the match,
|
||||||
|
// it will appear to be stuck in a (near) infinite loop.
|
||||||
|
u_uastrncpy(text, "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", LENGTHOF(text));
|
||||||
|
uregex_setText(re, text, -1, &status);
|
||||||
|
TEST_ASSERT_SUCCESS(status);
|
||||||
|
|
||||||
|
uregex_setMatchCallback(re, MatchCallback, NULL, &status);
|
||||||
|
TEST_ASSERT_SUCCESS(status);
|
||||||
|
|
||||||
|
uregex_findNext(re, &status);
|
||||||
|
TEST_ASSERT(status == U_REGEX_STOPPED_BY_CALLER);
|
||||||
|
|
||||||
|
uregex_close(re);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif /* !UCONFIG_NO_REGULAR_EXPRESSIONS */
|
#endif /* !UCONFIG_NO_REGULAR_EXPRESSIONS */
|
||||||
|
@ -2035,7 +2035,7 @@ void RegexTest::API_Match_UTF8() {
|
|||||||
utext_openUnicodeString(&destText, &dest, &status);
|
utext_openUnicodeString(&destText, &dest, &status);
|
||||||
UText *result;
|
UText *result;
|
||||||
//const char str_0123456789[] = { 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x00 }; /* 0123456789 */
|
//const char str_0123456789[] = { 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x00 }; /* 0123456789 */
|
||||||
// Test shallow-clone API
|
// Test shallow-clone API
|
||||||
int64_t group_len;
|
int64_t group_len;
|
||||||
result = matcher->group((UText *)NULL, group_len, status);
|
result = matcher->group((UText *)NULL, group_len, status);
|
||||||
REGEX_CHECK_STATUS;
|
REGEX_CHECK_STATUS;
|
||||||
@ -4826,6 +4826,9 @@ struct progressCallBackContext {
|
|||||||
void reset(int32_t max) {maxCalls=max; numCalls=0;lastIndex=0;};
|
void reset(int32_t max) {maxCalls=max; numCalls=0;lastIndex=0;};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// call-back function for find().
|
||||||
|
// Return TRUE to continue the find().
|
||||||
|
// Return FALSE to stop the find().
|
||||||
U_CDECL_BEGIN
|
U_CDECL_BEGIN
|
||||||
static UBool U_CALLCONV
|
static UBool U_CALLCONV
|
||||||
testProgressCallBackFn(const void *context, int64_t matchIndex) {
|
testProgressCallBackFn(const void *context, int64_t matchIndex) {
|
||||||
@ -4861,7 +4864,7 @@ void RegexTest::FindProgressCallbacks() {
|
|||||||
const void *returnedContext;
|
const void *returnedContext;
|
||||||
URegexFindProgressCallback *returnedFn;
|
URegexFindProgressCallback *returnedFn;
|
||||||
UErrorCode status = U_ZERO_ERROR;
|
UErrorCode status = U_ZERO_ERROR;
|
||||||
RegexMatcher matcher(UNICODE_STRING_SIMPLE("((.)+\\2)+x"), 0, status); // A pattern that can run long.
|
RegexMatcher matcher(UNICODE_STRING_SIMPLE("((.)\\2)x"), 0, status);
|
||||||
REGEX_CHECK_STATUS;
|
REGEX_CHECK_STATUS;
|
||||||
matcher.setFindProgressCallback(testProgressCallBackFn, &cbInfo, status);
|
matcher.setFindProgressCallback(testProgressCallBackFn, &cbInfo, status);
|
||||||
REGEX_CHECK_STATUS;
|
REGEX_CHECK_STATUS;
|
||||||
@ -4870,10 +4873,10 @@ void RegexTest::FindProgressCallbacks() {
|
|||||||
REGEX_ASSERT(returnedFn == testProgressCallBackFn);
|
REGEX_ASSERT(returnedFn == testProgressCallBackFn);
|
||||||
REGEX_ASSERT(returnedContext == &cbInfo);
|
REGEX_ASSERT(returnedContext == &cbInfo);
|
||||||
|
|
||||||
// A short-running match should NOT invoke the callback.
|
// A find that matches on the initial position does NOT invoke the callback.
|
||||||
status = U_ZERO_ERROR;
|
status = U_ZERO_ERROR;
|
||||||
cbInfo.reset(100);
|
cbInfo.reset(100);
|
||||||
UnicodeString s = "abxxx";
|
UnicodeString s = "aaxxx";
|
||||||
matcher.reset(s);
|
matcher.reset(s);
|
||||||
#if 0
|
#if 0
|
||||||
matcher.setTrace(TRUE);
|
matcher.setTrace(TRUE);
|
||||||
@ -4882,7 +4885,8 @@ void RegexTest::FindProgressCallbacks() {
|
|||||||
REGEX_CHECK_STATUS;
|
REGEX_CHECK_STATUS;
|
||||||
REGEX_ASSERT(cbInfo.numCalls == 0);
|
REGEX_ASSERT(cbInfo.numCalls == 0);
|
||||||
|
|
||||||
// A medium running match that causes matcher.find() to invoke our callback for each index.
|
// A medium running find() that causes matcher.find() to invoke our callback for each index,
|
||||||
|
// but not so many times that we interrupt the operation.
|
||||||
status = U_ZERO_ERROR;
|
status = U_ZERO_ERROR;
|
||||||
s = "aaaaaaaaaaaaaaaaaaab";
|
s = "aaaaaaaaaaaaaaaaaaab";
|
||||||
cbInfo.reset(s.length()); // Some upper limit for number of calls that is greater than size of our input string
|
cbInfo.reset(s.length()); // Some upper limit for number of calls that is greater than size of our input string
|
||||||
@ -4897,22 +4901,21 @@ void RegexTest::FindProgressCallbacks() {
|
|||||||
cbInfo.reset(s1.length() - 5); // Bail early somewhere near the end of input string
|
cbInfo.reset(s1.length() - 5); // Bail early somewhere near the end of input string
|
||||||
matcher.reset(s1);
|
matcher.reset(s1);
|
||||||
REGEX_ASSERT(matcher.find(0, status)==FALSE);
|
REGEX_ASSERT(matcher.find(0, status)==FALSE);
|
||||||
REGEX_CHECK_STATUS;
|
REGEX_ASSERT(status == U_REGEX_STOPPED_BY_CALLER);
|
||||||
REGEX_ASSERT(cbInfo.numCalls == s1.length() - 5);
|
REGEX_ASSERT(cbInfo.numCalls == s1.length() - 5);
|
||||||
|
|
||||||
#if 0
|
|
||||||
// Now a match that will succeed, but after an interruption
|
// Now a match that will succeed, but after an interruption
|
||||||
status = U_ZERO_ERROR;
|
status = U_ZERO_ERROR;
|
||||||
UnicodeString s2 = "aaaaaaaaaaaaaa aaaaaaaaab xxx";
|
UnicodeString s2 = "aaaaaaaaaaaaaa aaaaaaaaab xxx";
|
||||||
cbInfo.reset(s2.length() - 10); // Bail early somewhere near the end of input string
|
cbInfo.reset(s2.length() - 10); // Bail early somewhere near the end of input string
|
||||||
matcher.reset(s2);
|
matcher.reset(s2);
|
||||||
REGEX_ASSERT(matcher.find(0, status)==FALSE);
|
REGEX_ASSERT(matcher.find(0, status)==FALSE);
|
||||||
REGEX_CHECK_STATUS;
|
REGEX_ASSERT(status == U_REGEX_STOPPED_BY_CALLER);
|
||||||
// Now retry the match from where left off
|
// Now retry the match from where left off
|
||||||
cbInfo.maxCalls = 100; // No callback limit
|
cbInfo.maxCalls = 100; // No callback limit
|
||||||
|
status = U_ZERO_ERROR;
|
||||||
REGEX_ASSERT(matcher.find(cbInfo.lastIndex, status));
|
REGEX_ASSERT(matcher.find(cbInfo.lastIndex, status));
|
||||||
REGEX_CHECK_STATUS;
|
REGEX_CHECK_STATUS;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user