Merge branch 'master' into master

This commit is contained in:
rfm 2024-11-29 09:38:36 +00:00 committed by GitHub
commit f371b8068e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 631 additions and 173 deletions

View file

@ -18,6 +18,28 @@
* type_encoding.m: add test NSINSETS_ENCODING_PREFIX. * type_encoding.m: add test NSINSETS_ENCODING_PREFIX.
* GSConcreteValueTamplate.m: add GSEdgeInsetsValue. * GSConcreteValueTamplate.m: add GSEdgeInsetsValue.
* GSConcreteValue.m: add TYPE_ORDER 6. * GSConcreteValue.m: add TYPE_ORDER 6.
2024-11-24 Richard Frith-Macdonald <rfm@gnu.org>
* Source/NSSocketPort.m: fix leak of data object when establishing a
new connection.
2024-11-22 Richard Frith-Macdonald <rfm@gnu.org>
* Tools/AGSIndex: (-makeRefs:) process child nodes in loop rather
than recursively ... reduces the depth of recursion to the depth of
nesting children rather than the number of children, avoiding stack
overflow for large projects.
* Source/GSHTTPURLHandle.m: Fix leak of connection description strings
when reconnecting an existing handle.
2024-11-21 Richard Frith-Macdonald <rfm@gnu.org>
* NSRegularExpression: avoid leaks in ICU code by calling more
primitive methods.
* NSAutoreleasePool: fix leaks with libobjc2 ARC methods when a pool
is in a context that we leave due to an exception.
* NSObject: add -trackOwnership to log the retain/release/dealloc of
in individual instance.
2024-11-19 Richard Frith-Macdonald <rfm@gnu.org> 2024-11-19 Richard Frith-Macdonald <rfm@gnu.org>

View file

@ -295,6 +295,14 @@ extern "C" {
*/ */
+ (BOOL) shouldCleanUp; + (BOOL) shouldCleanUp;
/** Turns on tracking of retain/release for instances of the receiver.
*/
+ (void) trackOwnership;
/** Turns on tracking of retain/release for the receiver.
*/
- (void) trackOwnership;
@end @end
/* Macro to take an autoreleased object and either make it immutable or /* Macro to take an autoreleased object and either make it immutable or

View file

@ -121,7 +121,6 @@ static Class NSArrayClass = 0;
static Class NSStringClass = 0; static Class NSStringClass = 0;
static Class NSDataClass = 0; static Class NSDataClass = 0;
static Class documentClass = 0; static Class documentClass = 0;
static Class headerClass = 0;
static BOOL oldStyleFolding = NO; static BOOL oldStyleFolding = NO;
static NSString *Cte7bit = @"7bit"; static NSString *Cte7bit = @"7bit";
@ -888,6 +887,29 @@ wordData(NSString *word, BOOL *encoded)
+ (void) initialize + (void) initialize
{ {
NSMutableCharacterSet *m = [[NSMutableCharacterSet alloc] init];
[m formUnionWithCharacterSet:
[NSCharacterSet characterSetWithCharactersInString:
@".()<>@,;:[]\"\\"]];
[m formUnionWithCharacterSet:
[NSCharacterSet whitespaceAndNewlineCharacterSet]];
[m formUnionWithCharacterSet:
[NSCharacterSet controlCharacterSet]];
[m formUnionWithCharacterSet:
[NSCharacterSet illegalCharacterSet]];
rfc822Specials = [m copy];
[[NSObject leakAt: &rfc822Specials] release];
[m formUnionWithCharacterSet:
[NSCharacterSet characterSetWithCharactersInString:
@"/?="]];
[m removeCharactersInString: @"."];
rfc2045Specials = [m copy];
[[NSObject leakAt: &rfc2045Specials] release];
[m release];
whitespace = RETAIN([NSCharacterSet whitespaceAndNewlineCharacterSet]);
[[NSObject leakAt: &whitespace] release];
if (NSArrayClass == 0) if (NSArrayClass == 0)
{ {
NSArrayClass = [NSArray class]; NSArrayClass = [NSArray class];
@ -904,10 +926,6 @@ wordData(NSString *word, BOOL *encoded)
{ {
documentClass = [GSMimeDocument class]; documentClass = [GSMimeDocument class];
} }
if (headerClass == 0)
{
headerClass = [GSMimeHeader class];
}
} }
/** /**
@ -1745,7 +1763,7 @@ wordData(NSString *word, BOOL *encoded)
/* /*
* Set the header name. * Set the header name.
*/ */
info = [headerClass headerWithName: name info = [GSMimeHeader headerWithName: name
value: nil value: nil
parameters: nil]; parameters: nil];
name = [info name]; name = [info name];
@ -3395,10 +3413,6 @@ static NSCharacterSet *tokenSet = nil;
{ {
documentClass = [GSMimeDocument class]; documentClass = [GSMimeDocument class];
} }
if (headerClass == 0)
{
headerClass = [GSMimeHeader class];
}
[[NSNotificationCenter defaultCenter] addObserver: self [[NSNotificationCenter defaultCenter] addObserver: self
selector: @selector(_defaultsChanged:) selector: @selector(_defaultsChanged:)
name: NSUserDefaultsDidChangeNotification name: NSUserDefaultsDidChangeNotification
@ -3607,7 +3621,7 @@ static NSCharacterSet *tokenSet = nil;
NSEnumerator *e; NSEnumerator *e;
NSString *k; NSString *k;
c = [headerClass allocWithZone: z]; c = [[self class] allocWithZone: z];
c = [c initWithName: [self namePreservingCase: YES] c = [c initWithName: [self namePreservingCase: YES]
value: [self value] value: [self value]
parameters: [self parametersPreservingCase: YES]]; parameters: [self parametersPreservingCase: YES]];
@ -3722,7 +3736,7 @@ static NSCharacterSet *tokenSet = nil;
{ {
NSString *v; NSString *v;
v = [headerClass makeQuoted: [params objectForKey: k] always: NO]; v = [[self class] makeQuoted: [params objectForKey: k] always: NO];
[m appendString: @"; "]; [m appendString: @"; "];
[m appendString: k]; [m appendString: k];
[m appendString: @"="]; [m appendString: @"="];
@ -3769,7 +3783,7 @@ static NSCharacterSet *tokenSet = nil;
value: (NSString*)v value: (NSString*)v
parameters: (NSDictionary*)p parameters: (NSDictionary*)p
{ {
n = [headerClass makeToken: n preservingCase: YES]; n = [[self class] makeToken: n preservingCase: YES];
if ([n length] == 0) if ([n length] == 0)
{ {
n = @"unknown"; n = @"unknown";
@ -3807,7 +3821,7 @@ static NSCharacterSet *tokenSet = nil;
{ {
return YES; return YES;
} }
if (NO == [other isKindOfClass: headerClass]) if (NO == [other isKindOfClass: [self class]])
{ {
return NO; return NO;
} }
@ -3876,7 +3890,7 @@ static NSCharacterSet *tokenSet = nil;
if (p == nil) if (p == nil)
{ {
k = [headerClass makeToken: k]; k = [[self class] makeToken: k];
p = [params objectForKey: k]; p = [params objectForKey: k];
} }
return p; return p;
@ -4540,7 +4554,7 @@ appendString(NSMutableData *m, NSUInteger offset, NSUInteger fold,
NSUInteger kLength; NSUInteger kLength;
NSUInteger vLength; NSUInteger vLength;
v = [headerClass makeQuoted: [params objectForKey: k] always: NO]; v = [[self class] makeQuoted: [params objectForKey: k] always: NO];
if (preserve == NO) if (preserve == NO)
{ {
k = [k lowercaseString]; k = [k lowercaseString];
@ -4628,7 +4642,7 @@ appendString(NSMutableData *m, NSUInteger offset, NSUInteger fold,
*/ */
- (void) setParameter: (NSString*)v forKey: (NSString*)k - (void) setParameter: (NSString*)v forKey: (NSString*)k
{ {
k = [headerClass makeToken: k preservingCase: YES]; k = [[self class] makeToken: k preservingCase: YES];
if (v == nil) if (v == nil)
{ {
[params removeObjectForKey: k]; [params removeObjectForKey: k];
@ -4662,7 +4676,7 @@ appendString(NSMutableData *m, NSUInteger offset, NSUInteger fold,
{ {
NSString *v = [d objectForKey: k]; NSString *v = [d objectForKey: k];
k = [headerClass makeToken: k preservingCase: YES]; k = [[self class] makeToken: k preservingCase: YES];
[m setObject: v forKey: k]; [m setObject: v forKey: k];
} }
} }
@ -5216,32 +5230,11 @@ appendString(NSMutableData *m, NSUInteger offset, NSUInteger fold,
{ {
if (self == [GSMimeDocument class]) if (self == [GSMimeDocument class])
{ {
NSMutableCharacterSet *m = [[NSMutableCharacterSet alloc] init];
if (documentClass == 0) if (documentClass == 0)
{ {
documentClass = [GSMimeDocument class]; documentClass = [GSMimeDocument class];
} }
[m formUnionWithCharacterSet:
[NSCharacterSet characterSetWithCharactersInString:
@".()<>@,;:[]\"\\"]];
[m formUnionWithCharacterSet:
[NSCharacterSet whitespaceAndNewlineCharacterSet]];
[m formUnionWithCharacterSet:
[NSCharacterSet controlCharacterSet]];
[m formUnionWithCharacterSet:
[NSCharacterSet illegalCharacterSet]];
rfc822Specials = [m copy];
[[NSObject leakAt: &rfc822Specials] release];
[m formUnionWithCharacterSet:
[NSCharacterSet characterSetWithCharactersInString:
@"/?="]];
[m removeCharactersInString: @"."];
rfc2045Specials = [m copy];
[[NSObject leakAt: &rfc2045Specials] release];
[m release];
whitespace = RETAIN([NSCharacterSet whitespaceAndNewlineCharacterSet]);
[[NSObject leakAt: &whitespace] release];
if (NSArrayClass == 0) if (NSArrayClass == 0)
{ {
NSArrayClass = [NSArray class]; NSArrayClass = [NSArray class];
@ -5812,10 +5805,6 @@ appendString(NSMutableData *m, NSUInteger offset, NSUInteger fold,
(void*)@"gb18030"); (void*)@"gb18030");
#endif #endif
} }
if (headerClass == 0)
{
headerClass = [GSMimeHeader class];
}
} }
} }
@ -5926,7 +5915,7 @@ appendString(NSMutableData *m, NSUInteger offset, NSUInteger fold,
{ {
GSMimeHeader *hdr; GSMimeHeader *hdr;
hdr = [headerClass alloc]; hdr = [GSMimeHeader alloc];
hdr = [hdr initWithName: name hdr = [hdr initWithName: name
value: value value: value
parameters: parameters]; parameters: parameters];
@ -6685,7 +6674,7 @@ appendString(NSMutableData *m, NSUInteger offset, NSUInteger fold,
oaiIMP imp1; oaiIMP imp1;
boolIMP imp2; boolIMP imp2;
name = [headerClass makeToken: name preservingCase: NO]; name = [GSMimeHeader makeToken: name preservingCase: NO];
imp1 = (oaiIMP)[headers methodForSelector: @selector(objectAtIndex:)]; imp1 = (oaiIMP)[headers methodForSelector: @selector(objectAtIndex:)];
imp2 = (boolIMP)[name methodForSelector: @selector(isEqualToString:)]; imp2 = (boolIMP)[name methodForSelector: @selector(isEqualToString:)];
for (index = 0; index < count; index++) for (index = 0; index < count; index++)
@ -6710,7 +6699,7 @@ appendString(NSMutableData *m, NSUInteger offset, NSUInteger fold,
{ {
NSUInteger count; NSUInteger count;
name = [headerClass makeToken: name preservingCase: NO]; name = [GSMimeHeader makeToken: name preservingCase: NO];
count = [headers count]; count = [headers count];
if (count > 0) if (count > 0)
{ {
@ -6841,7 +6830,7 @@ appendString(NSMutableData *m, NSUInteger offset, NSUInteger fold,
{ {
GSMimeHeader *hdr; GSMimeHeader *hdr;
hdr = [[headerClass alloc] initWithName: name hdr = [[GSMimeHeader alloc] initWithName: name
value: value value: value
parameters: parameters]; parameters: parameters];
[self setHeader: hdr]; [self setHeader: hdr];
@ -7504,7 +7493,7 @@ appendString(NSMutableData *m, NSUInteger offset, NSUInteger fold,
GSMimeParser *p = AUTORELEASE([GSMimeParser new]); GSMimeParser *p = AUTORELEASE([GSMimeParser new]);
NSScanner *scanner = [NSScanner scannerWithString: type]; NSScanner *scanner = [NSScanner scannerWithString: type];
hdr = [headerClass headerWithName: @"Content-Type" hdr = [GSMimeHeader headerWithName: @"Content-Type"
value: nil value: nil
parameters: nil]; parameters: nil];
if ([p scanHeaderBody: scanner into: hdr] == NO) if ([p scanHeaderBody: scanner into: hdr] == NO)
@ -7519,7 +7508,7 @@ appendString(NSMutableData *m, NSUInteger offset, NSUInteger fold,
NSString *val; NSString *val;
val = [NSStringClass stringWithFormat: @"%@/%@", type, subtype]; val = [NSStringClass stringWithFormat: @"%@/%@", type, subtype];
hdr = [headerClass alloc]; hdr = [GSMimeHeader alloc];
hdr = [hdr initWithName: @"Content-Type" value: val parameters: nil]; hdr = [hdr initWithName: @"Content-Type" value: val parameters: nil];
[hdr setObject: type forKey: @"Type"]; [hdr setObject: type forKey: @"Type"];
[hdr setObject: subtype forKey: @"Subtype"]; [hdr setObject: subtype forKey: @"Subtype"];
@ -7565,7 +7554,7 @@ appendString(NSMutableData *m, NSUInteger offset, NSUInteger fold,
p = AUTORELEASE([GSMimeParser new]); p = AUTORELEASE([GSMimeParser new]);
scanner = [NSScanner scannerWithString: newType]; scanner = [NSScanner scannerWithString: newType];
hdr = [headerClass headerWithName: @"Content-Type" hdr = [GSMimeHeader headerWithName: @"Content-Type"
value: nil value: nil
parameters: nil]; parameters: nil];
if ([p scanHeaderBody: scanner into: hdr] == NO) if ([p scanHeaderBody: scanner into: hdr] == NO)
@ -7600,7 +7589,7 @@ appendString(NSMutableData *m, NSUInteger offset, NSUInteger fold,
{ {
GSMimeHeader *hdr; GSMimeHeader *hdr;
hdr = [headerClass alloc]; hdr = [GSMimeHeader alloc];
hdr = [hdr initWithName: name hdr = [hdr initWithName: name
value: value value: value
parameters: parameters]; parameters: parameters];

View file

@ -146,6 +146,11 @@
@end @end
#if defined(GNUSTEP) #if defined(GNUSTEP)
@interface NSAutoreleasePool (NSThread)
+ (void) _endThread: (NSThread*)thread;
@end
struct exitLink { struct exitLink {
struct exitLink *next; struct exitLink *next;
id obj; // Object to release or class for atExit id obj; // Object to release or class for atExit
@ -235,6 +240,11 @@ handleExit()
{ {
GSUnregisterCurrentThread(); GSUnregisterCurrentThread();
} }
else
{
[[NSAutoreleasePool currentPool] dealloc];
[NSAutoreleasePool _endThread: GSCurrentThread()];
}
isExiting = NO; isExiting = NO;
} }
@ -419,6 +429,290 @@ handleExit()
return shouldCleanUp; return shouldCleanUp;
} }
struct trackLink {
struct trackLink *next;
id object; // Instance or Class being tracked.
IMP dealloc; // Original -dealloc implementation
IMP release; // Original -release implementation
IMP retain; // Original -retain implementation
BOOL global; // If all instance are tracked.
};
static struct trackLink *tracked = 0;
static gs_mutex_t trackLock = GS_MUTEX_INIT_STATIC;
static inline struct trackLink *
find(id o)
{
struct trackLink *l = tracked;
while (l)
{
if (l->object == o)
{
return l;
}
l = l->next;
}
return NULL;
}
/* Lookup the object in the tracking list.
* If found as a tracked instance or found as an instance of a class for which
* all instances are tracked, return YES. Otherwise return NO (should not log).
*/
static BOOL
findMethods(id o, IMP *dea, IMP *rel, IMP *ret)
{
struct trackLink *l;
Class c;
GS_MUTEX_LOCK(trackLock);
l = find(o);
if (l)
{
*dea = l->dealloc;
*rel = l->release;
*ret = l->retain;
GS_MUTEX_UNLOCK(trackLock);
return YES;
}
c = object_getClass(o);
l = find((id)c);
if (l)
{
BOOL all;
*dea = l->dealloc;
*rel = l->release;
*ret = l->retain;
all = l->global;
GS_MUTEX_UNLOCK(trackLock);
return all;
}
GS_MUTEX_UNLOCK(trackLock);
/* Should never happen because we don't remove class entries, but I suppose
* someone could call the replacement methods directly.
*/
*dea = [c instanceMethodForSelector: @selector(dealloc)];
*rel = [c instanceMethodForSelector: @selector(release)];
*ret = [c instanceMethodForSelector: @selector(retain)];
return NO;
}
- (void) _replacementDealloc
{
IMP dealloc = 0;
IMP retain = 0;
IMP release = 0;
if (findMethods(self, &dealloc, &release, &retain) == NO)
{
/* Not a tracked instance ... dealloc without logging.
*/
(*dealloc)(self, _cmd);
}
else
{
struct trackLink *l;
/* If there's a link for tracking this specific instance, remove it.
*/
GS_MUTEX_LOCK(trackLock);
if ((l = tracked) != 0)
{
if (l->object == self)
{
tracked = l->next;
free(l);
}
else
{
struct trackLink *n;
while ((n = l->next) != 0)
{
if (n->object == self)
{
l->next = n->next;
free(n);
break;
}
l = n;
}
}
}
GS_MUTEX_UNLOCK(trackLock);
NSLog(@"Tracking ownership -[%p dealloc] at %@",
self, [NSThread callStackSymbols]);
(*dealloc)(self, _cmd);
}
}
- (void) _replacementRelease
{
IMP dealloc = 0;
IMP retain = 0;
IMP release = 0;
if (findMethods(self, &dealloc, &release, &retain) == NO)
{
/* Not a tracked instance ... release without logging.
*/
(*release)(self, _cmd);
}
else
{
unsigned rc;
rc = (unsigned)[self retainCount];
NSLog(@"Tracking ownership -[%p release] %u->%u at %@",
self, rc, rc-1, [NSThread callStackSymbols]);
(*release)(self, _cmd);
}
}
- (id) _replacementRetain
{
IMP dealloc = 0;
IMP retain = 0;
IMP release = 0;
id result;
if (findMethods(self, &dealloc, &release, &retain) == NO)
{
/* Not a tracked instance ... retain without logging.
*/
result = (*retain)(self, _cmd);
}
else
{
unsigned rc;
rc = (unsigned)[self retainCount];
result = (*retain)(self, _cmd);
NSLog(@"Tracking ownership -[%p retain] %u->%u at %@",
self, rc, (unsigned)[self retainCount], [NSThread callStackSymbols]);
}
return result;
}
static struct trackLink*
makeLinkForClass(Class c)
{
Method replacementDealloc;
Method replacementRelease;
Method replacementRetain;
struct trackLink *l;
replacementDealloc = class_getInstanceMethod([NSObject class],
@selector(_replacementDealloc));
replacementRelease = class_getInstanceMethod([NSObject class],
@selector(_replacementRelease));
replacementRetain = class_getInstanceMethod([NSObject class],
@selector(_replacementRetain));
l = (struct trackLink*)malloc(sizeof(struct trackLink));
l->object = c;
l->dealloc = class_getMethodImplementation(c, @selector(dealloc));
class_replaceMethod(c, @selector(dealloc),
method_getImplementation(replacementDealloc),
method_getTypeEncoding(replacementDealloc));
l->release = class_getMethodImplementation(c, @selector(release));
class_replaceMethod(c, @selector(release),
method_getImplementation(replacementRelease),
method_getTypeEncoding(replacementRelease));
l->retain = class_getMethodImplementation(c, @selector(retain));
class_replaceMethod(c, @selector(retain),
method_getImplementation(replacementRetain),
method_getTypeEncoding(replacementRetain));
return l;
}
+ (void) trackOwnership
{
Class c = self;
struct trackLink *l;
NSAssert(NO == class_isMetaClass(object_getClass(self)),
NSInternalInconsistencyException);
GS_MUTEX_LOCK(trackLock);
if ((l = find((id)c)) != 0)
{
/* Class already tracked. Set it so all instances are logged.
*/
l->global = YES;
GS_MUTEX_UNLOCK(trackLock);
return;
}
l = makeLinkForClass(c);
l->global = YES;
l->next = tracked;
tracked = l;
GS_MUTEX_UNLOCK(trackLock);
NSLog(@"Tracking ownership started for class %p at %@",
self, [NSThread callStackSymbols]);
}
- (void) trackOwnership
{
Class c = object_getClass(self);
struct trackLink *l;
struct trackLink *lc;
struct trackLink *li;
NSAssert(NO == class_isMetaClass(c), NSInternalInconsistencyException);
GS_MUTEX_LOCK(trackLock);
if ((l = find(self)) != 0)
{
/* Instance already tracked.
*/
GS_MUTEX_UNLOCK(trackLock);
return;
}
if ((l = find(c)) != 0)
{
/* The class already has tracking set up.
*/
if (l->global)
{
/* All instances are logged, so we have nothing to do.
*/
GS_MUTEX_UNLOCK(trackLock);
return;
}
lc = l;
}
else
{
/* Set this class up for tracking individual instances.
*/
lc = makeLinkForClass(c);
lc->global = NO;
lc->next = tracked;
tracked = lc;
}
/* Now set up a record to track this one instance.
*/
li = (struct trackLink*)malloc(sizeof(struct trackLink));
li->object = self;
li->global = NO;
li->dealloc = lc->dealloc;
li->release = lc->release;
li->retain = lc->retain;
li->next = tracked;
tracked = li;
GS_MUTEX_UNLOCK(trackLock);
NSLog(@"Tracking ownership started for instance %p at %@",
self, [NSThread callStackSymbols]);
}
@end @end
#else #else

View file

@ -40,6 +40,7 @@
static SEL eqSel; static SEL eqSel;
static SEL oaiSel; static SEL oaiSel;
static Class GSArrayClass;
static Class GSInlineArrayClass; static Class GSInlineArrayClass;
/* This class stores objects inline in data beyond the end of the instance. /* This class stores objects inline in data beyond the end of the instance.
*/ */
@ -107,6 +108,7 @@ static Class GSInlineArrayClass;
[self setVersion: 1]; [self setVersion: 1];
eqSel = @selector(isEqual:); eqSel = @selector(isEqual:);
oaiSel = @selector(objectAtIndex:); oaiSel = @selector(objectAtIndex:);
GSArrayClass = self;
GSInlineArrayClass = [GSInlineArray class]; GSInlineArrayClass = [GSInlineArray class];
} }
} }
@ -1195,8 +1197,17 @@ static Class GSInlineArrayClass;
- (id) initWithObjects: (const id[])objects count: (NSUInteger)count - (id) initWithObjects: (const id[])objects count: (NSUInteger)count
{ {
self = (id)NSAllocateObject(GSInlineArrayClass, sizeof(id)*count, NSZone *z = [self zone];
[self zone]);
/* The gnustep-make -asan=yes option enables LeakSanitizer but (Nov2024)
* that produces false positives for items held in an inline array, so
* we use the less efficient class in that case.
*/
#if defined(GS_WITH_ASAN)
self = (id)NSAllocateObject(GSArrayClass, 0, z);
#else
self = (id)NSAllocateObject(GSInlineArrayClass, sizeof(id)*count, z);
#endif
return [self initWithObjects: objects count: count]; return [self initWithObjects: objects count: count];
} }

View file

@ -1173,12 +1173,12 @@ debugWrite(GSHTTPURLHandle *handle, NSData *data)
return; return;
} }
in = [[NSString alloc] initWithFormat: @"(%@:%@ <-- %@:%@)", ASSIGN(in, ([NSString stringWithFormat: @"(%@:%@ <-- %@:%@)",
[sock socketLocalAddress], [sock socketLocalService], [sock socketLocalAddress], [sock socketLocalService],
[sock socketAddress], [sock socketService]]; [sock socketAddress], [sock socketService]]));
out = [[NSString alloc] initWithFormat: @"(%@:%@ --> %@:%@)", ASSIGN(out, ([NSString stringWithFormat: @"(%@:%@ --> %@:%@)",
[sock socketLocalAddress], [sock socketLocalService], [sock socketLocalAddress], [sock socketLocalService],
[sock socketAddress], [sock socketService]]; [sock socketAddress], [sock socketService]]));
if (debug) if (debug)
{ {

View file

@ -166,7 +166,7 @@ UTextNSMutableStringReplace(UText *ut,
// Setting the chunk length to 0 here forces UTextNSStringAccess to fetch // Setting the chunk length to 0 here forces UTextNSStringAccess to fetch
// the data from the string object. // the data from the string object.
ut->chunkLength = 0; ut->chunkLength = 0;
UTextNSStringAccess(ut, r.location + [replacement length] + 1, TRUE); UTextNSStringAccess(ut, r.location + [replacement length], TRUE);
ut->chunkOffset++; ut->chunkOffset++;
[replacement release]; [replacement release];

View file

@ -43,6 +43,8 @@
#define LOG_LIFETIME 0
/* When this is `NO', autoreleased objects are never actually recorded /* When this is `NO', autoreleased objects are never actually recorded
in an NSAutoreleasePool, and are not sent a `release' message. in an NSAutoreleasePool, and are not sent a `release' message.
Thus memory for objects use grows, and grows, and... */ Thus memory for objects use grows, and grows, and... */
@ -73,10 +75,10 @@ static unsigned pool_number_warning_threshold = 10000;
already alloc'ed. The cache is kept in the autorelease_thread_var already alloc'ed. The cache is kept in the autorelease_thread_var
structure, which is an ivar of NSThread. */ structure, which is an ivar of NSThread. */
static id pop_pool_from_cache (struct autorelease_thread_vars *tv); static id pop_pool_from_cache(struct autorelease_thread_vars *tv);
static inline void static inline void
free_pool_cache (struct autorelease_thread_vars *tv) free_pool_cache(struct autorelease_thread_vars *tv)
{ {
while (tv->pool_cache_count) while (tv->pool_cache_count)
{ {
@ -94,7 +96,7 @@ free_pool_cache (struct autorelease_thread_vars *tv)
} }
static inline void static inline void
init_pool_cache (struct autorelease_thread_vars *tv) init_pool_cache(struct autorelease_thread_vars *tv)
{ {
tv->pool_cache_size = 32; tv->pool_cache_size = 32;
tv->pool_cache_count = 0; tv->pool_cache_count = 0;
@ -103,11 +105,11 @@ init_pool_cache (struct autorelease_thread_vars *tv)
} }
static void static void
push_pool_to_cache (struct autorelease_thread_vars *tv, id p) push_pool_to_cache(struct autorelease_thread_vars *tv, id p)
{ {
if (!tv->pool_cache) if (!tv->pool_cache)
{ {
init_pool_cache (tv); init_pool_cache(tv);
} }
else if (tv->pool_cache_count == tv->pool_cache_size) else if (tv->pool_cache_count == tv->pool_cache_size)
{ {
@ -119,7 +121,7 @@ push_pool_to_cache (struct autorelease_thread_vars *tv, id p)
} }
static id static id
pop_pool_from_cache (struct autorelease_thread_vars *tv) pop_pool_from_cache(struct autorelease_thread_vars *tv)
{ {
return tv->pool_cache[--(tv->pool_cache_count)]; return tv->pool_cache[--(tv->pool_cache_count)];
} }
@ -138,10 +140,11 @@ pop_pool_from_cache (struct autorelease_thread_vars *tv)
+ (id) allocWithZone: (NSZone*)zone + (id) allocWithZone: (NSZone*)zone
{ {
struct autorelease_thread_vars *tv = ARP_THREAD_VARS; struct autorelease_thread_vars *tv = ARP_THREAD_VARS;
NSAutoreleasePool *p;
if (tv->pool_cache_count) if (tv->pool_cache_count)
{ {
NSAutoreleasePool *p = pop_pool_from_cache (tv); p = pop_pool_from_cache(tv);
/* When we cache a 'deallocated' pool, we set its _released_count to /* When we cache a 'deallocated' pool, we set its _released_count to
* UINT_MAX, so when we rtrieve it fromm the cache we must increment * UINT_MAX, so when we rtrieve it fromm the cache we must increment
@ -154,7 +157,14 @@ pop_pool_from_cache (struct autorelease_thread_vars *tv)
} }
return p; return p;
} }
return NSAllocateObject (self, 0, zone); p = (NSAutoreleasePool*)NSAllocateObject (self, 0, zone);
#if LOG_LIFETIME
fprintf(stderr, "*** %p autorelease pool allocated in %p\n",
p, GSCurrentThread());
#endif
return p;
} }
+ (id) new + (id) new
@ -174,6 +184,37 @@ pop_pool_from_cache (struct autorelease_thread_vars *tv)
return (*initImp)(arp, @selector(init)); return (*initImp)(arp, @selector(init));
} }
- (void) _emptyChild
{
/* If there are NSAutoreleasePool below us in the list of
* NSAutoreleasePools, then deallocate them also.
* The (only) way we could get in this situation (in correctly
* written programs, that don't release NSAutoreleasePools in
* weird ways), is if an exception threw us up the stack.
* However, if a program has leaked pools we may be deallocating
* a pool with LOTS of children. To avoid stack overflow we
* therefore deallocate children starting with the oldest first.
*/
if (nil != _child)
{
NSAutoreleasePool *pool = _child;
/* Find other end of linked list ... oldest child.
*/
while (nil != pool->_child)
{
pool = pool->_child;
}
/* Deallocate the children in the list.
*/
while (pool != self)
{
pool = pool->_parent;
[pool->_child dealloc];
}
}
}
#ifdef ARC_RUNTIME #ifdef ARC_RUNTIME
- (id) init - (id) init
@ -188,6 +229,7 @@ pop_pool_from_cache (struct autorelease_thread_vars *tv)
{ {
NSAutoreleasePool *pool = _parent; NSAutoreleasePool *pool = _parent;
_child = _parent->_child;
while (nil != pool) while (nil != pool)
{ {
level++; level++;
@ -240,8 +282,13 @@ pop_pool_from_cache (struct autorelease_thread_vars *tv)
- (void) emptyPool - (void) emptyPool
{ {
struct autorelease_thread_vars *tv = ARP_THREAD_VARS; struct autorelease_thread_vars *tv = ARP_THREAD_VARS;
tv->current_pool = self;
if (nil != _child)
{
[self _emptyChild];
}
objc_autoreleasePoolPop(_released); objc_autoreleasePoolPop(_released);
tv->current_pool = self;
} }
/** /**
* Indicate to the runtime that we have an ARC-compatible implementation of * Indicate to the runtime that we have an ARC-compatible implementation of
@ -282,11 +329,13 @@ pop_pool_from_cache (struct autorelease_thread_vars *tv)
{ {
struct autorelease_thread_vars *tv = ARP_THREAD_VARS; struct autorelease_thread_vars *tv = ARP_THREAD_VARS;
unsigned level = 0; unsigned level = 0;
_parent = tv->current_pool; _parent = tv->current_pool;
if (_parent) if (_parent)
{ {
NSAutoreleasePool *pool = _parent; NSAutoreleasePool *pool = _parent;
_child = _parent->_child;
while (nil != pool) while (nil != pool)
{ {
level++; level++;
@ -449,32 +498,9 @@ pop_pool_from_cache (struct autorelease_thread_vars *tv)
{ {
volatile struct autorelease_array_list *released; volatile struct autorelease_array_list *released;
/* If there are NSAutoreleasePool below us in the list of
* NSAutoreleasePools, then deallocate them also.
* The (only) way we could get in this situation (in correctly
* written programs, that don't release NSAutoreleasePools in
* weird ways), is if an exception threw us up the stack.
* However, if a program has leaked pools we may be deallocating
* a pool with LOTS of children. To avoid stack overflow we
* therefore deallocate children starting with the oldest first.
*/
if (nil != _child) if (nil != _child)
{ {
NSAutoreleasePool *pool = _child; [self _emptyChild];
/* Find other end of linked list ... oldest child.
*/
while (nil != pool->_child)
{
pool = pool->_child;
}
/* Deallocate the children in the list.
*/
while (pool != self)
{
pool = pool->_parent;
[pool->_child dealloc];
}
} }
/* Take the object out of the released list just before releasing it, /* Take the object out of the released list just before releasing it,
@ -593,13 +619,14 @@ pop_pool_from_cache (struct autorelease_thread_vars *tv)
_released_count = UINT_MAX; _released_count = UINT_MAX;
/* Don't deallocate ourself, just save us for later use. */ /* Don't deallocate ourself, just save us for later use. */
push_pool_to_cache (tv, self); push_pool_to_cache(tv, self);
GSNOSUPERDEALLOC; GSNOSUPERDEALLOC;
} }
- (void) _reallyDealloc - (void) _reallyDealloc
{ {
struct autorelease_array_list *a; struct autorelease_array_list *a;
for (a = _released_head; a;) for (a = _released_head; a;)
{ {
void *n = a->next; void *n = a->next;
@ -607,6 +634,10 @@ pop_pool_from_cache (struct autorelease_thread_vars *tv)
a = n; a = n;
} }
_released = _released_head = 0; _released = _released_head = 0;
#if LOG_LIFETIME
fprintf(stderr, "*** %p autorelease pool really dealloc\n", self);
#endif
[super dealloc]; [super dealloc];
} }

View file

@ -839,9 +839,12 @@ _find_paths(NSString *rootPath, NSString *subPath, NSString *localization)
addBundlePath(array, contents, primary, nil, nil); addBundlePath(array, contents, primary, nil, nil);
if (localization) if (localization)
{
if ([localization length])
{ {
primary = [primary stringByAppendingPathComponent: primary = [primary stringByAppendingPathComponent:
[localization stringByAppendingPathExtension: @"lproj"]]; [localization stringByAppendingPathExtension: @"lproj"]];
}
contents = bundle_directory_readable(primary); contents = bundle_directory_readable(primary);
addBundlePath(array, contents, primary, nil, nil); addBundlePath(array, contents, primary, nil, nil);
} }
@ -860,9 +863,12 @@ _find_paths(NSString *rootPath, NSString *subPath, NSString *localization)
} }
} }
if (localization) if (localization)
{
if ([localization length])
{ {
primary = [originalPrimary stringByAppendingPathComponent: primary = [originalPrimary stringByAppendingPathComponent:
[localization stringByAppendingPathExtension: @"lproj"]]; [localization stringByAppendingPathExtension: @"lproj"]];
}
contents = bundle_directory_readable(primary); contents = bundle_directory_readable(primary);
addBundlePath(array, contents, primary, nil, nil); addBundlePath(array, contents, primary, nil, nil);
} }

View file

@ -35,9 +35,19 @@
* won't work because libicu internally renames all entry points with some cpp * won't work because libicu internally renames all entry points with some cpp
* magic. * magic.
*/ */
#if !defined(HAVE_UREGEX_OPENUTEXT)
#if U_ICU_VERSION_MAJOR_NUM > 4 || (U_ICU_VERSION_MAJOR_NUM == 4 && U_ICU_VERSION_MINOR_NUM >= 4) || defined(HAVE_ICU_H) #if U_ICU_VERSION_MAJOR_NUM > 4 || (U_ICU_VERSION_MAJOR_NUM == 4 && U_ICU_VERSION_MINOR_NUM >= 4) || defined(HAVE_ICU_H)
#define HAVE_UREGEX_OPENUTEXT 1 #define HAVE_UREGEX_OPENUTEXT 1
#endif #endif
#endif
/* Until the uregex_replaceAllUText() and uregex_replaceFirstUText() work
* without leaking memory, we can't use them :-(
* Preoblem exists on Ubuntu in 2024 with icu-74.2
*/
#if defined(HAVE_UREGEX_OPENUTEXT)
#undef HAVE_UREGEX_OPENUTEXT
#endif
#define NSRegularExpressionWorks #define NSRegularExpressionWorks
@ -158,7 +168,8 @@ NSRegularExpressionOptionsToURegexpFlags(NSRegularExpressionOptions opts)
NSDictionary *userInfo; NSDictionary *userInfo;
NSString *description; NSString *description;
description = [NSString stringWithFormat: @"The value “%@” is invalid.", aPattern]; description = [NSString
stringWithFormat: @"The value “%@” is invalid.", aPattern];
userInfo = [NSDictionary dictionaryWithObjectsAndKeys: userInfo = [NSDictionary dictionaryWithObjectsAndKeys:
aPattern, @"NSInvalidValue", aPattern, @"NSInvalidValue",
@ -245,11 +256,46 @@ NSRegularExpressionOptionsToURegexpFlags(NSRegularExpressionOptions opts)
} }
#endif #endif
// Raise an NSInvalidArgumentException to match macOS behaviour.
if (!aPattern)
{
NSException *exp;
exp = [NSException exceptionWithName: NSInvalidArgumentException
reason: @"nil argument"
userInfo: nil];
RELEASE(self);
[exp raise];
}
[aPattern getCharacters: buffer range: NSMakeRange(0, length)]; [aPattern getCharacters: buffer range: NSMakeRange(0, length)];
regex = uregex_open(buffer, length, flags, &pe, &s); regex = uregex_open(buffer, length, flags, &pe, &s);
if (U_FAILURE(s)) if (U_FAILURE(s))
{ {
// FIXME: Do something sensible with the error parameter. /* Match macOS behaviour if the pattern is invalid.
* Example:
* Domain=NSCocoaErrorDomain
* Code=2048 "The value “<PATTERN>” is invalid."
* UserInfo={NSInvalidValue=<PATTERN>}
*/
if (e)
{
NSDictionary *userInfo;
NSString *description;
description = [NSString
stringWithFormat: @"The value “%@” is invalid.", aPattern];
userInfo = [NSDictionary dictionaryWithObjectsAndKeys:
aPattern, @"NSInvalidValue",
description, NSLocalizedDescriptionKey,
nil];
*e = [NSError errorWithDomain: NSCocoaErrorDomain
code: NSFormattingError
userInfo: userInfo];
}
DESTROY(self); DESTROY(self);
return self; return self;
} }
@ -979,13 +1025,13 @@ prepareResult(NSRegularExpression *regex,
NSInteger results = [self numberOfMatchesInString: string NSInteger results = [self numberOfMatchesInString: string
options: opts options: opts
range: range]; range: range];
if (results > 0)
{
UErrorCode s = 0; UErrorCode s = 0;
uint32_t length = [string length]; uint32_t length = [string length];
uint32_t replLength = [template length]; uint32_t replLength = [template length];
unichar replacement[replLength]; unichar replacement[replLength];
int32_t outLength; int32_t outLength;
unichar *output;
NSString *out;
URegularExpression *r; URegularExpression *r;
TEMP_BUFFER(buffer, length); TEMP_BUFFER(buffer, length);
@ -993,17 +1039,37 @@ prepareResult(NSRegularExpression *regex,
[template getCharacters: replacement range: NSMakeRange(0, replLength)]; [template getCharacters: replacement range: NSMakeRange(0, replLength)];
outLength = uregex_replaceAll(r, replacement, replLength, NULL, 0, &s); outLength = uregex_replaceAll(r, replacement, replLength, NULL, 0, &s);
if (0 == s || U_BUFFER_OVERFLOW_ERROR == s)
{
unichar *output;
s = 0; s = 0; // May have been set to a buffer overflow error
output = NSZoneMalloc(0, outLength * sizeof(unichar));
uregex_replaceAll(r, replacement, replLength, output, outLength, &s); output = NSZoneMalloc(0, (outLength + 1) * sizeof(unichar));
out = uregex_replaceAll(r, replacement, replLength,
[[NSString alloc] initWithCharactersNoCopy: output output, outLength + 1, &s);
if (0 == s)
{
NSString *out;
out = [[NSString alloc] initWithCharactersNoCopy: output
length: outLength length: outLength
freeWhenDone: YES]; freeWhenDone: YES];
[string setString: out]; [string setString: out];
RELEASE(out); RELEASE(out);
}
else
{
NSZoneFree(0, output);
results = 0;
}
}
else
{
results = 0;
}
uregex_close(r);
}
return results; return results;
} }
@ -1018,20 +1084,36 @@ prepareResult(NSRegularExpression *regex,
uint32_t replLength = [template length]; uint32_t replLength = [template length];
unichar replacement[replLength]; unichar replacement[replLength];
int32_t outLength; int32_t outLength;
unichar *output; NSString *result = nil;
TEMP_BUFFER(buffer, length); TEMP_BUFFER(buffer, length);
r = setupRegex(regex, string, buffer, length, opts, range, 0); r = setupRegex(regex, string, buffer, length, opts, range, 0);
[template getCharacters: replacement range: NSMakeRange(0, replLength)]; [template getCharacters: replacement range: NSMakeRange(0, replLength)];
outLength = uregex_replaceAll(r, replacement, replLength, NULL, 0, &s); outLength = uregex_replaceAll(r, replacement, replLength, NULL, 0, &s);
if (0 == s || U_BUFFER_OVERFLOW_ERROR == s)
{
unichar *output;
s = 0; s = 0; // may have been set to a buffer overflow error
output = NSZoneMalloc(0, outLength * sizeof(unichar));
uregex_replaceAll(r, replacement, replLength, output, outLength, &s); output = NSZoneMalloc(0, (outLength + 1) * sizeof(unichar));
return AUTORELEASE([[NSString alloc] initWithCharactersNoCopy: output uregex_replaceAll(r, replacement, replLength, output, outLength + 1, &s);
if (0 == s)
{
result = AUTORELEASE([[NSString alloc]
initWithCharactersNoCopy: output
length: outLength length: outLength
freeWhenDone: YES]); freeWhenDone: YES]);
}
else
{
NSZoneFree(0, output);
}
}
uregex_close(r);
return result;
} }
- (NSString*) replacementStringForResult: (NSTextCheckingResult*)result - (NSString*) replacementStringForResult: (NSTextCheckingResult*)result
@ -1045,7 +1127,7 @@ prepareResult(NSRegularExpression *regex,
uint32_t replLength = [template length]; uint32_t replLength = [template length];
unichar replacement[replLength]; unichar replacement[replLength];
int32_t outLength; int32_t outLength;
unichar *output; NSString *str = nil;
TEMP_BUFFER(buffer, range.length); TEMP_BUFFER(buffer, range.length);
r = setupRegex(regex, r = setupRegex(regex,
@ -1058,12 +1140,28 @@ prepareResult(NSRegularExpression *regex,
[template getCharacters: replacement range: NSMakeRange(0, replLength)]; [template getCharacters: replacement range: NSMakeRange(0, replLength)];
outLength = uregex_replaceFirst(r, replacement, replLength, NULL, 0, &s); outLength = uregex_replaceFirst(r, replacement, replLength, NULL, 0, &s);
if (0 == s || U_BUFFER_OVERFLOW_ERROR == s)
{
unichar *output;
s = 0; s = 0;
output = NSZoneMalloc(0, outLength * sizeof(unichar)); output = NSZoneMalloc(0, (outLength + 1) * sizeof(unichar));
uregex_replaceFirst(r, replacement, replLength, output, outLength, &s); uregex_replaceFirst(r, replacement, replLength,
return AUTORELEASE([[NSString alloc] initWithCharactersNoCopy: output output, outLength + 1, &s);
if (0 == s)
{
str = AUTORELEASE([[NSString alloc]
initWithCharactersNoCopy: output
length: outLength length: outLength
freeWhenDone: YES]); freeWhenDone: YES]);
}
else
{
NSZoneFree(0, output);
}
}
uregex_close(r);
return str;
} }
#endif #endif

View file

@ -1247,7 +1247,8 @@ static Class runLoopClass;
* first thing to do is send out port information (after setting * first thing to do is send out port information (after setting
* up a TLS session if necessary). * up a TLS session if necessary).
*/ */
ASSIGN(cData, newDataWithEncodedPort(p)); RELEASE(cData);
cData = newDataWithEncodedPort(p);
cLength = 0; cLength = 0;
#if defined(HAVE_GNUTLS) #if defined(HAVE_GNUTLS)

View file

@ -291,7 +291,6 @@ findKey(id refs, NSString *key, NSMutableArray *path, NSMutableArray *found)
- (void) makeRefs: (GSXMLNode*)node - (void) makeRefs: (GSXMLNode*)node
{ {
GSXMLNode *children = [node firstChild]; GSXMLNode *children = [node firstChild];
GSXMLNode *next = [node next];
BOOL newUnit = NO; BOOL newUnit = NO;
if ([node type] == XML_ELEMENT_NODE) if ([node type] == XML_ELEMENT_NODE)
@ -541,9 +540,10 @@ findKey(id refs, NSString *key, NSMutableArray *path, NSMutableArray *found)
} }
} }
if (children != nil) while (children)
{ {
[self makeRefs: children]; [self makeRefs: children];
children = [children next];
} }
if (newUnit == YES) if (newUnit == YES)
{ {
@ -551,10 +551,6 @@ findKey(id refs, NSString *key, NSMutableArray *path, NSMutableArray *found)
category = nil; category = nil;
classname = nil; classname = nil;
} }
if (next != nil)
{
[self makeRefs: next];
}
} }
/** /**

View file

@ -320,6 +320,7 @@ equalTypes(NSArray *t1, NSArray *t2)
- (void) dealloc - (void) dealloc
{ {
[self reset];
DESTROY(wordMap); DESTROY(wordMap);
DESTROY(ifStack); DESTROY(ifStack);
DESTROY(declared); DESTROY(declared);
@ -1485,8 +1486,8 @@ recheck:
- (NSMutableArray*) parseDeclarations - (NSMutableArray*) parseDeclarations
{ {
IF_NO_ARC(NSAutoreleasePool *arp = [NSAutoreleasePool new];)
NSMutableArray *declarations = [NSMutableArray array]; NSMutableArray *declarations = [NSMutableArray array];
CREATE_AUTORELEASE_POOL(arp);
static NSSet *qualifiers = nil; static NSSet *qualifiers = nil;
static NSSet *keep = nil; static NSSet *keep = nil;
NSString *baseName = nil; NSString *baseName = nil;
@ -1515,7 +1516,7 @@ recheck:
@"unsigned", @"unsigned",
@"volatile", @"volatile",
nil]; nil];
IF_NO_ARC([qualifiers retain];) IF_NO_ARC(qualifiers = [qualifiers retain];)
keep = [NSSet setWithObjects: keep = [NSSet setWithObjects:
@"const", @"const",
@"long", @"long",
@ -1524,7 +1525,7 @@ recheck:
@"unsigned", @"unsigned",
@"volatile", @"volatile",
nil]; nil];
IF_NO_ARC([keep retain];) IF_NO_ARC(keep = [keep retain];)
} }
{ {
@ -1572,7 +1573,7 @@ recheck:
pos++; pos++;
[self skipSpaces]; [self skipSpaces];
} }
IF_NO_ARC(DESTROY(arp);) IF_NO_ARC([arp release];)
return nil; return nil;
} }
@ -1643,7 +1644,7 @@ recheck:
if (NO == isEnum) if (NO == isEnum)
{ {
[self log: @"messed up NS_ENUM/NS_OPTIONS declaration"]; [self log: @"messed up NS_ENUM/NS_OPTIONS declaration"];
[arp drain]; IF_NO_ARC([arp release];)
return nil; return nil;
} }
} }
@ -1680,7 +1681,7 @@ recheck:
/* We want to be able to parse new comments while retaining the /* We want to be able to parse new comments while retaining the
originally parsed comment for the enum/union/struct. */ originally parsed comment for the enum/union/struct. */
introComment = [comment copy]; introComment = AUTORELEASE([comment copy]);
DESTROY(comment); DESTROY(comment);
pos++; /* Skip '{' */ pos++; /* Skip '{' */
@ -2007,8 +2008,8 @@ another:
{ {
if (buffer[pos] == ')' || buffer[pos] == ',') if (buffer[pos] == ')' || buffer[pos] == ',')
{ {
[arp drain]; IF_NO_ARC(declarations = [declarations retain]; [arp release];)
return declarations; return AUTORELEASE(declarations);
} }
else else
{ {
@ -2130,7 +2131,6 @@ another:
} }
DESTROY(comment); DESTROY(comment);
[arp drain];
if (inArgList == NO) if (inArgList == NO)
{ {
/* /*
@ -2148,11 +2148,13 @@ another:
{ {
[self log: @"parse declaration with no name - %@", d]; [self log: @"parse declaration with no name - %@", d];
} }
IF_NO_ARC([arp release];)
return nil; return nil;
} }
} }
[self setStandards: declarations]; [self setStandards: declarations];
return declarations; IF_NO_ARC(declarations = [declarations retain]; [arp release];)
return AUTORELEASE(declarations);
} }
else else
{ {
@ -2160,7 +2162,7 @@ another:
} }
fail: fail:
DESTROY(comment); DESTROY(comment);
[arp drain]; IF_NO_ARC([arp release];)
return nil; return nil;
} }
@ -2485,7 +2487,7 @@ fail:
*/ */
[self skipUnit]; [self skipUnit];
DESTROY(comment); DESTROY(comment);
[arp drain]; IF_NO_ARC([arp release];)
return [NSMutableDictionary dictionary]; return [NSMutableDictionary dictionary];
} }
else else
@ -2524,13 +2526,13 @@ fail:
DESTROY(unitName); DESTROY(unitName);
DESTROY(comment); DESTROY(comment);
[arp drain]; IF_NO_ARC([arp release];)
return dict; return dict;
fail: fail:
DESTROY(unitName); DESTROY(unitName);
DESTROY(comment); DESTROY(comment);
[arp drain]; IF_NO_ARC([arp release];)
return nil; return nil;
} }
@ -2690,13 +2692,13 @@ fail:
DESTROY(unitName); DESTROY(unitName);
DESTROY(comment); DESTROY(comment);
[arp drain]; IF_NO_ARC([arp release];)
return dict; return dict;
fail: fail:
DESTROY(unitName); DESTROY(unitName);
DESTROY(comment); DESTROY(comment);
[arp drain]; IF_NO_ARC([arp release];)
return nil; return nil;
} }
@ -3050,7 +3052,7 @@ fail:
- (NSMutableDictionary*) parseMethodIsDeclaration: (BOOL)flag - (NSMutableDictionary*) parseMethodIsDeclaration: (BOOL)flag
{ {
CREATE_AUTORELEASE_POOL(arp); IF_NO_ARC(CREATE_AUTORELEASE_POOL(arp);)
NSMutableDictionary *method; NSMutableDictionary *method;
NSMutableString *mname; NSMutableString *mname;
NSString *token; NSString *token;
@ -3338,14 +3340,14 @@ fail:
} }
DESTROY(itemName); DESTROY(itemName);
[arp drain]; IF_NO_ARC([arp release];)
IF_NO_ARC([method autorelease];) IF_NO_ARC([method autorelease];)
return method; return method;
fail: fail:
DESTROY(itemName); DESTROY(itemName);
DESTROY(comment); DESTROY(comment);
[arp drain]; IF_NO_ARC([arp release];)
RELEASE(method); RELEASE(method);
return nil; return nil;
} }
@ -4288,7 +4290,7 @@ countAttributes(NSSet *keys, NSDictionary *a)
NSDictionary *methods = nil; NSDictionary *methods = nil;
NSMutableDictionary *dict; NSMutableDictionary *dict;
NSMutableDictionary *d; NSMutableDictionary *d;
CREATE_AUTORELEASE_POOL(arp); IF_NO_ARC(CREATE_AUTORELEASE_POOL(arp);)
dict = [[NSMutableDictionary alloc] initWithCapacity: 8]; dict = [[NSMutableDictionary alloc] initWithCapacity: 8];
@ -4379,14 +4381,14 @@ countAttributes(NSSet *keys, NSDictionary *a)
DESTROY(unitName); DESTROY(unitName);
DESTROY(comment); DESTROY(comment);
[arp drain]; IF_NO_ARC([arp release];)
IF_NO_ARC([dict autorelease];) IF_NO_ARC([dict autorelease];)
return dict; return dict;
fail: fail:
DESTROY(unitName); DESTROY(unitName);
DESTROY(comment); DESTROY(comment);
[arp drain]; IF_NO_ARC([arp release];)
RELEASE(dict); RELEASE(dict);
return nil; return nil;
} }
@ -4816,7 +4818,7 @@ fail:
unichar *inptr; unichar *inptr;
unichar *outptr; unichar *outptr;
NSMutableArray *a; NSMutableArray *a;
CREATE_AUTORELEASE_POOL(arp); IF_NO_ARC(CREATE_AUTORELEASE_POOL(arp);)
contents = [NSString stringWithContentsOfFile: fileName]; contents = [NSString stringWithContentsOfFile: fileName];
length = [contents length]; length = [contents length];
@ -4910,7 +4912,7 @@ fail:
buffer = [data mutableBytes]; buffer = [data mutableBytes];
pos = 0; pos = 0;
ASSIGN(lines, [NSArray arrayWithArray: a]); ASSIGN(lines, [NSArray arrayWithArray: a]);
[arp drain]; IF_NO_ARC([arp release];)
IF_NO_ARC([data autorelease];) IF_NO_ARC([data autorelease];)
} }