mirror of
https://github.com/gnustep/libs-base.git
synced 2025-05-31 16:50:58 +00:00
Fix bug removing from index set.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@19615 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
0dee75786f
commit
97b8ebd06a
3 changed files with 112 additions and 71 deletions
|
@ -1,3 +1,10 @@
|
||||||
|
2004-06-25 Richard Frith-Macdonald <rfm@gnu.org>
|
||||||
|
|
||||||
|
* Source/NSIndexSet.m: Rewrite range removal to fix bug reported
|
||||||
|
by Fred Kiefer.
|
||||||
|
* Testing/nsindexset.m: Add test for deletion of range which has
|
||||||
|
partial overlap with two others.
|
||||||
|
|
||||||
2004-06-24 Richard Frith-Macdonald <rfm@gnu.org>
|
2004-06-24 Richard Frith-Macdonald <rfm@gnu.org>
|
||||||
|
|
||||||
* Source/NSIndexSet.m: Remove some redundant code for clarity.
|
* Source/NSIndexSet.m: Remove some redundant code for clarity.
|
||||||
|
|
|
@ -710,6 +710,7 @@ static unsigned posForIndex(GSIArray array, unsigned index)
|
||||||
- (void) removeIndexesInRange: (NSRange)aRange
|
- (void) removeIndexesInRange: (NSRange)aRange
|
||||||
{
|
{
|
||||||
unsigned pos;
|
unsigned pos;
|
||||||
|
NSRange r;
|
||||||
|
|
||||||
if (NSNotFound - aRange.length < aRange.location)
|
if (NSNotFound - aRange.length < aRange.location)
|
||||||
{
|
{
|
||||||
|
@ -717,95 +718,103 @@ static unsigned posForIndex(GSIArray array, unsigned index)
|
||||||
format: @"[%@-%@]: Bad range",
|
format: @"[%@-%@]: Bad range",
|
||||||
NSStringFromClass([self class]), NSStringFromSelector(_cmd)];
|
NSStringFromClass([self class]), NSStringFromSelector(_cmd)];
|
||||||
}
|
}
|
||||||
if (aRange.length == 0 || _array == 0 || GSIArrayCount(_array) == 0)
|
if (aRange.length == 0 || _array == 0
|
||||||
|
|| (pos = posForIndex(_array, aRange.location)) >= GSIArrayCount(_array))
|
||||||
{
|
{
|
||||||
return; // Already empty
|
return; // Already empty
|
||||||
}
|
}
|
||||||
pos = posForIndex(_array, aRange.location);
|
|
||||||
|
r = GSIArrayItemAtIndex(_array, pos).ext;
|
||||||
|
if (r.location <= aRange.location)
|
||||||
|
{
|
||||||
|
if (r.location == aRange.location)
|
||||||
|
{
|
||||||
|
if (NSMaxRange(r) <= NSMaxRange(aRange))
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Found range is entirely within range to remove,
|
||||||
|
* leaving next range to check at current position.
|
||||||
|
*/
|
||||||
|
GSIArrayRemoveItemAtIndex(_array, pos);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Range to remove is entirely within found range and
|
||||||
|
* overlaps the start of the found range ... shrink it
|
||||||
|
* and trhen we are finished.
|
||||||
|
*/
|
||||||
|
r.location += aRange.length;
|
||||||
|
r.length -= aRange.length;
|
||||||
|
GSIArraySetItemAtIndex(_array, (GSIArrayItem)r, pos);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (NSMaxRange(r) <= NSMaxRange(aRange))
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Range to remove overlaps the end of the found range.
|
||||||
|
* May also overlap next range ... so shorten found
|
||||||
|
* range and move on.
|
||||||
|
*/
|
||||||
|
r.length = aRange.location - r.location;
|
||||||
|
GSIArraySetItemAtIndex(_array, (GSIArrayItem)r, pos);
|
||||||
|
pos++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
NSRange next = r;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Remove any ranges contained entirely in the one to be removed.
|
* Range to remove is entirely within found range and
|
||||||
|
* overlaps the middle of the found range ... split it.
|
||||||
|
* Then we are finished.
|
||||||
|
*/
|
||||||
|
next.location = NSMaxRange(aRange);
|
||||||
|
next.length = NSMaxRange(r) - next.location;
|
||||||
|
r.length = aRange.location - r.location;
|
||||||
|
GSIArraySetItemAtIndex(_array, (GSIArrayItem)r, pos);
|
||||||
|
pos++;
|
||||||
|
GSIArrayInsertItem(_array, (GSIArrayItem)next, pos);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* At this point we are guaranteed that, if there is a range at pos,
|
||||||
|
* it does not start before aRange.location
|
||||||
*/
|
*/
|
||||||
while (pos < GSIArrayCount(_array))
|
while (pos < GSIArrayCount(_array))
|
||||||
{
|
{
|
||||||
NSRange r = GSIArrayItemAtIndex(_array, pos).ext;
|
NSRange r = GSIArrayItemAtIndex(_array, pos).ext;
|
||||||
|
|
||||||
if (r.location < aRange.location || NSMaxRange(r) > NSMaxRange(aRange))
|
if (NSMaxRange(r) <= NSMaxRange(aRange))
|
||||||
{
|
{
|
||||||
break;
|
/*
|
||||||
}
|
* Found range is entirely within range to remove ...
|
||||||
|
* delete it.
|
||||||
|
*/
|
||||||
GSIArrayRemoveItemAtIndex(_array, pos);
|
GSIArrayRemoveItemAtIndex(_array, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pos < GSIArrayCount(_array))
|
|
||||||
{
|
|
||||||
NSRange r = GSIArrayItemAtIndex(_array, pos).ext;
|
|
||||||
|
|
||||||
if (r.location <= aRange.location)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* The existing range might overlap or mcontain the range to remove.
|
|
||||||
*/
|
|
||||||
if (NSMaxRange(r) >= NSMaxRange(aRange))
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* Range to remove is contained in the range we found ...
|
|
||||||
*/
|
|
||||||
if (r.location == aRange.location)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* Remove from start of range.
|
|
||||||
*/
|
|
||||||
r.length -= aRange.length;
|
|
||||||
r.location += aRange.length;
|
|
||||||
GSIArraySetItemAtIndex(_array, (GSIArrayItem)r, pos);
|
|
||||||
}
|
|
||||||
else if (NSMaxRange(r) == NSMaxRange(aRange))
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* Remove from end of range.
|
|
||||||
*/
|
|
||||||
r.length -= aRange.length;
|
|
||||||
GSIArraySetItemAtIndex(_array, (GSIArrayItem)r, pos);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
NSRange t;
|
|
||||||
unsigned p;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Split the range.
|
|
||||||
*/
|
|
||||||
p = NSMaxRange(aRange);
|
|
||||||
t = NSMakeRange(p, NSMaxRange(r) - p);
|
|
||||||
GSIArrayInsertItem(_array, (GSIArrayItem)t, pos+1);
|
|
||||||
r.length = aRange.location - r.location;
|
|
||||||
GSIArraySetItemAtIndex(_array, (GSIArrayItem)r, pos);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (NSMaxRange(r) >= aRange.location)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* The range to remove overlaps the one we found.
|
|
||||||
*/
|
|
||||||
r.length = aRange.location - r.location;
|
|
||||||
GSIArraySetItemAtIndex(_array, (GSIArrayItem)r, pos);
|
|
||||||
|
|
||||||
if (++pos < GSIArrayCount(_array))
|
|
||||||
{
|
|
||||||
NSRange r = GSIArrayItemAtIndex(_array, pos).ext;
|
|
||||||
|
|
||||||
if (r.location < NSMaxRange(aRange))
|
if (r.location < NSMaxRange(aRange))
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* and also overlaps the following range.
|
* Range to remove overlaps start of found range ...
|
||||||
|
* shorten it.
|
||||||
*/
|
*/
|
||||||
r.length -= NSMaxRange(aRange) - r.location;
|
r.length = NSMaxRange(r) - NSMaxRange(aRange);
|
||||||
r.location = NSMaxRange(aRange);
|
r.location = NSMaxRange(aRange);
|
||||||
GSIArraySetItemAtIndex(_array, (GSIArrayItem)r, pos);
|
GSIArraySetItemAtIndex(_array, (GSIArrayItem)r, pos);
|
||||||
}
|
}
|
||||||
}
|
/*
|
||||||
}
|
* Found range extends beyond range to remove ... finished.
|
||||||
|
*/
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@ main ()
|
||||||
NSAutoreleasePool *arp = [NSAutoreleasePool new];
|
NSAutoreleasePool *arp = [NSAutoreleasePool new];
|
||||||
NSIndexSet *s;
|
NSIndexSet *s;
|
||||||
NSMutableIndexSet *m;
|
NSMutableIndexSet *m;
|
||||||
|
NSMutableIndexSet *o;
|
||||||
unsigned int buf[2];
|
unsigned int buf[2];
|
||||||
NSRange r;
|
NSRange r;
|
||||||
|
|
||||||
|
@ -179,6 +180,30 @@ main ()
|
||||||
[m removeIndexesInRange: NSMakeRange(0, 11)];
|
[m removeIndexesInRange: NSMakeRange(0, 11)];
|
||||||
printf(" %s\n", [m isEqual: [NSIndexSet indexSet]] == YES ? "passed" : "failed");
|
printf(" %s\n", [m isEqual: [NSIndexSet indexSet]] == YES ? "passed" : "failed");
|
||||||
|
|
||||||
|
o = [NSMutableIndexSet indexSet];
|
||||||
|
[m addIndex: 3];
|
||||||
|
[m addIndex: 4];
|
||||||
|
[m addIndex: 6];
|
||||||
|
[m addIndex: 7];
|
||||||
|
[o addIndex: 3];
|
||||||
|
[o addIndex: 7];
|
||||||
|
printf("Can remove range 4-6 from mutable set containing 3,4,6,7 ...");
|
||||||
|
[m removeIndexesInRange: NSMakeRange(4, 3)];
|
||||||
|
printf(" %s\n", [m isEqual: o] == YES ? "passed" : "failed");
|
||||||
|
|
||||||
|
[m addIndex: 3];
|
||||||
|
[m addIndex: 4];
|
||||||
|
[m addIndex: 6];
|
||||||
|
[m addIndex: 7];
|
||||||
|
[m addIndex: 8];
|
||||||
|
[m addIndex: 9];
|
||||||
|
[o addIndex: 3];
|
||||||
|
[o removeIndex: 7];
|
||||||
|
[o addIndex: 9];
|
||||||
|
printf("Can remove range 4-8 from mutable set containing 3,4,6,7,8,9 ...");
|
||||||
|
[m removeIndexesInRange: NSMakeRange(4, 5)];
|
||||||
|
printf(" %s\n", [m isEqual: o] == YES ? "passed" : "failed");
|
||||||
|
|
||||||
// NSLog(@"%@", m);
|
// NSLog(@"%@", m);
|
||||||
[arp release];
|
[arp release];
|
||||||
exit (0);
|
exit (0);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue