Checks for illegal comparator return values.

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@5349 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Richard Frith-MacDonald 1999-12-01 19:36:20 +00:00
parent 1b69260b1e
commit 0761b6ee95
5 changed files with 155 additions and 46 deletions

View file

@ -1,3 +1,10 @@
Wed Dec 1 19:36:00 1999 Richard Frith-Macdonald <richard@brainstorm.co.uk>
* Source/NSArray.m: When sorting, treat illegal return values from the
comparator the same way as OPENSTEP does, but log a warning.
* Source/NSGArray.m: ditto
* Source/NSDictionary.m ditto
Fri Nov 26 19:46:00 1999 Richard Frith-Macdonald <richard@brainstorm.co.uk>
* Headers/Foundation/NSString.h: Tidied and fixed return types for

View file

@ -1144,18 +1144,23 @@ static NSString *indentStrings[] = {
}
- (void) sortUsingFunction: (int(*)(id,id,void*))compare
context: (void*)context
context: (void*)context
{
/* Shell sort algorithm taken from SortingInAction - a NeXT example */
#define STRIDE_FACTOR 3 // good value for stride factor is not well-understood
// 3 is a fairly good choice (Sedgewick)
unsigned c,d, stride;
BOOL found;
int count = [self count];
unsigned c,d, stride;
BOOL found;
int count = [self count];
#ifdef GSWARN
BOOL badComparison = NO;
#endif
stride = 1;
while (stride <= count)
stride = stride * STRIDE_FACTOR + 1;
{
stride = stride * STRIDE_FACTOR + 1;
}
while(stride > (STRIDE_FACTOR - 1))
{
@ -1165,27 +1170,54 @@ static NSString *indentStrings[] = {
{
found = NO;
if (stride > c)
break;
d = c - stride;
while (!found)
{
// move to left until correct place
id a = [self objectAtIndex: d + stride];
id b = [self objectAtIndex: d];
if ((*compare)(a, b, context) == NSOrderedAscending)
break;
}
d = c - stride;
while (!found) /* move to left until correct place */
{
id a = [self objectAtIndex: d + stride];
id b = [self objectAtIndex: d];
NSComparisonResult r;
r = (*compare)(a, b, context);
if (r < 0)
{
#ifdef GSWARN
if (r != NSOrderedAscending)
{
badComparison = YES;
}
#endif
IF_NO_GC(RETAIN(a));
[self replaceObjectAtIndex: d + stride withObject: b];
[self replaceObjectAtIndex: d withObject: a];
RELEASE(a);
if (stride > d)
break;
{
break;
}
d -= stride; // jump by stride factor
}
else found = YES;
else
{
#ifdef GSWARN
if (r != NSOrderedDescending && r != NSOrderedSame)
{
badComparison = YES;
}
#endif
found = YES;
}
}
}
}
#ifdef GSWARN
if (badComparison == YES)
{
NSWarnMLog(@"Detected bad return value from comparison", 0);
}
#endif
}
@end

View file

@ -32,6 +32,7 @@
#include <Foundation/NSException.h>
#include <Foundation/NSAutoreleasePool.h>
#include <Foundation/NSFileManager.h>
#include <Foundation/NSDebug.h>
@interface NSDictionaryNonCore : NSDictionary
@end
@ -696,16 +697,21 @@ static NSString *indentStrings[] = {
* 3 is a fairly good choice (Sedgewick)
*/
#define STRIDE_FACTOR 3
unsigned c,d, stride;
unsigned c,d, stride;
BOOL found;
NSComparisonResult (*comp)(id, SEL, id);
int count = numKeys;
int count = numKeys;
#ifdef GSWARN
BOOL badComparison = NO;
#endif
stride = 1;
while (stride <= count)
stride = stride * STRIDE_FACTOR + 1;
{
stride = stride * STRIDE_FACTOR + 1;
}
lastClass = 0;
while(stride > (STRIDE_FACTOR - 1))
while (stride > (STRIDE_FACTOR - 1))
{
// loop to sort for each value of stride
stride = stride / STRIDE_FACTOR;
@ -713,14 +719,16 @@ static NSString *indentStrings[] = {
{
found = NO;
if (stride > c)
break;
d = c - stride;
while (!found)
{
// move to left until correct place
id a = keys[d + stride];
id b = keys[d];
Class x;
break;
}
d = c - stride;
while (!found) // move to left until correct place
{
id a = keys[d + stride];
id b = keys[d];
Class x;
NSComparisonResult r;
x = fastClass(a);
if (x != lastClass)
@ -729,21 +737,42 @@ static NSString *indentStrings[] = {
comp = (NSComparisonResult (*)(id, SEL, id))
[a methodForSelector: @selector(compare:)];
}
if ((*comp)(a, @selector(compare:), b) == NSOrderedAscending)
r = (*comp)(a, @selector(compare:), b);
if (r < 0)
{
#ifdef GSWARN
if (r != NSOrderedAscending)
{
badComparison = YES;
}
#endif
keys[d + stride] = b;
keys[d] = a;
if (stride > d)
break;
{
break;
}
d -= stride; // jump by stride factor
}
else
{
#ifdef GSWARN
if (r != NSOrderedDescending && r != NSOrderedSame)
{
badComparison = YES;
}
#endif
found = YES;
}
}
}
}
#ifdef GSWARN
if (badComparison == YES)
{
NSWarnMLog(@"Detected bad return value from comparison", 0);
}
#endif
}
for (i = 0; i < numKeys; i++)

View file

@ -530,13 +530,18 @@ static SEL eqSel = @selector(isEqual:);
/* Shell sort algorithm taken from SortingInAction - a NeXT example */
#define STRIDE_FACTOR 3 // good value for stride factor is not well-understood
// 3 is a fairly good choice (Sedgewick)
unsigned c,d, stride;
BOOL found;
int count = _count;
unsigned c,d, stride;
BOOL found;
int count = _count;
#ifdef GSWARN
BOOL badComparison = NO;
#endif
stride = 1;
while (stride <= count)
stride = stride * STRIDE_FACTOR + 1;
{
stride = stride * STRIDE_FACTOR + 1;
}
while (stride > (STRIDE_FACTOR - 1))
{
@ -546,26 +551,52 @@ static SEL eqSel = @selector(isEqual:);
{
found = NO;
if (stride > c)
break;
d = c - stride;
while (!found)
{
// move to left until correct place
id a = _contents_array[d + stride];
id b = _contents_array[d];
if ((*compare)(a, b, context) == NSOrderedAscending)
break;
}
d = c - stride;
while (!found) /* move to left until correct place */
{
id a = _contents_array[d + stride];
id b = _contents_array[d];
NSComparisonResult r;
r = (*compare)(a, b, context);
if (r < 0)
{
#ifdef GSWARN
if (r != NSOrderedAscending)
{
badComparison = YES;
}
#endif
_contents_array[d+stride] = b;
_contents_array[d] = a;
if (stride > d)
break;
{
break;
}
d -= stride; // jump by stride factor
}
else
found = YES;
{
#ifdef GSWARN
if (r != NSOrderedDescending && r != NSOrderedSame)
{
badComparison = YES;
}
#endif
found = YES;
}
}
}
}
#ifdef GSWARN
if (badComparison == YES)
{
NSWarnMLog(@"Detected bad return value from comparison", 0);
}
#endif
}
- (NSEnumerator*) objectEnumerator

View file

@ -2476,20 +2476,30 @@ handle_printf_atsign (FILE *stream,
// Creating Temporary Strings
+ (NSMutableString*) string
{
return AUTORELEASE([[NSMutableString_c_concrete_class allocWithZone:
NSDefaultMallocZone()] initWithCapacity: 0]);
}
+ (NSMutableString*) stringWithCapacity: (unsigned)capacity
{
return AUTORELEASE([[self allocWithZone: NSDefaultMallocZone()]
initWithCapacity: capacity]);
return AUTORELEASE([[NSMutableString_c_concrete_class allocWithZone:
NSDefaultMallocZone()] initWithCapacity: capacity]);
}
/* Inefficient. */
+ (NSString*) stringWithCharacters: (const unichar*)characters
length: (unsigned)length
{
id n;
n = [[self allocWithZone: NSDefaultMallocZone()]
initWithCharacters: characters length: length];
return AUTORELEASE(n);
return AUTORELEASE([[NSMutableString_c_concrete_class allocWithZone:
NSDefaultMallocZone()] initWithCharacters: characters length: length]);
}
+ (id) stringWithContentsOfFile: (NSString *)path
{
return AUTORELEASE([[NSMutableString_c_concrete_class allocWithZone:
NSDefaultMallocZone()] initWithContentsOfFile: path]);
}
+ (NSString*) stringWithCString: (const char*)byteString