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
This commit is contained in:
theraven 2011-08-03 12:04:27 +00:00
parent a04ed1a9ff
commit f72d31cd68
4 changed files with 60 additions and 68 deletions

View file

@ -27,6 +27,7 @@
#import <Foundation/NSObject.h> #import <Foundation/NSObject.h>
#import "GNUstepBase/GSBlocks.h" #import "GNUstepBase/GSBlocks.h"
#import "GNUstepBase/GSConfig.h"
#if defined(__cplusplus) #if defined(__cplusplus)
extern "C" { extern "C" {
@ -76,7 +77,6 @@ DEFINE_BLOCK_TYPE(GSRegexBlock, void, NSTextCheckingResult*, NSMatchingFlags, BO
#if GS_EXPOSE(NSRegularExpression) #if GS_EXPOSE(NSRegularExpression)
@private @private
GSREGEXTYPE *regex; GSREGEXTYPE *regex;
NSString *pattern;
NSRegularExpressionOptions options; NSRegularExpressionOptions options;
#endif #endif
#if GS_NONFRAGILE #if GS_NONFRAGILE
@ -89,6 +89,10 @@ DEFINE_BLOCK_TYPE(GSRegexBlock, void, NSTextCheckingResult*, NSMatchingFlags, BO
@private id _internal GS_UNUSED_IVAR; @private id _internal GS_UNUSED_IVAR;
#endif #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 + (NSRegularExpression*)regularExpressionWithPattern: (NSString*)aPattern
options: (NSRegularExpressionOptions)opts options: (NSRegularExpressionOptions)opts
error: (NSError**)e; error: (NSError**)e;
@ -138,6 +142,7 @@ DEFINE_BLOCK_TYPE(GSRegexBlock, void, NSTextCheckingResult*, NSMatchingFlags, BO
- (NSRegularExpressionOptions)options; - (NSRegularExpressionOptions)options;
- (NSUInteger)numberOfCaptureGroups; - (NSUInteger)numberOfCaptureGroups;
#endif #endif
#endif // GS_USE_ICU
@end @end
#if defined(__cplusplus) #if defined(__cplusplus)

View file

@ -27,19 +27,17 @@
#if GS_USE_ICU == 1 #if GS_USE_ICU == 1
#include "unicode/uregex.h" #include "unicode/uregex.h"
#if (U_ICU_VERSION_MAJOR_NUM > 4 || (U_ICU_VERSION_MAJOR_NUM == 4 && U_ICU_VERSION_MINOR_NUM >= 4)) #if (U_ICU_VERSION_MAJOR_NUM > 4 || (U_ICU_VERSION_MAJOR_NUM == 4 && U_ICU_VERSION_MINOR_NUM >= 4))
#define NSRegularExpressionWorks #define NSRegularExpressionWorks
#define GSREGEXTYPE URegularExpression #define GSREGEXTYPE URegularExpression
#import "GSICUString.h" #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/NSRegularExpression.h"
#import "Foundation/NSTextCheckingResult.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 * 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. * same thing as the URegexpFlags enum in libicu, but have different values.
@ -82,7 +80,6 @@ NSRegularExpressionOptionsToURegexpFlags(NSRegularExpressionOptions opts)
} }
return flags; return flags;
} }
#endif
@implementation NSRegularExpression @implementation NSRegularExpression
@ -99,7 +96,6 @@ NSRegularExpressionOptionsToURegexpFlags(NSRegularExpressionOptions opts)
options: (NSRegularExpressionOptions)opts options: (NSRegularExpressionOptions)opts
error: (NSError**)e error: (NSError**)e
{ {
#ifdef NSRegularExpressionWorks
uint32_t flags = NSRegularExpressionOptionsToURegexpFlags(opts); uint32_t flags = NSRegularExpressionOptionsToURegexpFlags(opts);
UText p = UTEXT_INITIALIZER; UText p = UTEXT_INITIALIZER;
UParseError pe = {0}; UParseError pe = {0};
@ -114,18 +110,26 @@ NSRegularExpressionOptionsToURegexpFlags(NSRegularExpressionOptions opts)
[self release]; [self release];
return nil; return nil;
} }
#endif
ASSIGN(pattern, aPattern);
options = opts; options = opts;
return self; return self;
} }
- (NSString*) pattern - (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 static UBool
callback(const void *context, int32_t steps) callback(const void *context, int32_t steps)
{ {
@ -213,14 +217,12 @@ prepareResult(NSRegularExpression *regex,
} }
return flags; return flags;
} }
#endif
- (void) enumerateMatchesInString: (NSString*)string - (void) enumerateMatchesInString: (NSString*)string
options: (NSMatchingOptions)opts options: (NSMatchingOptions)opts
range: (NSRange)range range: (NSRange)range
usingBlock: (GSRegexBlock)block usingBlock: (GSRegexBlock)block
{ {
#ifdef NSRegularExpressionWorks
UErrorCode s = 0; UErrorCode s = 0;
UText txt = UTEXT_INITIALIZER; UText txt = UTEXT_INITIALIZER;
BOOL stop = NO; BOOL stop = NO;
@ -270,11 +272,6 @@ prepareResult(NSRegularExpression *regex,
} }
utext_close(&txt); utext_close(&txt);
uregex_close(r); 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 /* The remaining methods are all meant to be wrappers around the primitive
@ -374,8 +371,6 @@ prepareResult(NSRegularExpression *regex,
# ifdef __clang__ # ifdef __clang__
# warning Your compiler would support blocks if you added -fblocks to your OBJCFLAGS # warning Your compiler would support blocks if you added -fblocks to your OBJCFLAGS
# endif # endif
#ifdef NSRegularExpressionWorks
#define FAKE_BLOCK_HACK(failRet, code) \ #define FAKE_BLOCK_HACK(failRet, code) \
UErrorCode s = 0;\ UErrorCode s = 0;\
UText txt = UTEXT_INITIALIZER;\ UText txt = UTEXT_INITIALIZER;\
@ -398,11 +393,6 @@ prepareResult(NSRegularExpression *regex,
}\ }\
utext_close(&txt);\ utext_close(&txt);\
uregex_close(r); 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 - (NSUInteger) numberOfMatchesInString: (NSString*)string
options: (NSMatchingOptions)opts options: (NSMatchingOptions)opts
@ -486,7 +476,6 @@ prepareResult(NSRegularExpression *regex,
NSInteger results = [self numberOfMatchesInString: string NSInteger results = [self numberOfMatchesInString: string
options: opts options: opts
range: range]; range: range];
#ifdef NSRegularExpressionWorks
UErrorCode s = 0; UErrorCode s = 0;
UText txt = UTEXT_INITIALIZER; UText txt = UTEXT_INITIALIZER;
UText replacement = UTEXT_INITIALIZER; UText replacement = UTEXT_INITIALIZER;
@ -505,7 +494,6 @@ prepareResult(NSRegularExpression *regex,
utext_close(&txt); utext_close(&txt);
utext_close(output); utext_close(output);
utext_close(&replacement); utext_close(&replacement);
#endif
return results; return results;
} }
@ -514,7 +502,6 @@ prepareResult(NSRegularExpression *regex,
range: (NSRange)range range: (NSRange)range
withTemplate: (NSString*)template withTemplate: (NSString*)template
{ {
#ifdef NSRegularExpressionWorks
UErrorCode s = 0; UErrorCode s = 0;
UText txt = UTEXT_INITIALIZER; UText txt = UTEXT_INITIALIZER;
UText replacement = UTEXT_INITIALIZER; UText replacement = UTEXT_INITIALIZER;
@ -532,10 +519,6 @@ prepareResult(NSRegularExpression *regex,
utext_close(output); utext_close(output);
utext_close(&replacement); utext_close(&replacement);
return ret; return ret;
#else
// FIXME
return nil;
#endif
} }
- (NSString*) replacementStringForResult: (NSTextCheckingResult*)result - (NSString*) replacementStringForResult: (NSTextCheckingResult*)result
@ -543,7 +526,6 @@ prepareResult(NSRegularExpression *regex,
offset: (NSInteger)offset offset: (NSInteger)offset
template: (NSString*)template template: (NSString*)template
{ {
#ifdef NSRegularExpressionWorks
UErrorCode s = 0; UErrorCode s = 0;
UText txt = UTEXT_INITIALIZER; UText txt = UTEXT_INITIALIZER;
UText replacement = UTEXT_INITIALIZER; UText replacement = UTEXT_INITIALIZER;
@ -567,10 +549,6 @@ prepareResult(NSRegularExpression *regex,
utext_close(output); utext_close(output);
utext_close(&replacement); utext_close(&replacement);
return ret; return ret;
#else
//FIXME
return nil;
#endif
} }
- (NSRegularExpressionOptions) options - (NSRegularExpressionOptions) options
@ -580,21 +558,13 @@ prepareResult(NSRegularExpression *regex,
- (NSUInteger) numberOfCaptureGroups - (NSUInteger) numberOfCaptureGroups
{ {
#ifdef NSRegularExpressionWorks
UErrorCode s = 0; UErrorCode s = 0;
return uregex_groupCount(regex, &s); return uregex_groupCount(regex, &s);
#else
// FIXME
return 0;
#endif
} }
- (void) dealloc - (void) dealloc
{ {
#ifdef NSRegularExpressionWorks
uregex_close(regex); uregex_close(regex);
#endif
RELEASE(pattern);
[super dealloc]; [super dealloc];
} }
@ -615,26 +585,24 @@ prepareResult(NSRegularExpression *regex,
- (id) initWithCoder: (NSCoder*)aCoder - (id) initWithCoder: (NSCoder*)aCoder
{ {
NSString *aPattern; NSString *pattern;
NSRegularExpressionOptions opts;
if ([aCoder allowsKeyedCoding]) if ([aCoder allowsKeyedCoding])
{ {
opts = [aCoder decodeIntegerForKey: @"options"]; options = [aCoder decodeIntegerForKey: @"options"];
aPattern = [aCoder decodeObjectForKey: @"pattern"]; pattern = [aCoder decodeObjectForKey: @"pattern"];
} }
else else
{ {
[aCoder decodeValueOfObjCType: @encode(NSRegularExpressionOptions) [aCoder decodeValueOfObjCType: @encode(NSRegularExpressionOptions)
at: &opts]; at: &options];
aPattern = [aCoder decodeObject]; pattern = [aCoder decodeObject];
} }
return [self initWithPattern: aPattern options: opts error: NULL]; return [self initWithPattern: pattern options: options error: NULL];
} }
- (id) copyWithZone: (NSZone*)aZone - (id) copyWithZone: (NSZone*)aZone
{ {
#ifdef NSRegularExpressionWorks
NSRegularExpressionOptions opts = options; NSRegularExpressionOptions opts = options;
UErrorCode s = 0; UErrorCode s = 0;
URegularExpression *r = uregex_clone(regex, &s); URegularExpression *r = uregex_clone(regex, &s);
@ -652,10 +620,32 @@ prepareResult(NSRegularExpression *regex,
options = opts; options = opts;
regex = r; regex = r;
return self; return self;
#else
return [[[self class] allocWithZone: aZone] initWithPattern: [self pattern]
options: [self options]
error: NULL];
#endif
} }
@end @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

View file

@ -43,6 +43,7 @@
Limited choice of default encodings. Limited choice of default encodings.
*/ */
#define GS_UNSAFE_REGEX 1
#import "common.h" #import "common.h"
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>

View file

@ -1,18 +1,13 @@
#import <Foundation/NSString.h> #import <Foundation/NSString.h>
#import <Foundation/NSRegularExpression.h>
#import "ObjectTesting.h" #import "ObjectTesting.h"
int main(void) int main(void)
{ {
[NSAutoreleasePool new]; [NSAutoreleasePool new];
START_SET("NSString + regex") START_SET("NSString + regex")
NS_DURING #if !(__APPLE__ || GS_USE_ICU)
[NSRegularExpression new];
NS_HANDLER
SKIP("NSRegularExpression not built, please install libicu") SKIP("NSRegularExpression not built, please install libicu")
return 0; #else
NS_ENDHANDLER
NSString *regex = @"abcd*"; NSString *regex = @"abcd*";
NSString *source = @"abcdddddd e f g"; NSString *source = @"abcdddddd e f g";
NSRange r = [source rangeOfString: regex options: NSRegularExpressionSearch]; NSRange r = [source rangeOfString: regex options: NSRegularExpressionSearch];
@ -20,6 +15,7 @@ int main(void)
regex = @"aBcD*"; regex = @"aBcD*";
r = [source rangeOfString: regex options: (NSRegularExpressionSearch | NSCaseInsensitiveSearch)]; r = [source rangeOfString: regex options: (NSRegularExpressionSearch | NSCaseInsensitiveSearch)];
PASS(r.length == 9, "Correct length for regex, expected 9 got %d", (int)r.length); PASS(r.length == 9, "Correct length for regex, expected 9 got %d", (int)r.length);
#endif
END_SET("NSString + regex") END_SET("NSString + regex")
return 0; return 0;
} }