mirror of
https://github.com/gnustep/libs-base.git
synced 2025-04-23 09:04:13 +00:00
Stylistic changes in -[NSString enumerateSubstringsInRange:options:usingBlock:]
This commit is contained in:
parent
b8239f604f
commit
a15fa66276
1 changed files with 137 additions and 129 deletions
|
@ -6269,141 +6269,149 @@ static NSFileManager *fm = nil;
|
|||
|
||||
NSUInteger currentLocation;
|
||||
BOOL stop = NO;
|
||||
if(isReverse) {
|
||||
currentLocation = range.location + range.length;
|
||||
} else {
|
||||
currentLocation = range.location;
|
||||
}
|
||||
|
||||
if (substringType == NSStringEnumerationByLines || substringType == NSStringEnumerationByParagraphs) {
|
||||
BOOL isLineSep = substringType == NSStringEnumerationByLines;
|
||||
|
||||
while(YES) {
|
||||
// contains the index of the first character of the line containing the beginning of aRange.
|
||||
NSUInteger start;
|
||||
// contains the index of the first character past the terminator of the line containing the end of aRange.
|
||||
NSUInteger end;
|
||||
// contains the index of the first character of the terminator of the line containing the end of aRange.
|
||||
NSUInteger contentsEnd;
|
||||
NSRange currentLocationRange = (NSRange){
|
||||
.location = currentLocation,
|
||||
.length = 0,
|
||||
};
|
||||
[self _getStart: &start
|
||||
end: &end
|
||||
contentsEnd: &contentsEnd
|
||||
forRange: currentLocationRange
|
||||
lineSep: isLineSep];
|
||||
// If the enumerated range starts after the line/paragraph, we start at the beginning of the enumerated range
|
||||
NSUInteger substringStart = start > range.location ? start : range.location;
|
||||
NSRange substringRange = (NSRange){
|
||||
.location = substringStart,
|
||||
.length = contentsEnd - substringStart
|
||||
};
|
||||
CALL_BLOCK(block,
|
||||
substringNotRequired ? nil : [self substringWithRange: substringRange],
|
||||
substringRange,
|
||||
(NSRange){
|
||||
.location = start,
|
||||
.length = end - start
|
||||
},
|
||||
&stop);
|
||||
if(stop) break;
|
||||
if(end == range.location + range.length) break;
|
||||
currentLocation = end;
|
||||
if (isReverse)
|
||||
{
|
||||
currentLocation = range.location + range.length;
|
||||
}
|
||||
else
|
||||
{
|
||||
currentLocation = range.location;
|
||||
}
|
||||
} else if (substringType == NSStringEnumerationByComposedCharacterSequences) {
|
||||
// We could also use rangeOfComposedCharacterSequenceAtIndex:, but then we would need different logic.
|
||||
while(YES) {
|
||||
// Since all characters are in a composed character sequence, enclosingRange == substringRange
|
||||
NSRange enclosingRange = [self rangeOfComposedCharacterSequenceAtIndex: currentLocation];
|
||||
CALL_BLOCK(block,
|
||||
substringNotRequired ? nil : [self substringWithRange: enclosingRange],
|
||||
enclosingRange,
|
||||
enclosingRange,
|
||||
&stop);
|
||||
if(stop) break;
|
||||
currentLocation = enclosingRange.location + enclosingRange.length;
|
||||
}
|
||||
} else if (substringType == NSStringEnumerationByWords || substringType == NSStringEnumerationBySentences) {
|
||||
#if GS_USE_ICU
|
||||
// These macros may be useful elsewhere.
|
||||
#define GS_U_HANDLE_ERROR(errorCode, description) do { \
|
||||
if(U_FAILURE(errorCode)) { \
|
||||
NSWarnMLog(@"Error " description ": %s", u_errorName(errorCode)); \
|
||||
return; \
|
||||
} else if(errorCode < U_ZERO_ERROR) { \
|
||||
NSWarnMLog(@"Warning " description ": %s", u_errorName(errorCode)); \
|
||||
} \
|
||||
errorCode = U_ZERO_ERROR; \
|
||||
} while (NO)
|
||||
|
||||
BOOL byWords = substringType == NSStringEnumerationByWords;
|
||||
NSUInteger length = range.length;
|
||||
UChar characters[length];
|
||||
[self getCharacters: characters range: range];
|
||||
UErrorCode errorCode = U_ZERO_ERROR;
|
||||
const char* locale = localized
|
||||
? [[[[NSLocale currentLocale]
|
||||
localeIdentifier]
|
||||
// @ss=standard will use lists of common abbreviations, such as Mr., Mrs., etc.
|
||||
stringByAppendingString: @"@ss=standard"]
|
||||
UTF8String]
|
||||
: "en_US_POSIX";
|
||||
UBreakIterator* breakIterator = ubrk_open(byWords ? UBRK_WORD : UBRK_SENTENCE, // type
|
||||
locale, // locale
|
||||
characters, // text
|
||||
length, // textLength
|
||||
&errorCode);
|
||||
GS_U_HANDLE_ERROR(errorCode, @"opening ICU break iterator");
|
||||
ubrk_first(breakIterator);
|
||||
while(YES) {
|
||||
// Make sure it's a valid substring.
|
||||
BOOL isValidSubstring = YES;
|
||||
if (substringType == NSStringEnumerationByLines || substringType == NSStringEnumerationByParagraphs)
|
||||
{
|
||||
BOOL isLineSep = substringType == NSStringEnumerationByLines;
|
||||
|
||||
if(byWords) {
|
||||
int32_t ruleStatus = ubrk_getRuleStatus(breakIterator);
|
||||
// From ICU User Guide:
|
||||
// A status value UBRK_WORD_NONE indicates that the boundary does
|
||||
// not start a word or number.
|
||||
// However, valid words seem to be UBRK_WORD_NONE, and invalid words
|
||||
// seem to be UBRK_WORD_NONE_LIMIT.
|
||||
isValidSubstring = ruleStatus != UBRK_WORD_NONE_LIMIT;
|
||||
NSLog(@"Status for position %d (%d): %d", (int)currentLocation, (int)ubrk_current(breakIterator), (int) ruleStatus);
|
||||
}
|
||||
int32_t nextPosition = ubrk_next(breakIterator);
|
||||
if(nextPosition == UBRK_DONE) break;
|
||||
NSUInteger nextLocation = range.location + nextPosition;
|
||||
// Same as substringRange
|
||||
NSRange enclosingRange = (NSRange){
|
||||
.location = currentLocation,
|
||||
.length = nextLocation - currentLocation
|
||||
};
|
||||
|
||||
if(isValidSubstring) {
|
||||
CALL_BLOCK(block,
|
||||
substringNotRequired ? nil : [self substringWithRange: enclosingRange],
|
||||
enclosingRange,
|
||||
enclosingRange,
|
||||
&stop);
|
||||
if(stop) break;
|
||||
}
|
||||
while (YES)
|
||||
{
|
||||
// contains the index of the first character of the line containing the beginning of aRange.
|
||||
NSUInteger start;
|
||||
// contains the index of the first character past the terminator of the line containing the end of aRange.
|
||||
NSUInteger end;
|
||||
// contains the index of the first character of the terminator of the line containing the end of aRange.
|
||||
NSUInteger contentsEnd;
|
||||
NSRange currentLocationRange = NSMakeRange(currentLocation, 0);
|
||||
[self _getStart: &start
|
||||
end: &end
|
||||
contentsEnd: &contentsEnd
|
||||
forRange: currentLocationRange
|
||||
lineSep: isLineSep];
|
||||
// If the enumerated range starts after the line/paragraph, we start at the beginning of the enumerated range
|
||||
NSUInteger substringStart = start > range.location ? start : range.location;
|
||||
NSRange substringRange = NSMakeRange(substringStart, contentsEnd - substringStart);
|
||||
CALL_BLOCK(block,
|
||||
substringNotRequired ? nil : [self substringWithRange: substringRange],
|
||||
substringRange,
|
||||
NSMakeRange(start, end - start),
|
||||
&stop);
|
||||
if (stop) break;
|
||||
if (end == range.location + range.length) break;
|
||||
currentLocation = end;
|
||||
}
|
||||
}
|
||||
else if (substringType == NSStringEnumerationByComposedCharacterSequences)
|
||||
{
|
||||
// We could also use rangeOfComposedCharacterSequenceAtIndex:, but then we would need different logic.
|
||||
while (YES)
|
||||
{
|
||||
// Since all characters are in a composed character sequence, enclosingRange == substringRange
|
||||
NSRange enclosingRange = [self rangeOfComposedCharacterSequenceAtIndex: currentLocation];
|
||||
CALL_BLOCK(block,
|
||||
substringNotRequired ? nil : [self substringWithRange: enclosingRange],
|
||||
enclosingRange,
|
||||
enclosingRange,
|
||||
&stop);
|
||||
if(stop) break;
|
||||
currentLocation = enclosingRange.location + enclosingRange.length;
|
||||
}
|
||||
}
|
||||
else if (substringType == NSStringEnumerationByWords || substringType == NSStringEnumerationBySentences)
|
||||
{
|
||||
#if GS_USE_ICU
|
||||
// These macros may be useful elsewhere.
|
||||
#define GS_U_HANDLE_ERROR(errorCode, description) do { \
|
||||
if (U_FAILURE(errorCode)) { \
|
||||
NSWarnMLog(@"Error " description ": %s", u_errorName(errorCode)); \
|
||||
return; \
|
||||
} else if (errorCode < U_ZERO_ERROR) { \
|
||||
NSWarnMLog(@"Warning " description ": %s", u_errorName(errorCode)); \
|
||||
} \
|
||||
errorCode = U_ZERO_ERROR; \
|
||||
} while (NO)
|
||||
|
||||
currentLocation = nextLocation;
|
||||
BOOL byWords = substringType == NSStringEnumerationByWords;
|
||||
NSUInteger length = range.length;
|
||||
UChar characters[length];
|
||||
[self getCharacters: characters range: range];
|
||||
UErrorCode errorCode = U_ZERO_ERROR;
|
||||
const char* locale = localized
|
||||
? [[[[NSLocale currentLocale]
|
||||
localeIdentifier]
|
||||
// @ss=standard will use lists of common abbreviations, such as Mr., Mrs., etc.
|
||||
stringByAppendingString: @"@ss=standard"]
|
||||
UTF8String]
|
||||
: "en_US_POSIX";
|
||||
UBreakIterator* breakIterator = ubrk_open(byWords ? UBRK_WORD : UBRK_SENTENCE, // type
|
||||
locale, // locale
|
||||
characters, // text
|
||||
length, // textLength
|
||||
&errorCode);
|
||||
GS_U_HANDLE_ERROR(errorCode, @"opening ICU break iterator");
|
||||
ubrk_first(breakIterator);
|
||||
while (YES)
|
||||
{
|
||||
// Make sure it's a valid substring.
|
||||
BOOL isValidSubstring = YES;
|
||||
|
||||
if (byWords)
|
||||
{
|
||||
int32_t ruleStatus = ubrk_getRuleStatus(breakIterator);
|
||||
// From ICU User Guide:
|
||||
// A status value UBRK_WORD_NONE indicates that the boundary does
|
||||
// not start a word or number.
|
||||
// However, valid words seem to be UBRK_WORD_NONE, and invalid words
|
||||
// seem to be UBRK_WORD_NONE_LIMIT.
|
||||
isValidSubstring = ruleStatus != UBRK_WORD_NONE_LIMIT;
|
||||
NSLog(@"Status for position %d (%d): %d", (int)currentLocation, (int)ubrk_current(breakIterator), (int) ruleStatus);
|
||||
}
|
||||
|
||||
int32_t nextPosition = ubrk_next(breakIterator);
|
||||
if (nextPosition == UBRK_DONE) break;
|
||||
|
||||
NSUInteger nextLocation = range.location + nextPosition;
|
||||
// Same as substringRange
|
||||
NSRange enclosingRange = NSMakeRange(currentLocation, nextLocation - currentLocation);
|
||||
|
||||
if (isValidSubstring)
|
||||
{
|
||||
CALL_BLOCK(block,
|
||||
substringNotRequired ? nil : [self substringWithRange: enclosingRange],
|
||||
enclosingRange,
|
||||
enclosingRange,
|
||||
&stop);
|
||||
if(stop) break;
|
||||
}
|
||||
|
||||
currentLocation = nextLocation;
|
||||
}
|
||||
#else
|
||||
NSWarnLog(@"NSStringEnumerationByWords and NSStringEnumerationBySentences are not supported when GNUstep-base is compiled without ICU.");
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
else if (substringType == NSStringEnumerationByCaretPositions)
|
||||
{
|
||||
// FIXME - Not documented by Apple.
|
||||
NSWarnLog(@"NSStringEnumerationByCaretPositions is not supported");
|
||||
return;
|
||||
}
|
||||
else if (substringType == NSStringEnumerationByDeletionClusters)
|
||||
{
|
||||
// FIXME - Not documented by Apple.
|
||||
NSWarnLog(@"NSStringEnumerationByDeletionClusters is not supported");
|
||||
return;
|
||||
}
|
||||
#else
|
||||
NSWarnLog(@"NSStringEnumerationByWords and NSStringEnumerationBySentences are not supported when GNUstep-base is compiled without ICU.");
|
||||
return;
|
||||
#endif
|
||||
} else if (substringType == NSStringEnumerationByCaretPositions) {
|
||||
// FIXME - Not documented by Apple.
|
||||
NSWarnLog(@"NSStringEnumerationByCaretPositions is not supported");
|
||||
return;
|
||||
} else if (substringType == NSStringEnumerationByDeletionClusters) {
|
||||
// FIXME - Not documented by Apple.
|
||||
NSWarnLog(@"NSStringEnumerationByDeletionClusters is not supported");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
Loading…
Reference in a new issue