diff --git a/ChangeLog b/ChangeLog index 1ab817b12..5d0543192 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-12-16 Richard Frith-Macdonald + + * Source/NSRegularExpression.m: Move towards coding standards compliance + * Source/GSICUString.m: ditto + 2010-12-16 Richard Frith-Macdonald * configure.ac: Remove redundant/incorrect define of HAVE_ICU. diff --git a/Source/GSICUString.m b/Source/GSICUString.m index 7adb77767..c4e811da4 100644 --- a/Source/GSICUString.m +++ b/Source/GSICUString.m @@ -1,3 +1,27 @@ +/** Implementation of GSICUString for GNUStep + + Copyright (C) 2010 Free Software Foundation, Inc. + + This file is part of the GNUstep Base Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. + + $Date: 2010-09-18 16:09:58 +0100 (Sat, 18 Sep 2010) $ $Revision: 31371 $ + */ + #import "common.h" #if GS_USE_ICU == 1 #import "GSICUString.h" @@ -13,9 +37,10 @@ static const NSUInteger chunkSize = 32; /** * Returns the number of UTF16 characters in a UText backed by an NSString. */ -static int64_t UTextNSStringNativeLength(UText *ut) +static int64_t +UTextNSStringNativeLength(UText *ut) { - return [(NSString*)ut->p length]; + return [(NSString*)ut->p length]; } @@ -23,152 +48,174 @@ static int64_t UTextNSStringNativeLength(UText *ut) * Loads a group of characters into the buffer that can be directly accessed by * users of the UText. This is used for iteration but UText users. */ -UBool UTextNSStringAccess(UText *ut, int64_t nativeIndex, UBool forward) +UBool +UTextNSStringAccess(UText *ut, int64_t nativeIndex, UBool forward) { - NSString *str = ut->p; - NSUInteger length = [str length]; - if (nativeIndex >= length) { return FALSE; } - // Special case if the chunk already contains this index - if (nativeIndex >= ut->chunkNativeStart - && nativeIndex < (ut->chunkNativeStart + ut->chunkLength)) + NSString *str = (NSString*)ut->p; + NSUInteger length = [str length]; + NSRange r; + + if (nativeIndex >= length) + { + return FALSE; + } + + /* Special case if the chunk already contains this index + */ + if (nativeIndex >= ut->chunkNativeStart + && nativeIndex < (ut->chunkNativeStart + ut->chunkLength)) + { + ut->chunkOffset = nativeIndex - ut->chunkNativeStart; + return TRUE; + } + r = NSMakeRange(nativeIndex, chunkSize); + forward = TRUE; + if (forward) + { + if (nativeIndex + chunkSize > length) { - ut->chunkOffset = nativeIndex - ut->chunkNativeStart; - return TRUE; + r.length = length - nativeIndex; } - NSRange r = {nativeIndex, chunkSize}; - forward = TRUE; - if (forward) + } + else + { + if (nativeIndex - chunkSize > 0) { - if (nativeIndex + chunkSize > length) - { - r.length = length - nativeIndex; - } + r.location = nativeIndex - chunkSize; + r.length = chunkSize; } - else + else { - if (nativeIndex - chunkSize > 0) - { - r.location = nativeIndex - chunkSize; - r.length = chunkSize; - } - else - { - r.location = 0; - r.length = chunkSize - nativeIndex; - } + r.location = 0; + r.length = chunkSize - nativeIndex; } - [str getCharacters: ut->pExtra range: r]; - ut->chunkNativeStart = r.location; - ut->chunkNativeLimit = r.location + r.length; - ut->chunkLength = r.length; - ut->chunkOffset = 0; - return TRUE; + } + [str getCharacters: ut->pExtra range: r]; + ut->chunkNativeStart = r.location; + ut->chunkNativeLimit = r.location + r.length; + ut->chunkLength = r.length; + ut->chunkOffset = 0; + return TRUE; } /** * Replaces characters in an NSString-backed UText. */ -static int32_t UTextNSMutableStringReplace(UText *ut, - int64_t nativeStart, - int64_t nativeLimit, - const UChar *replacementText, - int32_t replacmentLength, - UErrorCode *status) +static int32_t +UTextNSMutableStringReplace(UText *ut, + int64_t nativeStart, + int64_t nativeLimit, + const UChar *replacementText, + int32_t replacmentLength, + UErrorCode *status) { - NSMutableString *str = (NSMutableString*)ut->p; - NSRange r = NSMakeRange(nativeStart, nativeLimit-nativeStart); - NSString *replacement = [NSString alloc]; - if (replacmentLength < 0) - { - replacement = [replacement initWithCString: (const char*)replacementText - encoding: NSUTF16StringEncoding]; - } - else - { - replacement = [replacement initWithCharactersNoCopy: (unichar*)replacementText - length: replacmentLength - freeWhenDone: NO]; - } - [str replaceCharactersInRange: r withString: replacement]; + NSMutableString *str = (NSMutableString*)ut->p; + NSRange r = NSMakeRange(nativeStart, nativeLimit-nativeStart); + NSString *replacement = [NSString alloc]; - // Setting the chunk length to 0 here forces UTextNSStringAccess to fetch - // the data from the string object. - ut->chunkLength = 0; - UTextNSStringAccess(ut, r.location + [replacement length] + 1, TRUE); - ut->chunkOffset++; - - [replacement release]; - if (NULL != status) - { - *status = 0; - } - return 0; + if (replacmentLength < 0) + { + replacement = [replacement initWithCString: (const char*)replacementText + encoding: NSUTF16StringEncoding]; + } + else + { + replacement = [replacement initWithCharactersNoCopy: (unichar*)replacementText + length: replacmentLength + freeWhenDone: NO]; + } + [str replaceCharactersInRange: r withString: replacement]; + + // Setting the chunk length to 0 here forces UTextNSStringAccess to fetch + // the data from the string object. + ut->chunkLength = 0; + UTextNSStringAccess(ut, r.location + [replacement length] + 1, TRUE); + ut->chunkOffset++; + + [replacement release]; + if (NULL != status) + { + *status = 0; + } + return 0; } /** * Reads some characters. This is roughly analogous to NSString's * -getCharacters:range:. */ -static int32_t UTextNSStringExtract(UText *ut, - int64_t nativeStart, - int64_t nativeLimit, - UChar *dest, - int32_t destCapacity, - UErrorCode *status) +static int32_t +UTextNSStringExtract(UText *ut, + int64_t nativeStart, + int64_t nativeLimit, + UChar *dest, + int32_t destCapacity, + UErrorCode *status) { - // If we're loading no characters, we are expected to return the number of - // characters that we could load if requested. - if (destCapacity == 0) - { - return nativeLimit - nativeStart; - } - NSString *str = ut->p; - NSUInteger length = [str length]; - if (nativeLimit > length) - { - nativeLimit = length; - } - NSRange r = NSMakeRange(nativeStart, nativeLimit - nativeStart ); - if (destCapacity < r.length) - { - r.length = destCapacity; - } - [str getCharacters: dest range: r]; - if (destCapacity > r.length) - { - dest[r.length] = 0; - } - return r.length; + NSString *str; + NSUInteger length; + NSRange r; + + /* If we're loading no characters, we are expected to return the number of + * characters that we could load if requested. + */ + if (destCapacity == 0) + { + return nativeLimit - nativeStart; + } + str = (NSString*)ut->p; + length = [str length]; + if (nativeLimit > length) + { + nativeLimit = length; + } + r = NSMakeRange(nativeStart, nativeLimit - nativeStart ); + if (destCapacity < r.length) + { + r.length = destCapacity; + } + [str getCharacters: dest range: r]; + if (destCapacity > r.length) + { + dest[r.length] = 0; + } + return r.length; } /** * Copy or move some characters within a UText. */ void UTextNSStringCopy(UText *ut, - int64_t nativeStart, - int64_t nativeLimit, - int64_t nativeDest, - UBool move, - UErrorCode *status) + int64_t nativeStart, + int64_t nativeLimit, + int64_t nativeDest, + UBool move, + UErrorCode *status) { - NSMutableString *str = ut->p; - NSUInteger length = [str length]; - if (nativeLimit > length) + NSMutableString *str = (NSMutableString*)ut->p; + NSUInteger length = [str length]; + NSRange r; + NSString *substr; + + if (nativeLimit > length) + { + nativeLimit = length; + } + r = NSMakeRange(nativeStart, nativeLimit - nativeStart); + substr = [str substringWithRange: r]; + [str insertString: substr atIndex: nativeDest]; + if (move) + { + if (nativeDest < r.location) { - nativeLimit = length; + r.location += r.length; } - NSRange r = NSMakeRange(nativeStart, nativeLimit - nativeStart); - NSString *substr = [str substringWithRange: r]; - [str insertString: substr atIndex: nativeDest]; - if (move) - { - if (nativeDest < r.location) - { - r.location += r.length; - } - [str deleteCharactersInRange: r]; - } - if (NULL != status) { *status = 0; } + [str deleteCharactersInRange: r]; + } + if (NULL != status) + { + *status = 0; + } } @@ -177,11 +224,12 @@ void UTextNSStringCopy(UText *ut, * be allocated on the stack, or reused by different storage implementations, * this does not destroy the UText itself. */ -static void UTextNStringClose(UText *ut) +static void +UTextNStringClose(UText *ut) { - ut->chunkContents = NULL; - [(NSString*)ut->p release]; - ut->p = NULL; + ut->chunkContents = NULL; + [(NSString*)ut->p release]; + ut->p = NULL; } /** @@ -190,41 +238,46 @@ static void UTextNStringClose(UText *ut) * Typically, this should not actually copy the underlying storage, because it * is immutable. */ -UText* UTextNSStringClone(UText *dest, - const UText *src, - UBool deep, - UErrorCode *status) +UText* +UTextNSStringClone(UText *dest, + const UText *src, + UBool deep, + UErrorCode *status) { - NSString *str = src->p; - if (deep) - { - str = [[str copy] autorelease]; - } - return UTextInitWithNSString(dest, str); + NSString *str = (NSString*)src->p; + + if (deep) + { + str = [[str copy] autorelease]; + } + return UTextInitWithNSString(dest, str); } /** * Copies the UText object, optionally copying the NSMutableString. */ -UText* UTextNSMutableStringClone(UText *dest, - const UText *src, - UBool deep, - UErrorCode *status) +UText* +UTextNSMutableStringClone(UText *dest, + const UText *src, + UBool deep, + UErrorCode *status) { - NSMutableString *str = src->p; - if (deep) - { - str = [str mutableCopy]; - } - return UTextInitWithNSMutableString(dest, str); + NSMutableString *str = (NSMutableString*)src->p; + + if (deep) + { + str = [str mutableCopy]; + } + return UTextInitWithNSMutableString(dest, str); } /** * Returns the index of the current character in the temporary buffer. */ -int64_t UTextNSStringMapOffsetToNative(const UText *ut) +int64_t +UTextNSStringMapOffsetToNative(const UText *ut) { - return ut->chunkNativeStart + ut->chunkOffset; + return ut->chunkNativeStart + ut->chunkOffset; } /** @@ -232,18 +285,18 @@ int64_t UTextNSStringMapOffsetToNative(const UText *ut) */ static const UTextFuncs NSStringFuncs = { - sizeof(UTextFuncs), // Table size - 0, 0, 0, // Reserved - UTextNSStringClone, - UTextNSStringNativeLength, - UTextNSStringAccess, - UTextNSStringExtract, - 0, // Replace - UTextNSStringCopy, - UTextNSStringMapOffsetToNative, - 0, // Map to UTF16 - UTextNStringClose, - 0, 0, 0 // Spare + sizeof(UTextFuncs), // Table size + 0, 0, 0, // Reserved + UTextNSStringClone, + UTextNSStringNativeLength, + UTextNSStringAccess, + UTextNSStringExtract, + 0, // Replace + UTextNSStringCopy, + UTextNSStringMapOffsetToNative, + 0, // Map to UTF16 + UTextNStringClose, + 0, 0, 0 // Spare }; /** @@ -251,131 +304,157 @@ static const UTextFuncs NSStringFuncs = */ static const UTextFuncs NSMutableStringFuncs = { - sizeof(UTextFuncs), // Table size - 0, 0, 0, // Reserved - UTextNSMutableStringClone, - UTextNSStringNativeLength, - UTextNSStringAccess, - UTextNSStringExtract, - UTextNSMutableStringReplace, - UTextNSStringCopy, - UTextNSStringMapOffsetToNative, - 0, // Map to UTF16 - UTextNStringClose, - 0, 0, 0 // Spare + sizeof(UTextFuncs), // Table size + 0, 0, 0, // Reserved + UTextNSMutableStringClone, + UTextNSStringNativeLength, + UTextNSStringAccess, + UTextNSStringExtract, + UTextNSMutableStringReplace, + UTextNSStringCopy, + UTextNSStringMapOffsetToNative, + 0, // Map to UTF16 + UTextNStringClose, + 0, 0, 0 // Spare }; -UText* UTextInitWithNSMutableString(UText *txt, NSMutableString *str) +UText* +UTextInitWithNSMutableString(UText *txt, NSMutableString *str) { - UErrorCode status = 0; - txt = utext_setup(txt, chunkSize * sizeof(unichar), &status); + UErrorCode status = 0; - if (U_FAILURE(status)) { return NULL; } + txt = utext_setup(txt, chunkSize * sizeof(unichar), &status); - txt->p = [str retain]; - txt->pFuncs = &NSMutableStringFuncs; - txt->chunkContents = txt->pExtra; - txt->nativeIndexingLimit = INT32_MAX; + if (U_FAILURE(status)) + { + return NULL; + } - txt->providerProperties = 1<p = [str retain]; + txt->pFuncs = &NSMutableStringFuncs; + txt->chunkContents = txt->pExtra; + txt->nativeIndexingLimit = INT32_MAX; - return txt; + txt->providerProperties = 1<p = [str retain]; - txt->pFuncs = &NSStringFuncs; - txt->chunkContents = txt->pExtra; - txt->nativeIndexingLimit = INT32_MAX; + txt->p = [str retain]; + txt->pFuncs = &NSStringFuncs; + txt->chunkContents = txt->pExtra; + txt->nativeIndexingLimit = INT32_MAX; - return txt; + return txt; } @implementation GSUTextString -- init +- (id) init { - if (nil == (self = [super init])) { return nil; } - UText t = UTEXT_INITIALIZER; - memcpy(&txt, &t, sizeof(t)); - return self; + if (nil != (self = [super init])) + { + UText t = UTEXT_INITIALIZER; + + memcpy(&txt, &t, sizeof(t)); + } + return self; } -- (NSUInteger)length + +- (NSUInteger) length { - return utext_nativeLength(&txt); + return utext_nativeLength(&txt); } -- (unichar)characterAtIndex: (NSUInteger)idx + +- (unichar) characterAtIndex: (NSUInteger)idx { - unichar c; - [self getCharacters: &c range: NSMakeRange(idx, 1)]; - return c; + unichar c; + + [self getCharacters: &c range: NSMakeRange(idx, 1)]; + return c; } -- (void)getCharacters: (unichar*)buffer range: (NSRange)r + +- (void) getCharacters: (unichar*)buffer range: (NSRange)r { - UErrorCode status = 0; - utext_extract(&txt, r.location, r.location+r.length, buffer, r.length, - &status); - if (U_FAILURE(status)) - { - _NSRangeExceptionRaise(); - } + UErrorCode status = 0; + + utext_extract(&txt, r.location, r.location+r.length, buffer, r.length, + &status); + if (U_FAILURE(status)) + { + _NSRangeExceptionRaise(); + } } -- (void)dealloc + +- (void) dealloc { - utext_close(&txt); - [super dealloc]; + utext_close(&txt); + [super dealloc]; } @end @implementation GSUTextMutableString -- init +- (id) init { - if (nil == (self = [super init])) { return nil; } - UText t = UTEXT_INITIALIZER; - memcpy(&txt, &t, sizeof(t)); - return self; -} -- (NSUInteger)length -{ - return utext_nativeLength(&txt); -} -- (unichar)characterAtIndex: (NSUInteger)idx -{ - unichar c; - [self getCharacters: &c range: NSMakeRange(idx, 1)]; - return c; -} -- (void)getCharacters: (unichar*)buffer range: (NSRange)r -{ - UErrorCode status = 0; - utext_extract(&txt, r.location, r.location+r.length, buffer, r.length, - &status); - if (U_FAILURE(status)) - { - _NSRangeExceptionRaise(); - } -} -- (void)replaceCharactersInRange: (NSRange)r - withString: (NSString*)aString -{ - NSUInteger size = [aString length]; - UErrorCode status = 0; - TEMP_BUFFER(buffer, size); - [aString getCharacters: buffer range: NSMakeRange(0, size)]; + if (nil != (self = [super init])) + { + UText t = UTEXT_INITIALIZER; - utext_replace(&txt, r.location, r.location + r.length, buffer, size, - &status); + memcpy(&txt, &t, sizeof(t)); + } + return self; } -- (void)dealloc +- (NSUInteger) length { - utext_close(&txt); - [super dealloc]; + return utext_nativeLength(&txt); +} + +- (unichar) characterAtIndex: (NSUInteger)idx +{ + unichar c; + [self getCharacters: &c range: NSMakeRange(idx, 1)]; + return c; +} + +- (void) getCharacters: (unichar*)buffer range: (NSRange)r +{ + UErrorCode status = 0; + + utext_extract(&txt, r.location, r.location+r.length, buffer, r.length, + &status); + if (U_FAILURE(status)) + { + _NSRangeExceptionRaise(); + } +} + +- (void) replaceCharactersInRange: (NSRange)r + withString: (NSString*)aString +{ + NSUInteger size = [aString length]; + UErrorCode status = 0; + + TEMP_BUFFER(buffer, size); + [aString getCharacters: buffer range: NSMakeRange(0, size)]; + + utext_replace(&txt, r.location, r.location + r.length, buffer, size, &status); +} + +- (void) dealloc +{ + utext_close(&txt); + [super dealloc]; } @end #endif // HAV_ICU diff --git a/Source/NSRegularExpression.m b/Source/NSRegularExpression.m index 931ed3647..521d0ac55 100644 --- a/Source/NSRegularExpression.m +++ b/Source/NSRegularExpression.m @@ -1,4 +1,29 @@ -#include "common.h" +/** Implementation of NSRegualrExpression for GNUStep + + Copyright (C) 2010 Free Software Foundation, Inc. + + This file is part of the GNUstep Base Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. + + $Date: 2010-09-18 16:09:58 +0100 (Sat, 18 Sep 2010) $ $Revision: 31371 $ + */ + +#import "common.h" + #if GS_USE_ICU == 1 #include "unicode/uregex.h" #if (U_ICU_VERSION_MAJOR_NUM > 4 || (U_ICU_VERSION_MAJOR_NUM == 4 && U_ICU_VERSION_MINOR_NUM >= 4)) @@ -18,90 +43,105 @@ * in theory use the libicu values directly (that would be sensible), but that * would break any code that didn't correctly use the symbolic constants. */ -uint32_t NSRegularExpressionOptionsToURegexpFlags(NSRegularExpressionOptions opts) +uint32_t +NSRegularExpressionOptionsToURegexpFlags(NSRegularExpressionOptions opts) { - uint32_t flags = 0; - if (opts & NSRegularExpressionCaseInsensitive) - { - flags |= UREGEX_CASE_INSENSITIVE; - } - if (opts & NSRegularExpressionAllowCommentsAndWhitespace) - { - flags |= UREGEX_COMMENTS; - } - if (opts & NSRegularExpressionIgnoreMetacharacters) - { - flags |= UREGEX_LITERAL; - } - if (opts & NSRegularExpressionDotMatchesLineSeparators) - { - flags |= UREGEX_DOTALL; - } - if (opts & NSRegularExpressionAnchorsMatchLines) - { - flags |= UREGEX_MULTILINE; - } - if (opts & NSRegularExpressionUseUnixLineSeparators) - { - flags |= UREGEX_UNIX_LINES; - } - if (opts & NSRegularExpressionUseUnicodeWordBoundaries) - { - flags |= UREGEX_UWORD; - } - return flags; + uint32_t flags = 0; + + if (opts & NSRegularExpressionCaseInsensitive) + { + flags |= UREGEX_CASE_INSENSITIVE; + } + if (opts & NSRegularExpressionAllowCommentsAndWhitespace) + { + flags |= UREGEX_COMMENTS; + } + if (opts & NSRegularExpressionIgnoreMetacharacters) + { + flags |= UREGEX_LITERAL; + } + if (opts & NSRegularExpressionDotMatchesLineSeparators) + { + flags |= UREGEX_DOTALL; + } + if (opts & NSRegularExpressionAnchorsMatchLines) + { + flags |= UREGEX_MULTILINE; + } + if (opts & NSRegularExpressionUseUnixLineSeparators) + { + flags |= UREGEX_UNIX_LINES; + } + if (opts & NSRegularExpressionUseUnicodeWordBoundaries) + { + flags |= UREGEX_UWORD; + } + return flags; } @implementation NSRegularExpression -+ (NSRegularExpression*)regularExpressionWithPattern: (NSString*)aPattern - options: (NSRegularExpressionOptions)opts - error: (NSError**)e + ++ (NSRegularExpression*) regularExpressionWithPattern: (NSString*)aPattern + options: (NSRegularExpressionOptions)opts + error: (NSError**)e { - return [[[self alloc] initWithPattern: aPattern options: opts error: e] autorelease]; -} -- initWithPattern: (NSString*)aPattern - options: (NSRegularExpressionOptions)opts - error: (NSError**)e -{ - uint32_t flags = NSRegularExpressionOptionsToURegexpFlags(opts); - UText p = UTEXT_INITIALIZER; - UParseError pe = {0}; - UErrorCode s = 0; - UTextInitWithNSString(&p, aPattern); - regex = uregex_openUText(&p, flags, &pe, &s); - utext_close(&p); - if (U_FAILURE(s)) - { - // FIXME: Do something sensible with the error parameter. - [self release]; - return nil; - } - options = opts; - return self; -} -- (NSString*)pattern -{ - UErrorCode s = 0; - UText *t = uregex_patternUText(regex, &s); - GSUTextString *str = NULL; - if (U_FAILURE(s)) - { - return nil; - } - str = [GSUTextString new]; - utext_clone(&str->txt, t, FALSE, TRUE, &s); - utext_close(t); - return [str autorelease]; + return [[[self alloc] initWithPattern: aPattern + options: opts + error: e] autorelease]; } -static UBool callback(const void *context, int32_t steps) +- (id) initWithPattern: (NSString*)aPattern + options: (NSRegularExpressionOptions)opts + error: (NSError**)e { - BOOL stop = NO; - GSRegexBlock block = (GSRegexBlock)context; - if (NULL == context) { return FALSE; } - CALL_BLOCK(block, nil, NSMatchingProgress, &stop); - return stop; + uint32_t flags = NSRegularExpressionOptionsToURegexpFlags(opts); + UText p = UTEXT_INITIALIZER; + UParseError pe = {0}; + UErrorCode s = 0; + + UTextInitWithNSString(&p, aPattern); + regex = uregex_openUText(&p, flags, &pe, &s); + utext_close(&p); + if (U_FAILURE(s)) + { + // FIXME: Do something sensible with the error parameter. + [self release]; + return nil; + } + options = opts; + return self; } + +- (NSString*) pattern +{ + UErrorCode s = 0; + UText *t = uregex_patternUText(regex, &s); + GSUTextString *str = NULL; + + if (U_FAILURE(s)) + { + return nil; + } + str = [GSUTextString new]; + utext_clone(&str->txt, t, FALSE, TRUE, &s); + utext_close(t); + return [str autorelease]; +} + +static UBool +callback(const void *context, int32_t steps) +{ + BOOL stop = NO; + GSRegexBlock block = (GSRegexBlock)context; + + if (NULL == context) + { + return FALSE; + } + CALL_BLOCK(block, nil, NSMatchingProgress, &stop); + return stop; +} + /** * Sets up a libicu regex object for use. Note: the documentation states that * NSRegularExpression must be thread safe. To accomplish this, we store a @@ -110,416 +150,474 @@ static UBool callback(const void *context, int32_t steps) * NSRegularExpression, is stateful, and sharing this state between threads * would break concurrent calls. */ -static URegularExpression *setupRegex(URegularExpression *regex, - NSString *string, - UText *txt, - NSMatchingOptions options, - NSRange range, - GSRegexBlock block) +static URegularExpression * +setupRegex(URegularExpression *regex, + NSString *string, + UText *txt, + NSMatchingOptions options, + NSRange range, + GSRegexBlock block) { - UErrorCode s = 0; - URegularExpression *r = uregex_clone(regex, &s); - if (options & NSMatchingReportProgress) - { - uregex_setMatchCallback(r, callback, block, &s); - } - UTextInitWithNSString(txt, string); - uregex_setUText(r, txt, &s); - uregex_setRegion(r, range.location, range.location+range.length, &s); - if (options & NSMatchingWithoutAnchoringBounds) - { - uregex_useAnchoringBounds(r, FALSE, &s); - } - if (options & NSMatchingWithTransparentBounds) - { - uregex_useTransparentBounds(r, TRUE, &s); - } - if (U_FAILURE(s)) - { - uregex_close(r); - return NULL; - } - return r; -} -static uint32_t prepareResult(NSRegularExpression *regex, - URegularExpression *r, - NSRangePointer ranges, - NSUInteger groups, - UErrorCode *s) -{ - uint32_t flags = 0; - NSUInteger i = 0; - for (i = 0 ; itxt, output, TRUE, TRUE, &s); - [string setString: ret]; - [ret release]; - uregex_close(r); + UTextInitWithNSString(&replacement, template); - utext_close(&txt); - utext_close(output); - utext_close(&replacement); - return results; + output = uregex_replaceAllUText(r, &replacement, NULL, &s); + utext_clone(&ret->txt, output, TRUE, TRUE, &s); + [string setString: ret]; + [ret release]; + uregex_close(r); + + utext_close(&txt); + utext_close(output); + utext_close(&replacement); + return results; } -- (NSString*)stringByReplacingMatchesInString: (NSString*)string - options: (NSMatchingOptions)opts - range: (NSRange)range - withTemplate: (NSString*)template +- (NSString*) stringByReplacingMatchesInString: (NSString*)string + options: (NSMatchingOptions)opts + range: (NSRange)range + withTemplate: (NSString*)template { - UErrorCode s = 0; - UText txt = UTEXT_INITIALIZER; - UText replacement = UTEXT_INITIALIZER; - UText *output = NULL; - GSUTextString *ret = [GSUTextString new]; - URegularExpression *r = setupRegex(regex, string, &txt, opts, range, 0); - UTextInitWithNSString(&replacement, template); + UErrorCode s = 0; + UText txt = UTEXT_INITIALIZER; + UText replacement = UTEXT_INITIALIZER; + UText *output = NULL; + GSUTextString *ret = [GSUTextString new]; + URegularExpression *r = setupRegex(regex, string, &txt, opts, range, 0); + UTextInitWithNSString(&replacement, template); - output = uregex_replaceAllUText(r, &replacement, NULL, &s); - utext_clone(&ret->txt, output, TRUE, TRUE, &s); - uregex_close(r); + output = uregex_replaceAllUText(r, &replacement, NULL, &s); + utext_clone(&ret->txt, output, TRUE, TRUE, &s); + uregex_close(r); - utext_close(&txt); - utext_close(output); - utext_close(&replacement); - return ret; + utext_close(&txt); + utext_close(output); + utext_close(&replacement); + return ret; } -- (NSString*)replacementStringForResult: (NSTextCheckingResult*)result - inString: (NSString*)string - offset: (NSInteger)offset - template: (NSString*)template +- (NSString*) replacementStringForResult: (NSTextCheckingResult*)result + inString: (NSString*)string + offset: (NSInteger)offset + template: (NSString*)template { - UErrorCode s = 0; - UText txt = UTEXT_INITIALIZER; - UText replacement = UTEXT_INITIALIZER; - UText *output = NULL; - GSUTextString *ret = [GSUTextString new]; - NSRange range = [result range]; - URegularExpression *r = setupRegex(regex, - [string substringWithRange: range], - &txt, - 0, - NSMakeRange(0, range.length), - 0); - UTextInitWithNSString(&replacement, template); + UErrorCode s = 0; + UText txt = UTEXT_INITIALIZER; + UText replacement = UTEXT_INITIALIZER; + UText *output = NULL; + GSUTextString *ret = [GSUTextString new]; + NSRange range = [result range]; + URegularExpression *r = setupRegex(regex, + [string substringWithRange: range], + &txt, + 0, + NSMakeRange(0, range.length), + 0); + UTextInitWithNSString(&replacement, template); - output = uregex_replaceFirstUText(r, &replacement, NULL, &s); - utext_clone(&ret->txt, output, TRUE, TRUE, &s); - uregex_close(r); + output = uregex_replaceFirstUText(r, &replacement, NULL, &s); + utext_clone(&ret->txt, output, TRUE, TRUE, &s); + uregex_close(r); - utext_close(&txt); - utext_close(output); - utext_close(&replacement); - return ret; + utext_close(&txt); + utext_close(output); + utext_close(&replacement); + return ret; } -- (NSRegularExpressionOptions)options -{ - return options; -} -- (NSUInteger)numberOfCaptureGroups -{ - UErrorCode s = 0; - return uregex_groupCount(regex, &s); -} -- (void)dealloc -{ - uregex_close(regex); - [super dealloc]; -} -- (void)encodeWithCoder: (NSCoder*)aCoder -{ - if ([aCoder allowsKeyedCoding]) - { - [aCoder encodeInteger: options forKey: @"options"]; - [aCoder encodeObject: [self pattern] forKey: @"pattern"]; - } - else - { - [aCoder encodeValueOfObjCType: @encode(NSRegularExpressionOptions) at: &options]; - [aCoder encodeObject: [self pattern]]; - } -} -- initWithCoder: (NSCoder*)aCoder -{ - NSString *pattern; - if ([aCoder allowsKeyedCoding]) - { - options = [aCoder decodeIntegerForKey: @"options"]; - pattern = [aCoder decodeObjectForKey: @"pattern"]; - } - else - { - [aCoder decodeValueOfObjCType: @encode(NSRegularExpressionOptions) at: &options]; - pattern = [aCoder decodeObject]; - } - return [self initWithPattern: pattern options: options error: NULL]; -} -- copyWithZone: (NSZone*)aZone -{ - NSRegularExpressionOptions opts = options; - UErrorCode s = 0; - URegularExpression *r = uregex_clone(regex, &s); - if (0 != s) { return nil; } - self = [[self class] allocWithZone: aZone]; - if (nil == self) { return nil; } - options = opts; - regex = r; - return self; +- (NSRegularExpressionOptions) options +{ + return options; +} + +- (NSUInteger) numberOfCaptureGroups +{ + UErrorCode s = 0; + return uregex_groupCount(regex, &s); +} + +- (void) dealloc +{ + uregex_close(regex); + [super dealloc]; +} + +- (void) encodeWithCoder: (NSCoder*)aCoder +{ + if ([aCoder allowsKeyedCoding]) + { + [aCoder encodeInteger: options forKey: @"options"]; + [aCoder encodeObject: [self pattern] forKey: @"pattern"]; + } + else + { + [aCoder encodeValueOfObjCType: @encode(NSRegularExpressionOptions) + at: &options]; + [aCoder encodeObject: [self pattern]]; + } +} + +- (id) initWithCoder: (NSCoder*)aCoder +{ + NSString *pattern; + + if ([aCoder allowsKeyedCoding]) + { + options = [aCoder decodeIntegerForKey: @"options"]; + pattern = [aCoder decodeObjectForKey: @"pattern"]; + } + else + { + [aCoder decodeValueOfObjCType: @encode(NSRegularExpressionOptions) + at: &options]; + pattern = [aCoder decodeObject]; + } + return [self initWithPattern: pattern options: options error: NULL]; +} + +- (id) copyWithZone: (NSZone*)aZone +{ + NSRegularExpressionOptions opts = options; + UErrorCode s = 0; + URegularExpression *r = uregex_clone(regex, &s); + + if (0 != s) + { + return nil; + } + + self = [[self class] allocWithZone: aZone]; + if (nil == self) + { + return nil; + } + options = opts; + regex = r; + return self; } @end #endif //U_ICU_VERSION_MAJOR_NUM > 4 || (U_ICU_VERSION_MAJOR_NUM == 4 && U_ICU_VERSION_MINOR_NUM >= 4))