From f72d31cd68172f6d2dfdfd38a08b34a991a7d41c Mon Sep 17 00:00:00 2001 From: theraven Date: Wed, 3 Aug 2011 12:04:27 +0000 Subject: [PATCH] Clean up NSRegularExpression, so that it compiles without warnings with or without ICU, but we don't pretend that we support things that we don't and silently return nonsense results to make debugging difficult for GNUstep users. git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@33688 72102866-910b-0410-8b05-ffd578937521 --- Headers/Foundation/NSRegularExpression.h | 7 +- Source/NSRegularExpression.m | 110 +++++++++++------------ Source/NSString.m | 1 + Tests/base/NSString/regex.m | 10 +-- 4 files changed, 60 insertions(+), 68 deletions(-) diff --git a/Headers/Foundation/NSRegularExpression.h b/Headers/Foundation/NSRegularExpression.h index 235e06c6a..2abab097d 100644 --- a/Headers/Foundation/NSRegularExpression.h +++ b/Headers/Foundation/NSRegularExpression.h @@ -27,6 +27,7 @@ #import #import "GNUstepBase/GSBlocks.h" +#import "GNUstepBase/GSConfig.h" #if defined(__cplusplus) extern "C" { @@ -76,7 +77,6 @@ DEFINE_BLOCK_TYPE(GSRegexBlock, void, NSTextCheckingResult*, NSMatchingFlags, BO #if GS_EXPOSE(NSRegularExpression) @private GSREGEXTYPE *regex; - NSString *pattern; NSRegularExpressionOptions options; #endif #if GS_NONFRAGILE @@ -89,6 +89,10 @@ DEFINE_BLOCK_TYPE(GSRegexBlock, void, NSTextCheckingResult*, NSMatchingFlags, BO @private id _internal GS_UNUSED_IVAR; #endif } +// GNUstep, like OS X, uses libicu to provide the NSRegularExpression +// implementation. If you have configured GNUstep without this support then it +// will not work, so these methods are hidden. +#if GS_USE_ICU || GS_UNSAFE_REGEX + (NSRegularExpression*)regularExpressionWithPattern: (NSString*)aPattern options: (NSRegularExpressionOptions)opts error: (NSError**)e; @@ -138,6 +142,7 @@ DEFINE_BLOCK_TYPE(GSRegexBlock, void, NSTextCheckingResult*, NSMatchingFlags, BO - (NSRegularExpressionOptions)options; - (NSUInteger)numberOfCaptureGroups; #endif +#endif // GS_USE_ICU @end #if defined(__cplusplus) diff --git a/Source/NSRegularExpression.m b/Source/NSRegularExpression.m index dea043d76..b32007805 100644 --- a/Source/NSRegularExpression.m +++ b/Source/NSRegularExpression.m @@ -27,19 +27,17 @@ #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)) + #define NSRegularExpressionWorks + #define GSREGEXTYPE URegularExpression #import "GSICUString.h" -#endif //U_ICU_VERSION_MAJOR_NUM > 4 || (U_ICU_VERSION_MAJOR_NUM == 4 && U_ICU_VERSION_MINOR_NUM >= 4)) -#endif //HAV_ICU - -#import "Foundation/NSArray.h" -#import "Foundation/NSCoder.h" -#import "Foundation/NSException.h" #import "Foundation/NSRegularExpression.h" #import "Foundation/NSTextCheckingResult.h" +#import "Foundation/NSArray.h" +#import "Foundation/NSCoder.h" + -#ifdef NSRegularExpressionWorks /** * To be helpful, Apple decided to define a set of flags that mean exactly the * same thing as the URegexpFlags enum in libicu, but have different values. @@ -82,7 +80,6 @@ NSRegularExpressionOptionsToURegexpFlags(NSRegularExpressionOptions opts) } return flags; } -#endif @implementation NSRegularExpression @@ -99,7 +96,6 @@ NSRegularExpressionOptionsToURegexpFlags(NSRegularExpressionOptions opts) options: (NSRegularExpressionOptions)opts error: (NSError**)e { -#ifdef NSRegularExpressionWorks uint32_t flags = NSRegularExpressionOptionsToURegexpFlags(opts); UText p = UTEXT_INITIALIZER; UParseError pe = {0}; @@ -114,18 +110,26 @@ NSRegularExpressionOptionsToURegexpFlags(NSRegularExpressionOptions opts) [self release]; return nil; } -#endif - ASSIGN(pattern, aPattern); options = opts; return self; } - (NSString*) pattern { - return 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]; } -#ifdef NSRegularExpressionWorks static UBool callback(const void *context, int32_t steps) { @@ -213,14 +217,12 @@ prepareResult(NSRegularExpression *regex, } return flags; } -#endif - (void) enumerateMatchesInString: (NSString*)string options: (NSMatchingOptions)opts range: (NSRange)range usingBlock: (GSRegexBlock)block { -#ifdef NSRegularExpressionWorks UErrorCode s = 0; UText txt = UTEXT_INITIALIZER; BOOL stop = NO; @@ -270,11 +272,6 @@ prepareResult(NSRegularExpression *regex, } utext_close(&txt); uregex_close(r); -#else - //FIXME - [NSException raise: NSInvalidArgumentException - format: @"NSRegularExpression requires ICU 4.4 or later"]; -#endif } /* The remaining methods are all meant to be wrappers around the primitive @@ -374,8 +371,6 @@ prepareResult(NSRegularExpression *regex, # ifdef __clang__ # warning Your compiler would support blocks if you added -fblocks to your OBJCFLAGS # endif - -#ifdef NSRegularExpressionWorks #define FAKE_BLOCK_HACK(failRet, code) \ UErrorCode s = 0;\ UText txt = UTEXT_INITIALIZER;\ @@ -398,11 +393,6 @@ prepareResult(NSRegularExpression *regex, }\ utext_close(&txt);\ uregex_close(r); -#else -#define FAKE_BLOCK_HACK(failRet, code) \ - [NSException raise: NSInvalidArgumentException \ - format: @"NSRegularExpression requires ICU 4.4 or later"] -#endif - (NSUInteger) numberOfMatchesInString: (NSString*)string options: (NSMatchingOptions)opts @@ -486,7 +476,6 @@ prepareResult(NSRegularExpression *regex, NSInteger results = [self numberOfMatchesInString: string options: opts range: range]; -#ifdef NSRegularExpressionWorks UErrorCode s = 0; UText txt = UTEXT_INITIALIZER; UText replacement = UTEXT_INITIALIZER; @@ -505,7 +494,6 @@ prepareResult(NSRegularExpression *regex, utext_close(&txt); utext_close(output); utext_close(&replacement); -#endif return results; } @@ -514,7 +502,6 @@ prepareResult(NSRegularExpression *regex, range: (NSRange)range withTemplate: (NSString*)template { -#ifdef NSRegularExpressionWorks UErrorCode s = 0; UText txt = UTEXT_INITIALIZER; UText replacement = UTEXT_INITIALIZER; @@ -532,10 +519,6 @@ prepareResult(NSRegularExpression *regex, utext_close(output); utext_close(&replacement); return ret; -#else - // FIXME - return nil; -#endif } - (NSString*) replacementStringForResult: (NSTextCheckingResult*)result @@ -543,7 +526,6 @@ prepareResult(NSRegularExpression *regex, offset: (NSInteger)offset template: (NSString*)template { -#ifdef NSRegularExpressionWorks UErrorCode s = 0; UText txt = UTEXT_INITIALIZER; UText replacement = UTEXT_INITIALIZER; @@ -567,10 +549,6 @@ prepareResult(NSRegularExpression *regex, utext_close(output); utext_close(&replacement); return ret; -#else - //FIXME - return nil; -#endif } - (NSRegularExpressionOptions) options @@ -580,21 +558,13 @@ prepareResult(NSRegularExpression *regex, - (NSUInteger) numberOfCaptureGroups { -#ifdef NSRegularExpressionWorks UErrorCode s = 0; return uregex_groupCount(regex, &s); -#else - // FIXME - return 0; -#endif } - (void) dealloc { -#ifdef NSRegularExpressionWorks uregex_close(regex); -#endif - RELEASE(pattern); [super dealloc]; } @@ -615,26 +585,24 @@ prepareResult(NSRegularExpression *regex, - (id) initWithCoder: (NSCoder*)aCoder { - NSString *aPattern; - NSRegularExpressionOptions opts; + NSString *pattern; if ([aCoder allowsKeyedCoding]) { - opts = [aCoder decodeIntegerForKey: @"options"]; - aPattern = [aCoder decodeObjectForKey: @"pattern"]; + options = [aCoder decodeIntegerForKey: @"options"]; + pattern = [aCoder decodeObjectForKey: @"pattern"]; } else { [aCoder decodeValueOfObjCType: @encode(NSRegularExpressionOptions) - at: &opts]; - aPattern = [aCoder decodeObject]; + at: &options]; + pattern = [aCoder decodeObject]; } - return [self initWithPattern: aPattern options: opts error: NULL]; + return [self initWithPattern: pattern options: options error: NULL]; } - (id) copyWithZone: (NSZone*)aZone { -#ifdef NSRegularExpressionWorks NSRegularExpressionOptions opts = options; UErrorCode s = 0; URegularExpression *r = uregex_clone(regex, &s); @@ -652,10 +620,32 @@ prepareResult(NSRegularExpression *regex, options = opts; regex = r; return self; -#else - return [[[self class] allocWithZone: aZone] initWithPattern: [self pattern] - options: [self options] - error: NULL]; -#endif } @end +#endif //U_ICU_VERSION_MAJOR_NUM > 4 || (U_ICU_VERSION_MAJOR_NUM == 4 && U_ICU_VERSION_MINOR_NUM >= 4)) +#endif //HAV_ICU + +#ifndef NSRegularExpressionWorks +#import "Foundation/NSRegularExpression.h" +#import "Foundation/NSZone.h" +#import "Foundation/NSException.h" +@implementation NSRegularExpression ++ (id)allocWithZone: (NSZone*)aZone +{ + [NSException raise: NSInvalidArgumentException + format: @"NSRegularExpression requires ICU 4.4 or later"]; + return nil; +} +- (id) copyWithZone: (NSZone*)zone +{ + return nil; +} +- (void) encodeWithCoder: (NSCoder*)aCoder +{ +} +- (id) initWithCoder: (NSCoder*)aCoder +{ + return nil; +} +@end +#endif diff --git a/Source/NSString.m b/Source/NSString.m index 679084748..fc8e9e4ff 100644 --- a/Source/NSString.m +++ b/Source/NSString.m @@ -43,6 +43,7 @@ Limited choice of default encodings. */ +#define GS_UNSAFE_REGEX 1 #import "common.h" #include #include diff --git a/Tests/base/NSString/regex.m b/Tests/base/NSString/regex.m index 2bb25c467..b999e3be7 100644 --- a/Tests/base/NSString/regex.m +++ b/Tests/base/NSString/regex.m @@ -1,18 +1,13 @@ #import -#import #import "ObjectTesting.h" int main(void) { [NSAutoreleasePool new]; START_SET("NSString + regex") - NS_DURING - [NSRegularExpression new]; - NS_HANDLER +#if !(__APPLE__ || GS_USE_ICU) SKIP("NSRegularExpression not built, please install libicu") - return 0; - NS_ENDHANDLER - +#else NSString *regex = @"abcd*"; NSString *source = @"abcdddddd e f g"; NSRange r = [source rangeOfString: regex options: NSRegularExpressionSearch]; @@ -20,6 +15,7 @@ int main(void) regex = @"aBcD*"; r = [source rangeOfString: regex options: (NSRegularExpressionSearch | NSCaseInsensitiveSearch)]; PASS(r.length == 9, "Correct length for regex, expected 9 got %d", (int)r.length); +#endif END_SET("NSString + regex") return 0; }