NSPredicate MATCHES and LIKE implementation

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@31616 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
ericwa 2010-11-17 21:46:31 +00:00
parent dd2cf5c805
commit 4f86b23b2d
7 changed files with 5982 additions and 19538 deletions

View file

@ -1,3 +1,8 @@
2010-11-17 Eric Wasylishen
* Source/NSPredicate.m: Implement MATCHES and LIKE using ICU
* configure.ac: Check for unicode/uregex.h in ICU checks
2010-11-13 Riccardo Mottola
* Source/NSPathUtilities.m:

View file

@ -618,6 +618,9 @@
/* Define to 1 if you have the <unicode/uloc.h> header file. */
#undef HAVE_UNICODE_ULOC_H
/* Define to 1 if you have the <unicode/uregex.h> header file. */
#undef HAVE_UNICODE_UREGEX_H
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
@ -669,6 +672,9 @@
/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME
/* Define to the home page for this package. */
#undef PACKAGE_URL
/* Define to the version of this package. */
#undef PACKAGE_VERSION

View file

@ -93,6 +93,9 @@
/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME
/* Define to the home page for this package. */
#undef PACKAGE_URL
/* Define to the version of this package. */
#undef PACKAGE_VERSION

6001
SSL/configure vendored

File diff suppressed because it is too large Load diff

View file

@ -52,6 +52,10 @@
// For pow()
#include <math.h>
#if defined(HAVE_UNICODE_UREGEX_H)
#include <unicode/uregex.h>
#endif
/* Object to represent the expression beign evaluated.
*/
static NSExpression *evaluatedObjectExpression = nil;
@ -808,6 +812,44 @@ static NSExpression *evaluatedObjectExpression = nil;
}
}
#if defined(GS_USE_ICU)
static BOOL GSICUStringMatchesRegex(NSString *string, NSString *regex, NSStringCompareOptions opts)
{
BOOL result = NO;
UErrorCode error = 0;
uint32_t flags = 0;
NSUInteger stringLength = [string length];
NSUInteger regexLength = [regex length];
unichar *stringBuffer;
unichar *regexBuffer;
URegularExpression *icuregex = NULL;
stringBuffer = malloc(stringLength * sizeof(unichar));
if (NULL == stringBuffer) { return NO; }
regexBuffer = malloc(regexLength * sizeof(unichar));
if (NULL == regexBuffer) { free(stringBuffer); return NO; }
[string getCharacters: stringBuffer range: NSMakeRange(0, stringLength)];
[regex getCharacters: regexBuffer range: NSMakeRange(0, regexLength)];
flags |= UREGEX_DOTALL; // . is supposed to recognize newlines
if ((opts & NSCaseInsensitiveSearch) != 0) { flags |= UREGEX_CASE_INSENSITIVE; }
icuregex = uregex_open(regexBuffer, regexLength, flags, NULL, &error);
if (icuregex != NULL && U_SUCCESS(error))
{
uregex_setText(icuregex, stringBuffer, stringLength, &error);
result = uregex_matches(icuregex, 0, &error);
}
uregex_close(icuregex);
free(stringBuffer);
free(regexBuffer);
return result;
}
#endif
- (BOOL) _evaluateLeftValue: (id)leftResult
rightValue: (id)rightResult
object: (id)object
@ -866,11 +908,26 @@ static NSExpression *evaluatedObjectExpression = nil;
case NSNotEqualToPredicateOperatorType:
return ![leftResult isEqual: rightResult];
case NSMatchesPredicateOperatorType:
// FIXME: Missing implementation of matches.
#if defined(GS_USE_ICU)
return GSICUStringMatchesRegex(leftResult, rightResult, compareOptions);
#else
return [leftResult compare: rightResult options: compareOptions] == NSOrderedSame;
#endif
case NSLikePredicateOperatorType:
// FIXME: Missing implementation of like.
return [leftResult compare: rightResult options: compareOptions] == NSOrderedSame;
#if defined(GS_USE_ICU)
{
// The right hand is a pattern with ? meaning match one character, and
// * meaning match zero or more characters, so translate that into a regex
NSString *regex = [rightResult stringByReplacingOccurrencesOfString: @"*"
withString: @".*"];
regex = [regex stringByReplacingOccurrencesOfString: @"?"
withString: @".?"];
regex = [NSString stringWithFormat: @"^%@$", regex];
return GSICUStringMatchesRegex(leftResult, regex, compareOptions);
}
#else
return [leftResult compare: rightResult options: compareOptions] == NSOrderedSame;
#endif
case NSBeginsWithPredicateOperatorType:
{
NSRange range = NSMakeRange(0, [rightResult length]);

19440
configure vendored

File diff suppressed because it is too large Load diff

View file

@ -2648,7 +2648,7 @@ if test $enable_icu = yes; then
AC_CHECK_ICU(4.0, have_icu=yes, have_icu=no)
if test "$have_icu" = "yes"; then
AC_MSG_RESULT(yes)
AC_CHECK_HEADERS(unicode/uloc.h unicode/ulocdata.h unicode/ucurr.h)
AC_CHECK_HEADERS(unicode/uloc.h unicode/ulocdata.h unicode/ucurr.h unicode/uregex.h)
LIBS="$LIBS $ICU_LIBS"
HAVE_ICU=1
AC_DEFINE(HAVE_ICU,1,