Applied fixes for map table changes.

Also fixes for GSMime set methods


git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@13727 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Richard Frith-Macdonald 2002-05-28 11:30:15 +00:00
parent ecbcc202a1
commit 106faffbd9
10 changed files with 264 additions and 132 deletions

View file

@ -1,5 +1,7 @@
2002-05-28 Richard Frith-Macdonald <rfm@gnu.org>
* Headers/gnustep/base/GSMime.h: Make set... methods return void.
* Source//GSMime.m: Make set... methods return void.
* Headers/gnustep/base/GSIMap.h:
* Headers/gnustep/base/NSHashTable.h:
* Headers/gnustep/base/NSMapTable.h:
@ -19,6 +21,9 @@
Fixed minor problem in patch, and added code to call functions to
clean up after hash and map enumerations. Modified cleanup function
to clear enumerator ... for memory release on GC system.
Rewrote enumeration code so that it maintains the characteristic
that objects can safely be removed from maps after being enumerated
(this feature is used in several places).
*WARNING* This introduces a binary incompatibility in that the size
of the map table and hash table enumeration types has grown.
If you have binaries which use the NSEnumerateHashTable() or the

View file

@ -224,17 +224,18 @@ struct _GSIMapTable {
#endif
};
#ifdef GSI_MAP_ENUMERATOR
typedef GSI_MAP_ENUMERATOR GSIMapEnumerator_t;
#else
struct _GSIMapEnumerator {
typedef struct _GSIMapEnumerator {
GSIMapTable map; /* the map being enumerated. */
GSIMapNode node; /* The next node to use. */
size_t bucket; /* The next bucket to use. */
};
} *_GSIE;
#ifdef GSI_MAP_ENUMERATOR
typedef GSI_MAP_ENUMERATOR GSIMapEnumerator_t;
#else
typedef struct _GSIMapEnumerator GSIMapEnumerator_t;
#endif
typedef GSIMapEnumerator_t *GSIMapEnumerator;
typedef GSIMapEnumerator_t *GSIMapEnumerator;
static INLINE GSIMapBucket
GSIMapPickBucket(unsigned hash, GSIMapBucket buckets, size_t bucketCount)
@ -309,10 +310,8 @@ GSIMapRemoveNodeFromMap(GSIMapTable map, GSIMapBucket bkt, GSIMapNode node)
static INLINE void
GSIMapRemangleBuckets(GSIMapTable map,
GSIMapBucket old_buckets,
size_t old_bucketCount,
GSIMapBucket new_buckets,
size_t new_bucketCount)
GSIMapBucket old_buckets, size_t old_bucketCount,
GSIMapBucket new_buckets, size_t new_bucketCount)
{
while (old_bucketCount-- > 0)
{
@ -344,7 +343,9 @@ GSIMapMoreNodes(GSIMapTable map, unsigned required)
* the default zone
*/
if (map->zone == GSAtomicMallocZone())
newArray = (GSIMapNode*)NSZoneMalloc(NSDefaultMallocZone(), arraySize);
{
newArray = (GSIMapNode*)NSZoneMalloc(NSDefaultMallocZone(), arraySize);
}
else
#endif
newArray = (GSIMapNode*)NSZoneMalloc(map->zone, arraySize);
@ -470,7 +471,9 @@ GSIMapNodeForKey(GSIMapTable map, GSIMapKey key)
GSIMapNode node;
if (map->nodeCount == 0)
return 0;
{
return 0;
}
bucket = GSIMapBucketForKey(map, key);
node = GSIMapNodeForKeyInBucket(map, bucket, key);
return node;
@ -489,7 +492,9 @@ GSIMapNodeForSimpleKey(GSIMapTable map, GSIMapKey key)
GSIMapNode node;
if (map->nodeCount == 0)
return 0;
{
return 0;
}
bucket = map->buckets + key.uint % map->bucketCount;
node = bucket->firstNode;
while ((node != 0) && node->key.uint != key.uint)
@ -513,6 +518,7 @@ GSIMapResize(GSIMapTable map, size_t new_capacity)
while (size < new_capacity)
{
size_t tmp = old;
old = size;
size += tmp;
}
@ -522,7 +528,9 @@ GSIMapResize(GSIMapTable map, size_t new_capacity)
* bucket.
*/
if (size == 8)
size++;
{
size++;
}
/*
* Make a new set of buckets for this map
@ -559,21 +567,24 @@ GSIMapRightSizeMap(GSIMapTable map, size_t capacity)
/** Enumerating **/
/* WARNING: You should not alter a map while an enumeration is
* in progress. The results of doing so are reasonably unpremapable.
* With that in mind, read the following warnings carefully. But
* remember, DON'T MESS WITH A MAP WHILE YOU'RE ENUMERATING IT. */
/* IMPORTANT WARNING: Enumerators have a wonderous property.
* Once a node has been returned by `GSIMapEnumeratorNextNode()', it may be
* removed from the map without effecting the rest of the current
* enumeration. */
/* EXTREMELY IMPORTANT WARNING: The purpose of this warning is point
* out that, at this time, various (i.e., many) functions depend on
* out that, various (i.e., many) functions currently depend on
* the behaviour outlined above. So be prepared for some serious
* breakage when you go fudging around with these things. */
/**
* Create an return an enumerator for the specified map.<br />
* You must call GSIMapEndEnumerator() when you have finished
* with the enumerator.<br />
* <strong>WARNING</strong> You should not alter a map while an enumeration
* is in progress. The results of doing so are reasonably unpredictable.
* <br />Remember, DON'T MESS WITH A MAP WHILE YOU'RE ENUMERATING IT.
*/
static INLINE GSIMapEnumerator_t
GSIMapEnumeratorForMap(GSIMapTable map)
{
@ -582,26 +593,77 @@ GSIMapEnumeratorForMap(GSIMapTable map)
enumerator.map = map;
enumerator.node = 0;
enumerator.bucket = 0;
/*
* Locate next bucket and node to be returned.
*/
while (enumerator.bucket < map->bucketCount)
{
enumerator.node = map->buckets[enumerator.bucket].firstNode;
if (enumerator.node != 0)
{
break; // Got first node, and recorded its bucket.
}
enumerator.bucket++;
}
return enumerator;
}
/**
* Tidies up after map enumeration ... effectively destroys the enumerator.
*/
static INLINE void
GSIMapEndEnumerator(GSIMapEnumerator enumerator)
{
((_GSIE)enumerator)->map = 0;
((_GSIE)enumerator)->node = 0;
((_GSIE)enumerator)->bucket = 0;
}
/**
* Returns the bucket from which the next node in the enumeration will
* come. Once the next node has been enumerated, you can use the
* bucket and node to remove the node from the map using the
* GSIMapRemoveNodeFromMap() function.
*/
static INLINE GSIMapBucket
GSIMapEnumeratorBucket(GSIMapEnumerator enumerator)
{
if (((_GSIE)enumerator)->node != 0)
{
GSIMapTable map = ((_GSIE)enumerator)->map;
return &((map->buckets)[((_GSIE)enumerator)->bucket]);
}
return 0;
}
/**
* Returns the next node in the map, or a nul pointer if at the end.
*/
static INLINE GSIMapNode
GSIMapEnumeratorNextNode(GSIMapEnumerator enumerator)
{
GSIMapNode node;
int bucketCount = ((GSIMapTable)enumerator->map)->bucketCount;
node = enumerator->node;
GSIMapNode node = ((_GSIE)enumerator)->node;
while(!node && enumerator->bucket < bucketCount)
{
node = (((GSIMapTable)enumerator->map)->buckets[enumerator->bucket]).firstNode;
enumerator->bucket++;
}
if (node != 0)
enumerator->node = node->nextInBucket;
{
GSIMapNode next = node->nextInBucket;
/* Send back NODE. */
if (next == 0)
{
GSIMapTable map = ((_GSIE)enumerator)->map;
size_t bucketCount = map->bucketCount;
size_t bucket = ((_GSIE)enumerator)->bucket;
while (next == 0 && ++bucket < bucketCount)
{
next = (map->buckets[bucket]).firstNode;
}
((_GSIE)enumerator)->bucket = bucket;
}
((_GSIE)enumerator)->node = next;
}
return node;
}
@ -699,10 +761,14 @@ GSIMapCleanMap(GSIMapTable map)
for (i = 0; i < map->bucketCount; i++)
{
node = bucket->firstNode;
if(prevNode)
if (prevNode != 0)
{
prevNode->nextInBucket = node;
}
else
{
startNode = node;
}
while(node != 0)
{
GSI_MAP_RELEASE_KEY(map, node->key);

View file

@ -86,8 +86,8 @@
id content;
}
- (BOOL) addContent: (id)newContent;
- (BOOL) addHeader: (GSMimeHeader*)info;
- (void) addContent: (id)newContent;
- (void) addHeader: (GSMimeHeader*)info;
- (NSArray*) allHeaders;
- (id) content;
- (id) contentByID: (NSString*)key;
@ -104,12 +104,12 @@
- (GSMimeHeader*) headerNamed: (NSString*)name;
- (NSArray*) headersNamed: (NSString*)name;
- (GSMimeHeader*) makeContentID;
- (BOOL) setContent: (id)newContent;
- (BOOL) setContent: (id)newContent
- (void) setContent: (id)newContent;
- (void) setContent: (id)newContent
type: (NSString*)type
subType: (NSString*)subType
name: (NSString*)name;
- (BOOL) setHeader: (GSMimeHeader*)info;
- (void) setHeader: (GSMimeHeader*)info;
@end

View file

@ -57,7 +57,8 @@ static unsigned _count = 0;
static NSString *makeUniqueString();
static NSCharacterSet *specials = nil;
static NSCharacterSet *rfc822specials = nil;
static NSCharacterSet *rfc2045specials = nil;
/*
* Name - decodebase64()
@ -354,6 +355,7 @@ parseCharacterSet(NSString *token)
- (BOOL) _decodeBody: (NSData*)data;
- (NSString*) _decodeHeader;
- (BOOL) _unfoldHeader;
- (BOOL) _scanHeaderParameters: (NSScanner*)scanner into: (GSMimeHeader*)info;
@end
/**
@ -530,7 +532,8 @@ parseCharacterSet(NSString *token)
if (dData == nil || [con isKindOfClass: [GSMimeCodingContext class]] == NO)
{
[NSException raise: NSInvalidArgumentException
format: @"Bad destination data for decode"];
format: @"[%@ -%@:] bad destination data for decode",
NSStringFromClass([self class]), NSStringFromSelector(_cmd)];
}
GS_RANGE_CHECK(aRange, len);
@ -1332,42 +1335,11 @@ parseCharacterSet(NSString *token)
[document deleteHeaderNamed: name]; // Should be unique
}
return [document addHeader: info];
}
- (BOOL) scanHeaderParameters: (NSScanner*)scanner into: (GSMimeHeader*)info
{
[self scanPastSpace: scanner];
while ([scanner scanString: @";" intoString: 0] == YES)
{
NSString *paramName;
paramName = [self scanToken: scanner];
if ([paramName length] == 0)
{
NSLog(@"Invalid Mime %@ field (parameter name)", [info name]);
return NO;
}
[self scanPastSpace: scanner];
if ([scanner scanString: @"=" intoString: 0] == YES)
{
NSString *paramValue;
[self scanPastSpace: scanner];
paramValue = [self scanToken: scanner];
[self scanPastSpace: scanner];
if (paramValue == nil)
{
paramValue = @"";
}
[info setParameter: paramValue forKey: paramName];
}
else
{
NSLog(@"Ignoring Mime %@ field parameter (%@)",
[info name], paramName);
}
}
NS_DURING
[document addHeader: info];
NS_HANDLER
return NO;
NS_ENDHANDLER
return YES;
}
@ -1556,7 +1528,7 @@ parseCharacterSet(NSString *token)
value = type;
}
[self scanHeaderParameters: scanner into: info];
[self _scanHeaderParameters: scanner into: info];
}
else if ([name isEqualToString: @"content-disposition"] == YES)
{
@ -1579,7 +1551,7 @@ parseCharacterSet(NSString *token)
/*
* Expect anything else to be 'name=value' parameters.
*/
[self scanHeaderParameters: scanner into: info];
[self _scanHeaderParameters: scanner into: info];
}
else
{
@ -1625,11 +1597,20 @@ parseCharacterSet(NSString *token)
*/
- (NSString*) scanSpecial: (NSScanner*)scanner
{
NSCharacterSet *specials;
unsigned location;
unichar c;
[self scanPastSpace: scanner];
if (isHttp == YES)
{
specials = rfc822specials;
}
else
{
specials = rfc2045specials;
}
/*
* Now return token delimiter (may be whitespace)
*/
@ -1732,9 +1713,19 @@ parseCharacterSet(NSString *token)
}
else // Token
{
NSCharacterSet *specials;
NSCharacterSet *skip;
NSString *value;
if (isHttp == YES)
{
specials = rfc822specials;
}
else
{
specials = rfc2045specials;
}
/*
* Move past white space.
*/
@ -2289,6 +2280,43 @@ parseCharacterSet(NSString *token)
input, dataEnd, lineStart, dataEnd - input, dataEnd - input, &bytes[input]);
return unwrappingComplete;
}
- (BOOL) _scanHeaderParameters: (NSScanner*)scanner into: (GSMimeHeader*)info
{
[self scanPastSpace: scanner];
while ([scanner scanString: @";" intoString: 0] == YES)
{
NSString *paramName;
paramName = [self scanToken: scanner];
if ([paramName length] == 0)
{
NSLog(@"Invalid Mime %@ field (parameter name)", [info name]);
return NO;
}
[self scanPastSpace: scanner];
if ([scanner scanString: @"=" intoString: 0] == YES)
{
NSString *paramValue;
[self scanPastSpace: scanner];
paramValue = [self scanToken: scanner];
[self scanPastSpace: scanner];
if (paramValue == nil)
{
paramValue = @"";
}
[info setParameter: paramValue forKey: paramName];
}
else
{
NSLog(@"Ignoring Mime %@ field parameter (%@)",
[info name], paramName);
}
}
return YES;
}
@end
@ -2630,24 +2658,27 @@ static NSCharacterSet *tokenSet = nil;
[m formUnionWithCharacterSet:
[NSCharacterSet characterSetWithCharactersInString:
@"()<>@,;:/[]?=\"\\"]];
@".()<>@,;:[]\"\\"]];
[m formUnionWithCharacterSet:
[NSCharacterSet whitespaceAndNewlineCharacterSet]];
[m formUnionWithCharacterSet:
[NSCharacterSet controlCharacterSet]];
[m formUnionWithCharacterSet:
[NSCharacterSet illegalCharacterSet]];
specials = [m copy];
rfc822specials = [m copy];
[m formUnionWithCharacterSet:
[NSCharacterSet characterSetWithCharactersInString:
@"/?="]];
[m removeCharactersInString: @"."];
rfc2045specials = [m copy];
}
}
/**
* Adds a part to a multipart document
*/
- (BOOL) addContent: (GSMimeDocument*)newContent
- (void) addContent: (GSMimeDocument*)newContent
{
BOOL result = YES;
if (content == nil)
{
content = [NSMutableArray new];
@ -2658,9 +2689,10 @@ static NSCharacterSet *tokenSet = nil;
}
else
{
result = NO;
[NSException raise: NSInvalidArgumentException
format: @"[%@ -%@:] passed bad content",
NSStringFromClass([self class]), NSStringFromSelector(_cmd)];
}
return result;
}
/**
@ -2670,17 +2702,17 @@ static NSCharacterSet *tokenSet = nil;
* at least the fields that are standard for all headers.
* </p>
*/
- (BOOL) addHeader: (GSMimeHeader*)info
- (void) addHeader: (GSMimeHeader*)info
{
NSString *name = [info name];
if (name == nil || [name isEqual: @"unknown"] == YES)
{
NSLog(@"setHeader: supplied with header without valid name");
return NO;
[NSException raise: NSInvalidArgumentException
format: @"[%@ -%@:] header with invalid name",
NSStringFromClass([self class]), NSStringFromSelector(_cmd)];
}
[headers addObject: info];
return YES;
}
/**
@ -3003,10 +3035,8 @@ static NSCharacterSet *tokenSet = nil;
/**
* Sets a new value for the content of the document.
*/
- (BOOL) setContent: (id)newContent
- (void) setContent: (id)newContent
{
BOOL result = YES;
if ([newContent isKindOfClass: [NSString class]] == YES)
{
ASSIGNCOPY(content, newContent);
@ -3023,47 +3053,43 @@ static NSCharacterSet *tokenSet = nil;
}
else
{
result = NO;
[NSException raise: NSInvalidArgumentException
format: @"[%@ -%@:] passed bad content",
NSStringFromClass([self class]), NSStringFromSelector(_cmd)];
}
return result;
}
/**
* Convenience method to set the content of the document along with
* creating a content-type header for it.
*/
- (BOOL) setContent: (id)newContent
- (void) setContent: (id)newContent
type: (NSString*)type
subType: (NSString*)subType
name: (NSString*)name
{
GSMimeHeader *hdr;
NSString *val;
if ([type isEqualToString: @"multi-part"] == NO
&& [content isKindOfClass: [NSArray class]] == YES)
{
NSLog(@"Can't set non-'multi-part' content type for array of content");
return NO;
[NSException raise: NSInvalidArgumentException
format: @"[%@ -%@:] content doesn't match content-type",
NSStringFromClass([self class]), NSStringFromSelector(_cmd)];
}
if ([self setContent: newContent] == NO)
{
return NO;
}
else
{
GSMimeHeader *hdr;
NSString *val;
[self setContent: newContent];
val = [NSString stringWithFormat: @"%@/%@", type, subType];
hdr = [GSMimeHeader alloc];
hdr = [hdr initWithName: @"content-type" value: val parameters: nil];
if (name != nil)
{
[hdr setParameter: name forKey: @"name"];
}
[self setHeader: hdr];
RELEASE(hdr);
val = [NSString stringWithFormat: @"%@/%@", type, subType];
hdr = [GSMimeHeader alloc];
hdr = [hdr initWithName: @"content-type" value: val parameters: nil];
if (name != nil)
{
[hdr setParameter: name forKey: @"name"];
}
return YES;
[self setHeader: hdr];
RELEASE(hdr);
}
/**
@ -3071,7 +3097,7 @@ static NSCharacterSet *tokenSet = nil;
* Any other headers with the same name will be removed from
* the document.
*/
- (BOOL) setHeader: (GSMimeHeader*)info
- (void) setHeader: (GSMimeHeader*)info
{
NSString *name = [info name];
@ -3092,7 +3118,7 @@ static NSCharacterSet *tokenSet = nil;
}
}
}
return [self addHeader: info];
[self addHeader: info];
}
@end

View file

@ -57,6 +57,7 @@
- (void) dealloc
{
GSIMapEndEnumerator(&enumerator);
RELEASE(set);
[super dealloc];
}
@ -160,6 +161,7 @@
(*imp2)(aCoder, sel2, type, &node->value.uint);
node = GSIMapEnumeratorNextNode(&enumerator);
}
GSIMapEndEnumerator(&enumerator);
}
- (unsigned) hash
@ -249,27 +251,32 @@
NSDefaultMallocZone()] initWithSet: self]);
}
/**
* Removes all objcts which have not been added more than level times
* from the counted set.<br />
* Note to GNUstep maintainers ... this method depends on the characteristic
* of the GSIMap enumeration that, once enumerated, an object can be removed
* from the map. If GSIMap ever loses that characterstic, this will break.
*/
- (void) purge: (int)level
{
if (level > 0)
{
GSIMapEnumerator_t enumerator = GSIMapEnumeratorForMap(&map);
GSIMapBucket bucket = GSIMapEnumeratorBucket(&enumerator);
GSIMapNode node = GSIMapEnumeratorNextNode(&enumerator);
while (node != 0)
{
GSIMapNode next = GSIMapEnumeratorNextNode(&enumerator);
if (node->value.uint <= level)
{
GSIMapBucket bucket;
bucket = GSIMapBucketForKey(&map, node->key);
GSIMapRemoveNodeFromMap(&map, bucket, node);
GSIMapFreeNode(&map, node);
}
node = next;
bucket = GSIMapEnumeratorBucket(&enumerator);
node = GSIMapEnumeratorNextNode(&enumerator);
}
GSIMapEndEnumerator(&enumerator);
}
}

View file

@ -110,6 +110,7 @@ static SEL objSel;
(*imp)(aCoder, sel, node->value.obj);
node = GSIMapEnumeratorNextNode(&enumerator);
}
GSIMapEndEnumerator(&enumerator);
}
- (unsigned) hash
@ -350,6 +351,7 @@ static SEL objSel;
- (void) dealloc
{
GSIMapEndEnumerator(&enumerator);
RELEASE(dictionary);
[super dealloc];
}

View file

@ -86,6 +86,7 @@
- (void) dealloc
{
GSIMapEndEnumerator(&enumerator);
RELEASE(set);
[super dealloc];
}
@ -121,6 +122,7 @@ static Class mutableSetClass;
objs[i++] = node->key.obj;
node = GSIMapEnumeratorNextNode(&enumerator);
}
GSIMapEndEnumerator(&enumerator);
return AUTORELEASE([[arrayClass allocWithZone: NSDefaultMallocZone()]
initWithObjects: objs count: i]);
}
@ -167,6 +169,7 @@ static Class mutableSetClass;
(*imp)(aCoder, sel, node->key.obj);
node = GSIMapEnumeratorNextNode(&enumerator);
}
GSIMapEndEnumerator(&enumerator);
}
- (unsigned) hash
@ -247,10 +250,12 @@ static Class mutableSetClass;
{
if (GSIMapNodeForKey(&map, node->key) != 0)
{
GSIMapEndEnumerator(&enumerator);
return YES;
}
node = GSIMapEnumeratorNextNode(&enumerator);
}
GSIMapEndEnumerator(&enumerator);
}
else
{
@ -295,9 +300,11 @@ static Class mutableSetClass;
else
{
// 1.2 if false -> return NO;
GSIMapEndEnumerator(&enumerator);
return NO;
}
}
GSIMapEndEnumerator(&enumerator);
// 2. return YES; all members in this set are also in the otherSet.
return YES;
}
@ -334,10 +341,12 @@ static Class mutableSetClass;
{
if (GSIMapNodeForKey(&(((GSSet*)other)->map), node->key) == 0)
{
GSIMapEndEnumerator(&enumerator);
return NO;
}
node = GSIMapEnumeratorNextNode(&enumerator);
}
GSIMapEndEnumerator(&enumerator);
}
}
else
@ -358,10 +367,12 @@ static Class mutableSetClass;
{
if ([other member: node->key.obj] == nil)
{
GSIMapEndEnumerator(&enumerator);
return NO;
}
node = GSIMapEnumeratorNextNode(&enumerator);
}
GSIMapEndEnumerator(&enumerator);
}
}
return YES;
@ -378,6 +389,7 @@ static Class mutableSetClass;
[node->key.obj performSelector: aSelector];
node = GSIMapEnumeratorNextNode(&enumerator);
}
GSIMapEndEnumerator(&enumerator);
}
- (void) makeObjectsPerformSelector: (SEL)aSelector
@ -390,6 +402,7 @@ static Class mutableSetClass;
[node->key.obj performSelector: aSelector];
node = GSIMapEnumeratorNextNode(&enumerator);
}
GSIMapEndEnumerator(&enumerator);
}
- (void) makeObjectsPerformSelector: (SEL)aSelector withObject: argument
@ -402,6 +415,7 @@ static Class mutableSetClass;
[node->key.obj performSelector: aSelector withObject: argument];
node = GSIMapEnumeratorNextNode(&enumerator);
}
GSIMapEndEnumerator(&enumerator);
}
- (void) makeObjectsPerform: (SEL)aSelector withObject: argument
@ -414,6 +428,7 @@ static Class mutableSetClass;
[node->key.obj performSelector: aSelector withObject: argument];
node = GSIMapEnumeratorNextNode(&enumerator);
}
GSIMapEndEnumerator(&enumerator);
}
- (id) member: (id)anObject
@ -529,18 +544,21 @@ static Class mutableSetClass;
if (other != self)
{
GSIMapEnumerator_t enumerator = GSIMapEnumeratorForMap(&map);
GSIMapBucket bucket = GSIMapEnumeratorBucket(&enumerator);
GSIMapNode node = GSIMapEnumeratorNextNode(&enumerator);
while (node != 0)
{
GSIMapNode next = GSIMapEnumeratorNextNode(&enumerator);
if ([other containsObject: node->key.obj] == NO)
{
GSIMapRemoveKey(&map, node->key);
GSIMapRemoveNodeFromMap(&map, bucket, node);
GSIMapFreeNode(&map, node);
}
node = next;
bucket = GSIMapEnumeratorBucket(&enumerator);
node = GSIMapEnumeratorNextNode(&enumerator);
}
GSIMapEndEnumerator(&enumerator);
}
}

View file

@ -194,6 +194,7 @@ $(GNUSTEP_OBJ_DIR)/NSUnarchiver.o \
#
# Files that include GSIArray.h will need a rebuild if it is changed.
#
$(GNUSTEP_OBJ_DIR)/NSFileManager.o \
$(GNUSTEP_OBJ_DIR)/NSNotificationCenter.o \
$(GNUSTEP_OBJ_DIR)/NSPortCoder.o \
$(GNUSTEP_OBJ_DIR)/NSRunLoop.o \
@ -204,13 +205,17 @@ $(GNUSTEP_OBJ_DIR)/NSUnarchiver.o \
#
# Files that include GSIMap.h will need a rebuild if it is changed.
#
$(GNUSTEP_OBJ_DIR)/GSAttributedString.o \
$(GNUSTEP_OBJ_DIR)/GSCountedSet.o \
$(GNUSTEP_OBJ_DIR)/GSDictionary.o \
$(GNUSTEP_OBJ_DIR)/GSFFCallInvocation.o \
$(GNUSTEP_OBJ_DIR)/GSSet.o \
$(GNUSTEP_OBJ_DIR)/NSArchiver.o \
$(GNUSTEP_OBJ_DIR)/NSConnection.o \
$(GNUSTEP_OBJ_DIR)/NSGAttributedString.o \
$(GNUSTEP_OBJ_DIR)/NSGDictionary.o \
$(GNUSTEP_OBJ_DIR)/NSHashTable.o \
$(GNUSTEP_OBJ_DIR)/NSMapTable.o \
$(GNUSTEP_OBJ_DIR)/NSNotificationCenter.o \
$(GNUSTEP_OBJ_DIR)/NSObject.o \
$(GNUSTEP_OBJ_DIR)/NSPortCoder.o \
$(GNUSTEP_OBJ_DIR)/NSSerializer.o \
: $(HEADER_DIR)/GSIMap.h $(HEADER_DIR)/GSUnion.h

View file

@ -128,9 +128,11 @@ NSCompareHashTables(NSHashTable *table1, NSHashTable *table2)
{
if (GSIMapNodeForKey(t2, n->key) == 0)
{
GSIMapEndEnumerator((GSIMapEnumerator)&enumerator);
return NO;
}
}
GSIMapEndEnumerator((GSIMapEnumerator)&enumerator);
return YES;
}
}
@ -159,6 +161,7 @@ NSCopyHashTableWithZone(NSHashTable *table, NSZone *zone)
{
GSIMapAddKey(t, n->key);
}
GSIMapEndEnumerator((GSIMapEnumerator)&enumerator);
return (NSHashTable*)t;
}
@ -234,9 +237,7 @@ NSEndHashTableEnumeration(NSHashEnumerator *enumerator)
NSWarnFLog(@"Nul enumerator argument supplied");
return;
}
#if GS_WITH_GC
memset(enumerator, 0, sizeof(*enumerator));
#endif
GSIMapEndEnumerator((GSIMapEnumerator)enumerator);
}
/**

View file

@ -173,13 +173,16 @@ NSCompareMapTables(NSMapTable *table1, NSMapTable *table2)
{
NSMapEnumerator enumerator = GSIMapEnumeratorForMap((GSIMapTable)t1);
GSIMapNode n;
while ((n = GSIMapEnumeratorNextNode(&enumerator)) != 0)
{
if (GSIMapNodeForKey(t2, n->key) == 0)
{
GSIMapEndEnumerator((GSIMapEnumerator)&enumerator);
return NO;
}
}
GSIMapEndEnumerator((GSIMapEnumerator)&enumerator);
return YES;
}
}
@ -209,6 +212,7 @@ NSCopyMapTableWithZone(NSMapTable *table, NSZone *zone)
{
GSIMapAddPair(t, n->key, n->value);
}
GSIMapEndEnumerator((GSIMapEnumerator)&enumerator);
return (NSMapTable*)t;
}
@ -295,9 +299,7 @@ NSEndMapTableEnumeration(NSMapEnumerator *enumerator)
NSWarnFLog(@"Nul enumerator argument supplied");
return;
}
#if GS_WITH_GC
memset(enumerator, 0, sizeof(*enumerator));
#endif
GSIMapEndEnumerator((GSIMapEnumerator)enumerator);
}
/**