Fix fosdem changes and a few bugs exposed by them.

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@20811 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
CaS 2005-02-28 17:18:54 +00:00
parent b2d1a0346a
commit d05bb0584e
4 changed files with 136 additions and 29 deletions

View file

@ -1,3 +1,20 @@
2005-02-28 17:10 Richard Frith-Macdonald <rfm@gnu.org>
* Source/NSAutoreleasePool.m:
* Source/NSCharacterSet.m:
* Source/NSproxy.m:
Damn ... when I ran the testsuite for the stuff I did at fosdem, it
all worked ... but now I find that it was linking to an older version
of the base library and actually the changes were broken.
The new modifications should (hopefully) fix all breakage.
The changes exposed rare bugs in the existing code ...
NSCharacterSet was returning immutable copies of the standard
character sets when it should return mutable ones, it was also
being a bit bad about allocating new instances. NSProxy was
failing to implement instanceMethodForSelector:, and NSAutoreleasePool
had a bug which could mess up a bit if the objects being deallocated
by it autoreleased anything.
2005-02-28 David Ayers <d.ayers@inode.at> 2005-02-28 David Ayers <d.ayers@inode.at>
* Source/NSPropertyList.m (OAppend): Attempt to transform * Source/NSPropertyList.m (OAppend): Attempt to transform

View file

@ -327,14 +327,35 @@ static IMP initImp;
- (void) dealloc - (void) dealloc
{ {
struct autorelease_thread_vars *tv = ARP_THREAD_VARS;
/*
* Remove self from the linked list of pools in use.
* Do this *first* so that any object which does an autorelease while
* being released does not cause an object to be added to this pool!
*/
if (tv->current_pool == self)
{
tv->current_pool = _parent;
if (_parent != nil)
{
_parent->_child = nil;
}
}
// fprintf (stderr, "Deallocating an NSAutoreleasePool\n"); // fprintf (stderr, "Deallocating an NSAutoreleasePool\n");
/* If there are NSAutoreleasePool below us in the stack of /* If there are NSAutoreleasePool below us in the stack of
NSAutoreleasePools, then deallocate them also. The (only) way we NSAutoreleasePools, then deallocate them also. The (only) way we
could get in this situation (in correctly written programs, that could get in this situation (in correctly written programs, that
don't release NSAutoreleasePools in weird ways), is if an don't release NSAutoreleasePools in weird ways), is if an
exception threw us up the stack. */ exception threw us up the stack. */
if (_child) if (_child != nil)
[_child dealloc]; {
NSAutoreleasePool *child = _child;
_child = nil;
[child dealloc];
}
/* Make debugging easier by checking to see if the user already /* Make debugging easier by checking to see if the user already
dealloced the object before trying to release it. Also, take the dealloced the object before trying to release it. Also, take the
@ -366,7 +387,14 @@ static IMP initImp;
if (classes[hash] != c) if (classes[hash] != c)
{ {
classes[hash] = c; classes[hash] = c;
imps[hash] = [c methodForSelector: releaseSel]; if (GSObjCIsInstance(anObject))
{
imps[hash] = [c instanceMethodForSelector: releaseSel];
}
else
{
imps[hash] = [c methodForSelector: releaseSel];
}
} }
(imps[hash])(anObject, releaseSel); (imps[hash])(anObject, releaseSel);
} }
@ -375,20 +403,8 @@ static IMP initImp;
} }
} }
{ /* Don't deallocate ourself, just save us for later use. */
struct autorelease_thread_vars *tv; push_pool_to_cache (tv, self);
NSAutoreleasePool **cp;
/* Uninstall ourselves as the current pool; install our parent pool. */
tv = ARP_THREAD_VARS;
cp = &(tv->current_pool);
*cp = _parent;
if (*cp)
(*cp)->_child = nil;
/* Don't deallocate ourself, just save us for later use. */
push_pool_to_cache (tv, self);
}
} }
- (void) emptyPool - (void) emptyPool

View file

@ -106,15 +106,6 @@ static Class abstractClass = nil;
cache_lock = [GSLazyLock new]; cache_lock = [GSLazyLock new];
} }
/* Provide a default object for allocation */
+ (id) allocWithZone: (NSZone*)zone
{
if (self == abstractClass)
return NSAllocateObject([NSBitmapCharSet self], 0, zone);
else
return NSAllocateObject(self, 0, zone);
}
/** /**
* Creat and cache (or retrieve from cache) a characterset * Creat and cache (or retrieve from cache) a characterset
* using static bitmap data. * using static bitmap data.
@ -356,7 +347,7 @@ static Class abstractClass = nil;
- (id) initWithCoder: (NSCoder*)aCoder - (id) initWithCoder: (NSCoder*)aCoder
{ {
if ([self class] == [NSCharacterSet class]) if ([self class] == abstractClass)
{ {
int index; int index;
@ -365,7 +356,10 @@ static Class abstractClass = nil;
*/ */
DESTROY(self); DESTROY(self);
[aCoder decodeValueOfObjCType: @encode(int) at: &index]; [aCoder decodeValueOfObjCType: @encode(int) at: &index];
self = RETAIN([NSCharacterSet _staticSet: 0 number: index]); self = RETAIN([abstractClass _staticSet: 0 number: index]);
}
else
{
} }
return self; return self;
} }
@ -374,7 +368,7 @@ static Class abstractClass = nil;
{ {
if (anObject == self) if (anObject == self)
return YES; return YES;
if ([anObject isKindOfClass: [NSCharacterSet class]]) if ([anObject isKindOfClass: abstractClass])
{ {
unsigned i; unsigned i;
@ -448,6 +442,71 @@ static Class abstractClass = nil;
return AUTORELEASE([[NSMutableBitmapCharSet alloc] initWithBitmap: data]); return AUTORELEASE([[NSMutableBitmapCharSet alloc] initWithBitmap: data]);
} }
+ (NSCharacterSet*) alphanumericCharacterSet
{
return AUTORELEASE([[abstractClass performSelector: _cmd] mutableCopy]);
}
+ (NSCharacterSet*) controlCharacterSet
{
return AUTORELEASE([[abstractClass performSelector: _cmd] mutableCopy]);
}
+ (NSCharacterSet*) decimalDigitCharacterSet
{
return AUTORELEASE([[abstractClass performSelector: _cmd] mutableCopy]);
}
+ (NSCharacterSet*) decomposableCharacterSet
{
return AUTORELEASE([[abstractClass performSelector: _cmd] mutableCopy]);
}
+ (NSCharacterSet*) illegalCharacterSet
{
return AUTORELEASE([[abstractClass performSelector: _cmd] mutableCopy]);
}
+ (NSCharacterSet*) letterCharacterSet
{
return AUTORELEASE([[abstractClass performSelector: _cmd] mutableCopy]);
}
+ (NSCharacterSet*) lowercaseLetterCharacterSet
{
return AUTORELEASE([[abstractClass performSelector: _cmd] mutableCopy]);
}
+ (NSCharacterSet*) nonBaseCharacterSet
{
return AUTORELEASE([[abstractClass performSelector: _cmd] mutableCopy]);
}
+ (NSCharacterSet*) punctuationCharacterSet
{
return AUTORELEASE([[abstractClass performSelector: _cmd] mutableCopy]);
}
+ (NSCharacterSet*) symbolAndOperatorCharacterSet
{
return AUTORELEASE([[abstractClass performSelector: _cmd] mutableCopy]);
}
+ (NSCharacterSet*) uppercaseLetterCharacterSet
{
return AUTORELEASE([[abstractClass performSelector: _cmd] mutableCopy]);
}
+ (NSCharacterSet*) whitespaceAndNewlineCharacterSet
{
return AUTORELEASE([[abstractClass performSelector: _cmd] mutableCopy]);
}
+ (NSCharacterSet*) whitespaceCharacterSet
{
return AUTORELEASE([[abstractClass performSelector: _cmd] mutableCopy]);
}
/* Mutable subclasses must implement ALL of these methods. */ /* Mutable subclasses must implement ALL of these methods. */
/** /**

View file

@ -102,6 +102,17 @@ extern BOOL __objc_responds_to(id, SEL);
return [NSString stringWithFormat: @"<%s>", GSClassNameFromObject(self)]; return [NSString stringWithFormat: @"<%s>", GSClassNameFromObject(self)];
} }
+ (IMP) instanceMethodForSelector: (SEL)aSelector
{
if (aSelector == 0)
[NSException raise: NSInvalidArgumentException
format: @"%@ null selector given", NSStringFromSelector(_cmd)];
/*
* Since 'self' is an class, get_imp() will get the instance method.
*/
return get_imp((Class)self, aSelector);
}
/** /**
* Returns NO ... the NSProxy class cannot be an instance of any class. * Returns NO ... the NSProxy class cannot be an instance of any class.
*/ */
@ -128,6 +139,10 @@ extern BOOL __objc_responds_to(id, SEL);
- (IMP) methodForSelector: (SEL)aSelector - (IMP) methodForSelector: (SEL)aSelector
{ {
if (aSelector == 0)
[NSException raise: NSInvalidArgumentException
format: @"%@ null selector given", NSStringFromSelector(_cmd)];
return get_imp(GSObjCClass((id)self), aSelector); return get_imp(GSObjCClass((id)self), aSelector);
} }