mirror of
https://github.com/gnustep/libs-base.git
synced 2025-06-04 18:40:47 +00:00
* Source/NSString.m: Factor out code for opening an ICU collator
into static function GSICUCollatorOpen. Support NSDiacriticInsensitiveSearch. git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@34883 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
7bd91587e4
commit
1a6c14af38
2 changed files with 89 additions and 38 deletions
|
@ -1,3 +1,9 @@
|
||||||
|
2012-03-05 Eric Wasylishen <ewasylishen@gmail.com>
|
||||||
|
|
||||||
|
* Source/NSString.m: Factor out code for opening an ICU collator
|
||||||
|
into static function GSICUCollatorOpen. Support
|
||||||
|
NSDiacriticInsensitiveSearch.
|
||||||
|
|
||||||
2012-03-05 Eric Wasylishen <ewasylishen@gmail.com>
|
2012-03-05 Eric Wasylishen <ewasylishen@gmail.com>
|
||||||
|
|
||||||
* Headers/Foundation/NSString.h (-compare:options:range:locale:):
|
* Headers/Foundation/NSString.h (-compare:options:range:locale:):
|
||||||
|
|
|
@ -584,6 +584,79 @@ handle_printf_atsign (FILE *stream,
|
||||||
}
|
}
|
||||||
#endif /* HAVE_REGISTER_PRINTF_FUNCTION */
|
#endif /* HAVE_REGISTER_PRINTF_FUNCTION */
|
||||||
|
|
||||||
|
#if GS_USE_ICU == 1
|
||||||
|
/**
|
||||||
|
* Returns an ICU collator for the given locale and options, or returns
|
||||||
|
* NULL if a collator couldn't be created or the GNUstep comparison code should be
|
||||||
|
* used instead.
|
||||||
|
*/
|
||||||
|
static UCollator *GSICUCollatorOpen(NSStringCompareOptions mask, NSLocale *locale)
|
||||||
|
{
|
||||||
|
UErrorCode status = U_ZERO_ERROR;
|
||||||
|
const char *localeCString;
|
||||||
|
UCollator *coll;
|
||||||
|
|
||||||
|
if (mask & NSLiteralSearch)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (locale == nil)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* a nil locale should trigger POSIX collation (i.e. 'A'-'Z' sort before 'a'),
|
||||||
|
* and support for this was added in ICU 4.6 under the locale name
|
||||||
|
* en_US_POSIX, but it doesn't fit our requirements (e.g. 'e' and 'E' don't
|
||||||
|
* compare as equal with case insensitive comparison.) - so return NULL to
|
||||||
|
* indicate that the GNUstep comparison code should be used.
|
||||||
|
*/
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
localeCString = [[locale localeIdentifier] UTF8String];
|
||||||
|
|
||||||
|
if (localeCString == NULL
|
||||||
|
|| strcmp("", localeCString) == 0)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
coll = ucol_open(localeCString, &status);
|
||||||
|
|
||||||
|
if (U_SUCCESS(status))
|
||||||
|
{
|
||||||
|
if (mask & (NSCaseInsensitiveSearch | NSDiacriticInsensitiveSearch))
|
||||||
|
{
|
||||||
|
ucol_setStrength(coll, UCOL_PRIMARY);
|
||||||
|
}
|
||||||
|
else if (mask & NSCaseInsensitiveSearch)
|
||||||
|
{
|
||||||
|
ucol_setStrength(coll, UCOL_SECONDARY);
|
||||||
|
}
|
||||||
|
else if (mask & NSDiacriticInsensitiveSearch)
|
||||||
|
{
|
||||||
|
ucol_setStrength(coll, UCOL_PRIMARY);
|
||||||
|
ucol_setAttribute(coll, UCOL_CASE_LEVEL, UCOL_ON, &status);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mask & NSNumericSearch)
|
||||||
|
{
|
||||||
|
ucol_setAttribute(coll, UCOL_NUMERIC_COLLATION, UCOL_ON, &status);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (U_SUCCESS(status))
|
||||||
|
{
|
||||||
|
return coll;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ucol_close(coll);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
+ (void) atExit
|
+ (void) atExit
|
||||||
{
|
{
|
||||||
DESTROY(placeholderLock);
|
DESTROY(placeholderLock);
|
||||||
|
@ -2105,19 +2178,13 @@ handle_printf_atsign (FILE *stream,
|
||||||
}
|
}
|
||||||
|
|
||||||
#if GS_USE_ICU == 1
|
#if GS_USE_ICU == 1
|
||||||
if (locale != nil
|
{
|
||||||
&& ((mask & NSLiteralSearch) != NSLiteralSearch))
|
UCollator *coll = GSICUCollatorOpen(mask, locale);
|
||||||
|
|
||||||
|
if (NULL != coll)
|
||||||
{
|
{
|
||||||
NSRange result = NSMakeRange(NSNotFound, 0);
|
NSRange result = NSMakeRange(NSNotFound, 0);
|
||||||
|
|
||||||
NSString *localeId = [locale objectForKey: NSLocaleIdentifier];
|
|
||||||
const char *localeCString = [localeId UTF8String];
|
|
||||||
|
|
||||||
UErrorCode status = U_ZERO_ERROR;
|
UErrorCode status = U_ZERO_ERROR;
|
||||||
UCollator *coll = ucol_open(localeCString, &status);
|
|
||||||
|
|
||||||
if (U_SUCCESS(status))
|
|
||||||
{
|
|
||||||
NSUInteger countSelf = aRange.length;
|
NSUInteger countSelf = aRange.length;
|
||||||
NSUInteger countOther = [aString length];
|
NSUInteger countOther = [aString length];
|
||||||
unichar *charsSelf;
|
unichar *charsSelf;
|
||||||
|
@ -2128,10 +2195,6 @@ handle_printf_atsign (FILE *stream,
|
||||||
countSelf * sizeof(unichar));
|
countSelf * sizeof(unichar));
|
||||||
charsOther = NSZoneMalloc(NSDefaultMallocZone(),
|
charsOther = NSZoneMalloc(NSDefaultMallocZone(),
|
||||||
countOther * sizeof(unichar));
|
countOther * sizeof(unichar));
|
||||||
if ((mask & NSCaseInsensitiveSearch) == NSCaseInsensitiveSearch)
|
|
||||||
{
|
|
||||||
ucol_setStrength(coll, UCOL_PRIMARY);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copy to buffer
|
// Copy to buffer
|
||||||
|
|
||||||
|
@ -2179,11 +2242,10 @@ handle_printf_atsign (FILE *stream,
|
||||||
NSZoneFree(NSDefaultMallocZone(), charsSelf);
|
NSZoneFree(NSDefaultMallocZone(), charsSelf);
|
||||||
NSZoneFree(NSDefaultMallocZone(), charsOther);
|
NSZoneFree(NSDefaultMallocZone(), charsOther);
|
||||||
usearch_close(search);
|
usearch_close(search);
|
||||||
}
|
|
||||||
ucol_close(coll);
|
ucol_close(coll);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return strRangeNsNs(self, aString, mask, aRange);
|
return strRangeNsNs(self, aString, mask, aRange);
|
||||||
|
@ -4967,15 +5029,10 @@ static NSFileManager *fm = nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if GS_USE_ICU == 1
|
#if GS_USE_ICU == 1
|
||||||
if ((mask & NSLiteralSearch) != NSLiteralSearch
|
|
||||||
&& nil != locale)
|
|
||||||
{
|
{
|
||||||
NSString *localeId = [locale objectForKey: NSLocaleIdentifier];
|
UCollator *coll = GSICUCollatorOpen(mask, locale);
|
||||||
const char *localeCString = [localeId UTF8String];
|
|
||||||
|
|
||||||
UErrorCode status = U_ZERO_ERROR;
|
if (coll != NULL)
|
||||||
UCollator *coll = ucol_open(localeCString, &status);
|
|
||||||
if (U_SUCCESS(status))
|
|
||||||
{
|
{
|
||||||
NSUInteger countSelf = compareRange.length;
|
NSUInteger countSelf = compareRange.length;
|
||||||
NSUInteger countOther = [string length];
|
NSUInteger countOther = [string length];
|
||||||
|
@ -4992,18 +5049,6 @@ static NSFileManager *fm = nil;
|
||||||
[self getCharacters: charsSelf range: compareRange];
|
[self getCharacters: charsSelf range: compareRange];
|
||||||
[string getCharacters: charsOther range: NSMakeRange(0, countOther)];
|
[string getCharacters: charsOther range: NSMakeRange(0, countOther)];
|
||||||
|
|
||||||
if ((mask & NSCaseInsensitiveSearch) == NSCaseInsensitiveSearch)
|
|
||||||
{
|
|
||||||
// see http://icu-project.org/docs/papers/efficient_text_searching_in_java.html
|
|
||||||
ucol_setStrength(coll, UCOL_PRIMARY);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((mask & NSNumericSearch) == NSNumericSearch)
|
|
||||||
{
|
|
||||||
status = U_ZERO_ERROR;
|
|
||||||
ucol_setAttribute(coll, UCOL_NUMERIC_COLLATION, UCOL_ON, &status);
|
|
||||||
}
|
|
||||||
|
|
||||||
result = ucol_strcoll(coll,
|
result = ucol_strcoll(coll,
|
||||||
charsSelf, countSelf, charsOther, countOther);
|
charsSelf, countSelf, charsOther, countOther);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue