mirror of
https://github.com/gnustep/libs-base.git
synced 2025-04-22 16:33:29 +00:00
Updated docs, remnoved old next files
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@3681 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
2de680b4a7
commit
46bc0c6cea
14 changed files with 8 additions and 3583 deletions
|
@ -1,3 +1,11 @@
|
|||
1999-02-09 Adam Fedor <fedor@gnu.org>
|
||||
|
||||
* Source/HashTable.m: Moved to extensions.
|
||||
* Source/List.m, Source/NXStringTable*, Source/Storage.m,
|
||||
Source/objc/HashTable.h, Source/objc/List.h,
|
||||
Source/objc/NXStringTable.h, Source/objc/Storage.h:
|
||||
Likewise.
|
||||
|
||||
Tue Feb 9 14:08:00 1999 Richard Frith-Macdonald <richard@brainstorm.co.uk>
|
||||
|
||||
* Source/NSProcessInfo.m: Fixed login in #if construct so things
|
||||
|
|
|
@ -251,29 +251,6 @@ RNGBerkeley.h \
|
|||
RandomGenerating.h \
|
||||
Time.h
|
||||
|
||||
# NEXTSTEP source files
|
||||
|
||||
NEXTSTEP_MFILES = \
|
||||
HashTable.m \
|
||||
List.m \
|
||||
NXStringTable.m \
|
||||
Storage.m
|
||||
|
||||
NEXTSTEP_CFILES =
|
||||
|
||||
NEXTSTEP_DERIVED_CFILES = \
|
||||
NXStringTable_scan.c
|
||||
|
||||
NEXTSTEP_OTHER_SRCFILES = \
|
||||
NXStringTable_scan.l
|
||||
|
||||
NEXTSTEP_HEADERS = \
|
||||
objc/HashTable.h \
|
||||
objc/List.h \
|
||||
objc/NXStringTable.h \
|
||||
objc/Storage.h \
|
||||
objc/zone.h
|
||||
|
||||
# GNUStep source files
|
||||
|
||||
BASE_MFILES = \
|
||||
|
|
|
@ -1,362 +0,0 @@
|
|||
/* Implementation of Objective C NeXT-compatible HashTable object
|
||||
Copyright (C) 1993,1994 Free Software Foundation, Inc.
|
||||
|
||||
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
|
||||
Date: May 1993
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <base/preface.h>
|
||||
#include <objc/HashTable.h>
|
||||
|
||||
#define DEFAULT_HASH_CAPACITY 32
|
||||
|
||||
|
||||
/* Some useful hash and compare functions not provided by hash.h */
|
||||
|
||||
static inline unsigned int
|
||||
hash_object (cache_ptr cache, const void *key)
|
||||
{
|
||||
return (([((id)key) hash]) & cache->mask);
|
||||
}
|
||||
|
||||
static inline int
|
||||
compare_objects (const void *k1, const void *k2)
|
||||
{
|
||||
return (int)[(id)k1 isEqual:(id)k2];
|
||||
}
|
||||
|
||||
static inline unsigned int
|
||||
hash_int (cache_ptr cache, const void *key)
|
||||
{
|
||||
return ((unsigned int)key & cache->mask);
|
||||
}
|
||||
|
||||
static inline int
|
||||
compare_ints (const void *k1, const void *k2)
|
||||
{
|
||||
return !((int)k1 - (int)k2);
|
||||
}
|
||||
|
||||
static inline int
|
||||
compare_long_ints (const void *k1, const void *k2)
|
||||
{
|
||||
return !((long int)k1 - (long int)k2);
|
||||
}
|
||||
|
||||
@implementation HashTable
|
||||
|
||||
+ initialize
|
||||
{
|
||||
if (self == [HashTable class])
|
||||
[self setVersion:0]; /* beta release */
|
||||
return self;
|
||||
}
|
||||
|
||||
- initKeyDesc: (const char *)aKeyDesc
|
||||
valueDesc: (const char *)aValueDesc
|
||||
capacity: (unsigned) aCapacity
|
||||
{
|
||||
hash_func_type hf;
|
||||
compare_func_type cf;
|
||||
|
||||
if (!aKeyDesc)
|
||||
[self error:"in %s, NULL keyDesc\n", sel_get_name(_cmd)];
|
||||
if (!aValueDesc)
|
||||
[self error:"in %s, NULL valueDesc\n", sel_get_name(_cmd)];
|
||||
count = 0;
|
||||
keyDesc = aKeyDesc;
|
||||
valueDesc = aValueDesc;
|
||||
switch (*aKeyDesc)
|
||||
{
|
||||
case _C_ATOM:
|
||||
case _C_CHARPTR :
|
||||
hf = (hash_func_type)hash_string;
|
||||
cf = (compare_func_type)compare_strings;
|
||||
break;
|
||||
case _C_ID:
|
||||
case _C_CLASS:
|
||||
hf = (hash_func_type)hash_object;
|
||||
cf = (compare_func_type)compare_objects;
|
||||
break;
|
||||
case _C_PTR:
|
||||
hf = (hash_func_type)hash_ptr;
|
||||
cf = (compare_func_type)compare_ptrs;
|
||||
break;
|
||||
case _C_INT:
|
||||
case _C_SEL:
|
||||
case _C_UINT:
|
||||
hf = (hash_func_type)hash_int;
|
||||
cf = (compare_func_type)compare_ints;
|
||||
break;
|
||||
case _C_LNG:
|
||||
case _C_ULNG:
|
||||
hf = (hash_func_type)hash_int;
|
||||
cf = (compare_func_type)compare_long_ints;
|
||||
break;
|
||||
case _C_FLT:
|
||||
/* Fix this. Do something better with floats. */
|
||||
hf = (hash_func_type)hash_int;
|
||||
cf = (compare_func_type)compare_ints;
|
||||
break;
|
||||
default:
|
||||
hf = (hash_func_type)hash_int;
|
||||
cf = (compare_func_type)compare_ints;
|
||||
break;
|
||||
}
|
||||
_buckets = hash_new(aCapacity, hf, cf);
|
||||
_nbBuckets = _buckets->size;
|
||||
return self;
|
||||
}
|
||||
|
||||
- initKeyDesc:(const char *)aKeyDesc
|
||||
valueDesc:(const char *)aValueDesc
|
||||
{
|
||||
return [self initKeyDesc:aKeyDesc
|
||||
valueDesc:aValueDesc
|
||||
capacity:DEFAULT_HASH_CAPACITY];
|
||||
}
|
||||
|
||||
- initKeyDesc: (const char *)aKeyDesc
|
||||
{
|
||||
return [self initKeyDesc:aKeyDesc
|
||||
valueDesc:@encode(id)];
|
||||
}
|
||||
|
||||
- init
|
||||
{
|
||||
return [self initKeyDesc:@encode(id)];
|
||||
}
|
||||
|
||||
- free
|
||||
{
|
||||
hash_delete(_buckets);
|
||||
return [super free];
|
||||
}
|
||||
|
||||
- freeObjects
|
||||
{
|
||||
node_ptr node;
|
||||
void *val;
|
||||
|
||||
while ((node = hash_next(_buckets, 0)))
|
||||
{
|
||||
val = node->value;
|
||||
hash_remove(_buckets, node->key);
|
||||
if (*valueDesc == _C_ID)
|
||||
[(id)val free];
|
||||
}
|
||||
count = 0;
|
||||
_nbBuckets = _buckets->size;
|
||||
return self;
|
||||
}
|
||||
|
||||
- freeKeys:(void (*) (void *))keyFunc
|
||||
values:(void (*) (void *))valueFunc
|
||||
{
|
||||
/* What exactly is this supposed to do? */
|
||||
[self notImplemented:_cmd];
|
||||
return self;
|
||||
}
|
||||
|
||||
- empty
|
||||
{
|
||||
node_ptr node;
|
||||
|
||||
while ((node = hash_next(_buckets, 0)))
|
||||
hash_remove(_buckets, node->key);
|
||||
count = 0;
|
||||
_nbBuckets = _buckets->size;
|
||||
return self;
|
||||
}
|
||||
|
||||
- shallowCopy
|
||||
{
|
||||
HashTable *c;
|
||||
node_ptr node;
|
||||
|
||||
c = [super shallowCopy];
|
||||
c->_buckets = hash_new(_buckets->size,
|
||||
_buckets->hash_func,
|
||||
_buckets->compare_func);
|
||||
/* copy nodes to new copy */
|
||||
node = 0;
|
||||
while ((node = hash_next(_buckets, node)))
|
||||
[c insertKey:node->key value:node->value];
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
- deepen
|
||||
{
|
||||
node_ptr node = 0;
|
||||
|
||||
if (*valueDesc == _C_ID)
|
||||
{
|
||||
while ((node = hash_next(_buckets, node)))
|
||||
{
|
||||
node->value = [(id)(node->value) deepCopy];
|
||||
}
|
||||
}
|
||||
/* If the hashtable contains strings should we copy them too??
|
||||
But we definitely shouldn't copy "%" keys. */
|
||||
return self;
|
||||
}
|
||||
|
||||
- (unsigned) count
|
||||
{
|
||||
return count;
|
||||
}
|
||||
|
||||
- (BOOL) isKey:(const void *)aKey
|
||||
{
|
||||
return hash_is_key_in_hash(_buckets, aKey);
|
||||
}
|
||||
|
||||
- (void *) valueForKey:(const void *)aKey
|
||||
{
|
||||
return hash_value_for_key(_buckets, aKey);
|
||||
}
|
||||
|
||||
- (void *) insertKey:(const void *)aKey value:(void *)aValue
|
||||
{
|
||||
void *prevValue;
|
||||
|
||||
prevValue = hash_value_for_key(_buckets, aKey);
|
||||
if (prevValue)
|
||||
hash_remove(_buckets, aKey);
|
||||
hash_add(&_buckets, aKey, aValue);
|
||||
count = _buckets->used;
|
||||
_nbBuckets = _buckets->size;
|
||||
return prevValue;
|
||||
}
|
||||
|
||||
- (void *) removeKey:(const void *)aKey
|
||||
{
|
||||
if (hash_value_for_key(_buckets, aKey))
|
||||
{
|
||||
hash_remove(_buckets, aKey);
|
||||
count = _buckets->used;
|
||||
_nbBuckets = _buckets->size;
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (NXHashState) initState
|
||||
{
|
||||
return (NXHashState) 0;
|
||||
}
|
||||
|
||||
- (BOOL) nextState:(NXHashState *)aState
|
||||
key:(const void **)aKey
|
||||
value:(void **)aValue
|
||||
{
|
||||
*aState = hash_next(_buckets, *aState);
|
||||
if (*aState)
|
||||
{
|
||||
*aKey = (*aState)->key;
|
||||
*aValue = (*aState)->value;
|
||||
return YES;
|
||||
}
|
||||
else
|
||||
return NO;
|
||||
}
|
||||
|
||||
- write: (TypedStream*)aStream
|
||||
{
|
||||
NXHashState state = [self initState];
|
||||
const void *k;
|
||||
void *v;
|
||||
|
||||
if (!strcmp(keyDesc, "%"))
|
||||
[self error:"Archiving atom strings, @encode()=\"%\", not yet handled"];
|
||||
[super write: aStream];
|
||||
objc_write_types(aStream, "II**",
|
||||
[self count], _nbBuckets, keyDesc, valueDesc);
|
||||
while ([self nextState:&state key:&k value:&v])
|
||||
{
|
||||
objc_write_type(aStream, keyDesc, &k);
|
||||
objc_write_type(aStream, valueDesc, &v);
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- read: (TypedStream*)aStream
|
||||
{
|
||||
unsigned cnt, capacity;
|
||||
int i;
|
||||
const void *k;
|
||||
void *v;
|
||||
|
||||
[super read:aStream];
|
||||
objc_read_types(aStream, "II**",
|
||||
&cnt, &capacity, &keyDesc, &valueDesc);
|
||||
if (!strcmp(keyDesc, "%"))
|
||||
[self error:"Archiving atom strings, @encode()=\"%\", not yet handled"];
|
||||
[self initKeyDesc:keyDesc valueDesc:valueDesc capacity:capacity];
|
||||
for (i = 0; i < cnt; i++)
|
||||
{
|
||||
objc_read_type(aStream, keyDesc, &k);
|
||||
objc_read_type(aStream, valueDesc, &v);
|
||||
[self insertKey:k value:v];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
+ newKeyDesc: (const char *)aKeyDesc
|
||||
{
|
||||
return [[[self class] alloc] initKeyDesc:aKeyDesc];
|
||||
}
|
||||
|
||||
+ newKeyDesc:(const char *)aKeyDesc
|
||||
valueDesc:(const char *)aValueDesc
|
||||
{
|
||||
return [[self alloc]
|
||||
initKeyDesc:aKeyDesc
|
||||
valueDesc:aValueDesc];
|
||||
}
|
||||
|
||||
+ newKeyDesc:(const char *)aKeyDesc
|
||||
valueDesc:(const char *)aValueDesc
|
||||
capacity:(unsigned)aCapacity
|
||||
{
|
||||
return [[self alloc]
|
||||
initKeyDesc:aKeyDesc
|
||||
valueDesc:aValueDesc
|
||||
capacity:aCapacity];
|
||||
}
|
||||
|
||||
- makeObjectsPerform:(SEL)aSel
|
||||
{
|
||||
node_ptr node = 0;
|
||||
|
||||
while ((node = hash_next(_buckets, node)))
|
||||
[(id)(node->value) perform:aSel];
|
||||
return self;
|
||||
}
|
||||
|
||||
- makeObjectsPerform:(SEL)aSel with:anObject
|
||||
{
|
||||
node_ptr node = 0;
|
||||
|
||||
while ((node = hash_next(_buckets, node)))
|
||||
[(id)(node->value) perform:aSel with:anObject];
|
||||
return self;
|
||||
}
|
||||
|
||||
@end
|
358
Source/List.m
358
Source/List.m
|
@ -1,358 +0,0 @@
|
|||
/* Implementation of Objective-C NeXT-compatible List object
|
||||
Copyright (C) 1993, 1994, 1996 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNUstep Base Library.
|
||||
|
||||
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
|
||||
Date: May 1993
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <base/preface.h>
|
||||
#include <objc/List.h>
|
||||
|
||||
/* Change this #define to 0 if you want -makeObjectsPerform: and
|
||||
-makeObjectsPerform:with: to access content objects in order
|
||||
from lower indices to higher indices.
|
||||
If you want the NeXTSTEP behavior, leave the #define as 1. */
|
||||
#define LIST_PERFORM_REVERSE_ORDER_DEFAULT 1
|
||||
|
||||
#define LIST_GROW_FACTOR 2
|
||||
|
||||
|
||||
/* memcpy() is a gcc builtin */
|
||||
|
||||
|
||||
/* Do this before adding an element */
|
||||
static inline void
|
||||
incrementCount(List *self)
|
||||
{
|
||||
(self->numElements)++;
|
||||
if (self->numElements >= self->maxElements)
|
||||
{
|
||||
[self setAvailableCapacity:(self->numElements) * LIST_GROW_FACTOR];
|
||||
}
|
||||
}
|
||||
|
||||
/* Do this after removing an element */
|
||||
static inline void
|
||||
decrementCount(List *self)
|
||||
{
|
||||
(self->numElements)--;
|
||||
if (self->numElements < (self->maxElements) / LIST_GROW_FACTOR)
|
||||
{
|
||||
[self setAvailableCapacity:(self->maxElements) / LIST_GROW_FACTOR];
|
||||
}
|
||||
}
|
||||
|
||||
@implementation List
|
||||
|
||||
+ initialize
|
||||
{
|
||||
if (self == [List class])
|
||||
[self setVersion:0]; /* beta release */
|
||||
return self;
|
||||
}
|
||||
|
||||
// INITIALIZING, FREEING;
|
||||
|
||||
- initCount:(unsigned)numSlots;
|
||||
{
|
||||
[super init];
|
||||
numElements = 0;
|
||||
maxElements = numSlots;
|
||||
OBJC_MALLOC(dataPtr, id, maxElements);
|
||||
return self;
|
||||
}
|
||||
|
||||
- init
|
||||
{
|
||||
return [self initCount:2];
|
||||
}
|
||||
|
||||
|
||||
- free
|
||||
{
|
||||
if (dataPtr)
|
||||
OBJC_FREE(dataPtr);
|
||||
return [super free];
|
||||
}
|
||||
|
||||
- freeObjects
|
||||
{
|
||||
[self makeObjectsPerform:@selector(free)];
|
||||
[self empty];
|
||||
return self;
|
||||
}
|
||||
|
||||
// COPYING;
|
||||
|
||||
- copy
|
||||
{
|
||||
return [self shallowCopy];
|
||||
}
|
||||
|
||||
- shallowCopy
|
||||
{
|
||||
List *c = [super shallowCopy];
|
||||
OBJC_MALLOC(c->dataPtr, id, maxElements);
|
||||
memcpy(c->dataPtr, dataPtr, numElements * sizeof(id *));
|
||||
return c;
|
||||
}
|
||||
|
||||
- deepen
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < numElements; i++)
|
||||
{
|
||||
dataPtr[i] = [dataPtr[i] deepCopy];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
// COMPARING TWO LISTS;
|
||||
|
||||
- (BOOL)isEqual: anObject
|
||||
{
|
||||
int i;
|
||||
|
||||
if ( (![anObject isKindOf:[List class]])
|
||||
|| ([self count] != [anObject count]))
|
||||
return NO;
|
||||
for (i = 0; i < numElements; i++)
|
||||
/* NeXT documentation says to compare id's. */
|
||||
if ( dataPtr[i] != [anObject objectAt:i] )
|
||||
return NO;
|
||||
return YES;
|
||||
}
|
||||
|
||||
// MANAGING THE STORAGE CAPACITY;
|
||||
|
||||
- (unsigned)capacity
|
||||
{
|
||||
return maxElements;
|
||||
}
|
||||
|
||||
- setAvailableCapacity:(unsigned)numSlots
|
||||
{
|
||||
if (numSlots > numElements)
|
||||
{
|
||||
maxElements = numSlots;
|
||||
OBJC_REALLOC(dataPtr, id, maxElements);
|
||||
return self;
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
|
||||
/* Manipulating objects by index */
|
||||
|
||||
#define CHECK_INDEX(IND) if ((IND) >= numElements) return nil
|
||||
#define CHECK_OBJECT(OBJ) if (!(OBJ)) return nil
|
||||
|
||||
- (unsigned)count
|
||||
{
|
||||
return numElements;
|
||||
}
|
||||
|
||||
- objectAt:(unsigned)index
|
||||
{
|
||||
CHECK_INDEX(index);
|
||||
return dataPtr[index];
|
||||
}
|
||||
|
||||
- lastObject
|
||||
{
|
||||
if (numElements)
|
||||
return dataPtr[numElements-1];
|
||||
else
|
||||
return nil;
|
||||
}
|
||||
|
||||
- addObject:anObject
|
||||
{
|
||||
[self insertObject:anObject at:numElements];
|
||||
return self;
|
||||
}
|
||||
|
||||
- insertObject:anObject at:(unsigned)index
|
||||
{
|
||||
int i;
|
||||
|
||||
if (index > 0) {
|
||||
CHECK_INDEX(index-1);
|
||||
}
|
||||
CHECK_OBJECT(anObject);
|
||||
incrementCount(self);
|
||||
for (i = numElements-1; i > index; i--)
|
||||
dataPtr[i] = dataPtr[i-1];
|
||||
dataPtr[i] = anObject;
|
||||
return self;
|
||||
}
|
||||
|
||||
- removeObjectAt:(unsigned)index
|
||||
{
|
||||
id oldObject;
|
||||
int i;
|
||||
|
||||
CHECK_INDEX(index);
|
||||
oldObject = dataPtr[index];
|
||||
for (i = index; i < numElements-1; i++)
|
||||
dataPtr[i] = dataPtr[i+1];
|
||||
decrementCount(self);
|
||||
return oldObject;
|
||||
}
|
||||
|
||||
- removeLastObject
|
||||
{
|
||||
if (numElements)
|
||||
return [self removeObjectAt:numElements-1];
|
||||
return nil;
|
||||
}
|
||||
|
||||
- replaceObjectAt:(unsigned)index with:newObject
|
||||
{
|
||||
id oldObject;
|
||||
|
||||
CHECK_INDEX(index);
|
||||
CHECK_OBJECT(newObject);
|
||||
oldObject = dataPtr[index];
|
||||
dataPtr[index] = newObject;
|
||||
return oldObject;
|
||||
}
|
||||
|
||||
/* Inefficient to send objectAt: each time, but it handles subclasses
|
||||
of List nicely. */
|
||||
- appendList: (List *)otherList
|
||||
{
|
||||
int i, c;
|
||||
|
||||
c = [otherList count];
|
||||
/* Should we do something like this for efficiency?
|
||||
[self setCapacity:numElements+c]; */
|
||||
for (i = 0; i < c; i++)
|
||||
[self addObject:[otherList objectAt:i]];
|
||||
return self;
|
||||
}
|
||||
|
||||
/* Manipulating objects by id */
|
||||
|
||||
- (unsigned) indexOf:anObject
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < numElements; i++)
|
||||
if ([dataPtr[i] isEqual:anObject])
|
||||
return i;
|
||||
return NX_NOT_IN_LIST;
|
||||
}
|
||||
|
||||
- addObjectIfAbsent:anObject
|
||||
{
|
||||
CHECK_OBJECT(anObject);
|
||||
if ([self indexOf:anObject] == NX_NOT_IN_LIST)
|
||||
[self addObject:anObject];
|
||||
return self;
|
||||
}
|
||||
|
||||
- removeObject:anObject
|
||||
{
|
||||
CHECK_OBJECT(anObject);
|
||||
return [self removeObjectAt:[self indexOf:anObject]];
|
||||
}
|
||||
|
||||
- replaceObject:anObject with:newObject
|
||||
{
|
||||
return [self replaceObjectAt:[self indexOf:anObject]
|
||||
with:newObject];
|
||||
}
|
||||
|
||||
/* Emptying the list */
|
||||
|
||||
- empty
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < numElements; i++)
|
||||
dataPtr[i] = nil;
|
||||
numElements = 0;
|
||||
return self;
|
||||
}
|
||||
|
||||
/* Archiving */
|
||||
|
||||
- write: (TypedStream*)aStream
|
||||
{
|
||||
[super write: aStream];
|
||||
objc_write_types (aStream, "II", &numElements, &maxElements);
|
||||
objc_write_array (aStream, "@", numElements, dataPtr);
|
||||
return self;
|
||||
}
|
||||
|
||||
- read: (TypedStream*)aStream
|
||||
{
|
||||
[super read: aStream];
|
||||
objc_read_types (aStream, "II", &numElements, &maxElements);
|
||||
OBJC_MALLOC(dataPtr, id, maxElements);
|
||||
objc_read_array (aStream, "@", numElements, dataPtr);
|
||||
return self;
|
||||
}
|
||||
|
||||
/* Sending messages to elements of the list */
|
||||
|
||||
- makeObjectsPerform:(SEL)aSel
|
||||
{
|
||||
int i;
|
||||
|
||||
/* For better interaction with List subclasses, we could use
|
||||
objectAt: instead of accessing dataPtr directly. */
|
||||
#if (LIST_PERFORM_REVERSE_ORDER_DEFAULT)
|
||||
for (i = numElements-1; i >= 0; i--)
|
||||
[dataPtr[i] perform:aSel];
|
||||
#else
|
||||
for (i = 0; i < numElements; i++)
|
||||
[dataPtr[i] perform:aSel];
|
||||
#endif /* LIST_PERFORM_REVERSE_ORDER_DEFAULT */
|
||||
return self;
|
||||
}
|
||||
|
||||
- makeObjectsPerform:(SEL)aSel with:anObject
|
||||
{
|
||||
int i;
|
||||
|
||||
/* For better interaction with List subclasses, we could use
|
||||
objectAt: instead of accessing dataPtr directly. */
|
||||
#if (LIST_PERFORM_REVERSE_ORDER_DEFAULT)
|
||||
for (i = numElements-1; i >= 0; i--)
|
||||
[dataPtr[i] perform:aSel with:anObject];
|
||||
#else
|
||||
for (i = 0; i < numElements; i++)
|
||||
[dataPtr[i] perform:aSel with:anObject];
|
||||
#endif /* LIST_PERFORM_REVERSE_ORDER_DEFAULT */
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
/* Old-style creation */
|
||||
|
||||
+ newCount:(unsigned)numSlots
|
||||
{
|
||||
return [[self alloc] initCount:numSlots];
|
||||
}
|
||||
|
||||
@end
|
|
@ -131,13 +131,6 @@ $(NSNUMBER_MFILES) : NSConcreteNumber.m
|
|||
echo '#define TYPE_ORDER' `echo $@ | sed -e "s,[^0-9],,g"` >$@
|
||||
cat $(srcdir)/NSConcreteNumber.m >> $@
|
||||
|
||||
NXStringTable_scan.c: NXStringTable_scan.l
|
||||
$(FLEX) $(LEXFLAGS) -t $(srcdir)/NXStringTable_scan.l \
|
||||
> NXStringTable_scan.temp
|
||||
sed "s/yy/NXlex_/g" < NXStringTable_scan.temp \
|
||||
> NXStringTable_scan.c
|
||||
$(RM) -f NXStringTable_scan.temp
|
||||
|
||||
$(GNUSTEP_OBJ_DIR)/objc-load${OEXT}: dynamic-load.h
|
||||
|
||||
dynamic-load.h: ../config.status
|
||||
|
|
|
@ -1,151 +0,0 @@
|
|||
/* Implementation for Objective C NeXT-compatible NXStringTable object
|
||||
Copyright (C) 1993 Free Software Foundation, Inc.
|
||||
|
||||
Written by: Adam Fedor <adam@bastille.rmnug.org>
|
||||
|
||||
This file is part of the GNU Objective-C Collection library.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
StringTable - Hash table for strings in the NeXT StringTable style
|
||||
|
||||
TODO: Should I reject duplicate keys on readFromStream?
|
||||
the real MAX_STRINGTABLE_LENGTH is in NXStringTable.l, even though
|
||||
it also appears in StringTable.h
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <base/preface.h>
|
||||
#include <objc/NXStringTable.h>
|
||||
|
||||
char *
|
||||
CopyStringBuffer(const char *buf)
|
||||
{
|
||||
char *out;
|
||||
if (!buf)
|
||||
return NULL;
|
||||
OBJC_MALLOC(out, char, strlen(buf)+1);
|
||||
if (out)
|
||||
strcpy(out, buf);
|
||||
return out;
|
||||
}
|
||||
|
||||
/* table_scan is a lexical parser created using flex. It parses a string
|
||||
table and returns (1) every time it finds a token (the token is stored
|
||||
in *str. It returns (-1) on an error or (0) when finished. Tokens are
|
||||
guaranteed to alternate between Keys and Values.
|
||||
*/
|
||||
#if HAVE_FLEX
|
||||
extern int NXtable_scan(FILE *in_stream, FILE *out_stream, const char **str);
|
||||
#else
|
||||
/* Variables to export to yylex */
|
||||
FILE *NXscan_in;
|
||||
FILE *NXscan_out;
|
||||
char *NXscan_string;
|
||||
#endif
|
||||
|
||||
@implementation NXStringTable
|
||||
|
||||
- init
|
||||
{
|
||||
return [super initKeyDesc: "*" valueDesc: "*"];
|
||||
}
|
||||
|
||||
- (const char *)valueForStringKey:(const char *)aString
|
||||
{
|
||||
return [super valueForKey:aString];
|
||||
}
|
||||
|
||||
- readFromStream:(FILE *)stream
|
||||
{
|
||||
const char *str;
|
||||
char *key = 0, *value;
|
||||
int status;
|
||||
BOOL gotKey = NO;
|
||||
|
||||
#if HAVE_FLEX
|
||||
status = NXtable_scan(stream, stderr, &str);
|
||||
#else
|
||||
NXscan_in = stream;
|
||||
NXscan_out = stderr;
|
||||
status = NXlex_lex();
|
||||
str = NXscan_string;
|
||||
#endif
|
||||
while (status > 0) {
|
||||
if (gotKey) {
|
||||
value = CopyStringBuffer(str);
|
||||
[super insertKey:key value:value];
|
||||
} else
|
||||
key = CopyStringBuffer(str);
|
||||
gotKey = ~gotKey;
|
||||
#if HAVE_FLEX
|
||||
status = NXtable_scan(stream, stderr, &str);
|
||||
#else
|
||||
status = NXlex_lex();
|
||||
#endif
|
||||
}
|
||||
if (gotKey) {
|
||||
OBJC_FREE(key);
|
||||
return nil;
|
||||
}
|
||||
|
||||
return (status >= 0) ? self : nil;
|
||||
}
|
||||
|
||||
- readFromFile:(const char *)fileName
|
||||
{
|
||||
id returnVal;
|
||||
FILE *stream;
|
||||
if ((stream = fopen(fileName, "r")) == NULL) {
|
||||
perror("Error (NXStringTable)");
|
||||
return nil;
|
||||
}
|
||||
returnVal = [self readFromStream:stream];
|
||||
fclose(stream);
|
||||
return returnVal;
|
||||
}
|
||||
|
||||
- writeToStream:(FILE *)stream
|
||||
{
|
||||
const char *key;
|
||||
char *value;
|
||||
NXHashState state = [super initState];
|
||||
while ([super nextState: &state
|
||||
key: (const void **)&key
|
||||
value: (void **)&value])
|
||||
fprintf(stream, "\"%s\" = \"%s\";\n", key, value);
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- writeToFile:(const char *)fileName
|
||||
{
|
||||
FILE *stream;
|
||||
if ((stream = fopen(fileName, "w")) == NULL) {
|
||||
perror("Error (NXStringTable)");
|
||||
return nil;
|
||||
}
|
||||
[self writeToStream:stream];
|
||||
fclose(stream);
|
||||
return self;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
File diff suppressed because it is too large
Load diff
|
@ -1,216 +0,0 @@
|
|||
/* Lex scanner for Objective C NeXT-compatible NXStringTable object
|
||||
Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
|
||||
|
||||
Written by: Adam Fedor <adam@bastille.rmnug.org>
|
||||
|
||||
This file is part of the GNU Objective-C Collection library.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
%{
|
||||
|
||||
#ifdef HAVE_FLEX
|
||||
#define YY_DECL int NXtable_scan(FILE *NXscan_in, \
|
||||
FILE *NXscan_out, const char **buffer)
|
||||
#endif
|
||||
#define MAX_STRINGTABLE_LENGTH 1024
|
||||
#define KEY 1
|
||||
#define VALUE 2
|
||||
|
||||
#define yyterminate() {got = 0; line = 1; return 0;}
|
||||
#define return_err() {got = 0; line = 1; return -1;}
|
||||
#define return_ok() {return 1;}
|
||||
|
||||
%}
|
||||
|
||||
ESCAPES [abfnrtv]
|
||||
|
||||
%s parse comment token
|
||||
|
||||
%%
|
||||
/* Lexical initialization - This gets executed before any analysis */
|
||||
char string_buf[MAX_STRINGTABLE_LENGTH];
|
||||
char *string_buf_ptr = NULL;
|
||||
static int got; /* Holds the type of token we just got */
|
||||
static int line;
|
||||
#ifndef HAVE_FLEX
|
||||
extern FILE *NXscan_in;
|
||||
extern FILE *NXscan_out;
|
||||
extern char *NXscan_string;
|
||||
#endif
|
||||
if (yyin != NXscan_in || line <= 1) { /* Reset */
|
||||
got = 0;
|
||||
line= 1;
|
||||
/* ifdef's can't start in column 1 in this part of the lex file */
|
||||
#ifdef FLEX_SCANNER
|
||||
yyrestart(NXscan_in);
|
||||
#else
|
||||
/* FIXME: This is a horrible hack to get lex to reset itself at the
|
||||
beggining of a new file. (And it still doesn't work right) */
|
||||
yysptr = yysbuf;
|
||||
yyin = NXscan_in;
|
||||
#endif
|
||||
}
|
||||
yyout = NXscan_out;
|
||||
#ifdef HAVE_FLEX
|
||||
*buffer = string_buf;
|
||||
#else
|
||||
NXscan_string = string_buf;
|
||||
#endif
|
||||
BEGIN(parse);
|
||||
|
||||
<parse>"/*" BEGIN(comment);
|
||||
|
||||
<comment>[^*\n]* /* eat anything that's not a '*' */;
|
||||
<comment>"*"+[^*/\n]* /* eat up '*'s not followed by '/'s */;
|
||||
<comment>\n line++;
|
||||
<comment>"*"+"/" BEGIN(parse);
|
||||
<comment><<EOF>> {
|
||||
/* error - unterminated comment */
|
||||
fprintf(stderr, "ERROR (NXStringTable): Unterminated comment\n");
|
||||
return_err();
|
||||
}
|
||||
|
||||
<parse>= {
|
||||
if (!got) {
|
||||
fprintf(stderr, "\nERROR (NXStringTable): Improper use of = (Expected a key, line %d)\n", line);
|
||||
return_err();
|
||||
}
|
||||
if (got == VALUE) {
|
||||
fprintf(stderr, "\nERROR (NXStringTable): Improper use of = (Expected a ;, line %d)\n", line);
|
||||
return_err();
|
||||
}
|
||||
}
|
||||
|
||||
<parse>; {
|
||||
if (!got) {
|
||||
fprintf(stderr, "\nERROR (NXStringTable): Improper use of ; (Expected a key, line %d)\n", line);
|
||||
return_err();
|
||||
}
|
||||
if (got == KEY) {
|
||||
got = 0;
|
||||
return_ok();
|
||||
}
|
||||
got = 0;
|
||||
}
|
||||
|
||||
<parse>[ \t]* /* Eat up white space between tokens */;
|
||||
|
||||
<parse>\n line++;
|
||||
|
||||
<parse>\" {string_buf_ptr = string_buf; BEGIN(token);}
|
||||
|
||||
<parse><<EOF>> yyterminate();
|
||||
|
||||
<parse>. {
|
||||
fprintf(stderr, "ERROR (NXStringTable): Extra characters in table (line %d)\n", line);
|
||||
return_err();
|
||||
}
|
||||
|
||||
<token>\" { /* saw closing quote - all done */
|
||||
BEGIN(parse);
|
||||
*string_buf_ptr = '\0';
|
||||
/* return string constant token type and
|
||||
* value to parser
|
||||
*/
|
||||
got++;
|
||||
if (got == KEY || got == VALUE) {
|
||||
return_ok();
|
||||
} else {
|
||||
fprintf(stderr, "ERROR (NXStringTable): Parse error, line %d \n", line);
|
||||
return_err();
|
||||
}
|
||||
}
|
||||
|
||||
<token>\n {
|
||||
/* error - unterminated string constant */
|
||||
fprintf(stderr, "ERROR (NXStringTable): Unterminated string (line %d)\n", line);
|
||||
return_err();
|
||||
}
|
||||
|
||||
<token><<EOF>> {
|
||||
/* error - unterminated string constant */
|
||||
fprintf(stderr, "ERROR (NXStringTable): Unterminated string (line %d)\n", line);
|
||||
return_err();
|
||||
}
|
||||
|
||||
<token>\\{ESCAPES} {*string_buf_ptr++='\\';*string_buf_ptr++ = yytext[1];}
|
||||
|
||||
<token>\\(.|\n) *string_buf_ptr++ = yytext[1];
|
||||
|
||||
<token>[^\\\n\"]+ {
|
||||
char *text_ptr = yytext;
|
||||
if (!text_ptr) {
|
||||
fprintf(stderr, "ERROR (NXStringTable): internal parse error\n");
|
||||
break;
|
||||
}
|
||||
while ( *text_ptr )
|
||||
*string_buf_ptr++ = *text_ptr++;
|
||||
}
|
||||
|
||||
%%
|
||||
|
||||
int
|
||||
yywrap()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef NEED_MAIN
|
||||
#ifndef HAVE_FLEX
|
||||
FILE *NXscan_in;
|
||||
FILE *NXscan_out;
|
||||
char *NXscan_string;
|
||||
#endif
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
FILE *input;
|
||||
const char *str;
|
||||
int ok, value = 0;
|
||||
|
||||
if (argc > 1) {
|
||||
if ((input = fopen(argv[1], "r")) == NULL) {
|
||||
fprintf(stderr, "Error: Couldn't open %s\n", argv[1]);
|
||||
exit (1);
|
||||
}
|
||||
} else
|
||||
exit(1);
|
||||
|
||||
#ifdef HAVE_FLEX
|
||||
ok = NXtable_scan( input, stdout, &str);
|
||||
#else
|
||||
NXscan_in = input;
|
||||
NXscan_out = stdout;
|
||||
ok = yylex();
|
||||
str = NXscan_string;
|
||||
#endif
|
||||
while (ok > 0) {
|
||||
if (value)
|
||||
printf("Value: %s\n", str);
|
||||
else
|
||||
printf("Key: %s\n", str);
|
||||
value = ~value;
|
||||
#ifdef HAVE_FLEX
|
||||
ok = NXtable_scan( input, stdout, &str);
|
||||
#else
|
||||
ok = yylex();
|
||||
#endif
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
301
Source/Storage.m
301
Source/Storage.m
|
@ -1,301 +0,0 @@
|
|||
/* Implementation of Objective C NeXT-compatible Storage object
|
||||
Copyright (C) 1993,1994, 1996 Free Software Foundation, Inc.
|
||||
|
||||
Written by: Kresten Krab Thorup <krab@iesd.auc.dk>
|
||||
Dept. of Mathematics and Computer Science, Aalborg U., Denmark
|
||||
|
||||
This file is part of the GNUstep Base Library.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <objc/Storage.h>
|
||||
#include <base/preface.h>
|
||||
/* memcpy() and memcmp() are gcc builtin's */
|
||||
|
||||
/* Deal with bzero: */
|
||||
#if STDC_HEADERS || HAVE_STRING_H
|
||||
#include <string.h>
|
||||
/* An ANSI string.h and pre-ANSI memory.h might conflict. */
|
||||
#if !STDC_HEADERS && HAVE_MEMORY_H
|
||||
#include <memory.h>
|
||||
#endif /* not STDC_HEADERS and HAVE_MEMORY_H */
|
||||
#define index strchr
|
||||
#define rindex strrchr
|
||||
#define bcopy(s, d, n) memcpy ((d), (s), (n))
|
||||
#define bcmp(s1, s2, n) memcmp ((s1), (s2), (n))
|
||||
#define bzero(s, n) memset ((s), 0, (n))
|
||||
#else /* not STDC_HEADERS and not HAVE_STRING_H */
|
||||
#include <strings.h>
|
||||
/* memory.h and strings.h conflict on some systems. */
|
||||
#endif /* not STDC_HEADERS and not HAVE_STRING_H */
|
||||
|
||||
|
||||
#define GNU_STORAGE_NTH(x,N) \
|
||||
({ GNUStorageId* __s=(GNUStorageId*)(x); \
|
||||
(void*)(((char*)__s->dataPtr)+(__s->elementSize*(N))); })
|
||||
#define STORAGE_NTH(N) GNU_STORAGE_NTH (self, N)
|
||||
|
||||
typedef struct {
|
||||
@defs(Storage)
|
||||
} GNUStorageId;
|
||||
|
||||
@implementation Storage
|
||||
|
||||
+ initialize
|
||||
{
|
||||
if (self == [Storage class])
|
||||
[self setVersion:0]; /* beta release */
|
||||
return self;
|
||||
}
|
||||
|
||||
// INITIALIZING, FREEING;
|
||||
|
||||
- initCount: (unsigned)numSlots
|
||||
elementSize: (unsigned)sizeInBytes
|
||||
description: (const char*)elemDesc;
|
||||
{
|
||||
[super init];
|
||||
numElements = numSlots;
|
||||
maxElements = (numSlots > 0) ? numSlots : 1;
|
||||
elementSize = sizeInBytes;
|
||||
description = elemDesc;
|
||||
dataPtr = (void*) objc_malloc (maxElements * elementSize);
|
||||
bzero(dataPtr, numElements * elementSize);
|
||||
return self;
|
||||
}
|
||||
|
||||
- init
|
||||
{
|
||||
return [self initCount:1
|
||||
elementSize:sizeof(id)
|
||||
description:@encode(id)];
|
||||
}
|
||||
|
||||
|
||||
- free
|
||||
{
|
||||
if (dataPtr)
|
||||
free(dataPtr);
|
||||
return [super free];
|
||||
}
|
||||
|
||||
- (const char*) description
|
||||
{
|
||||
return description;
|
||||
}
|
||||
|
||||
|
||||
// COPYING;
|
||||
|
||||
- shallowCopy
|
||||
{
|
||||
Storage *c = [super shallowCopy];
|
||||
c->dataPtr = (void*) objc_malloc (maxElements * elementSize);
|
||||
memcpy(c->dataPtr, dataPtr, numElements * elementSize);
|
||||
return c;
|
||||
}
|
||||
|
||||
// COMPARING TWO STORAGES;
|
||||
|
||||
- (BOOL)isEqual: anObject
|
||||
{
|
||||
if ([anObject isKindOf: [Storage class]]
|
||||
&& [anObject count] == [self count]
|
||||
&& !memcmp(((GNUStorageId*)anObject)->dataPtr,
|
||||
dataPtr, numElements*elementSize))
|
||||
return YES;
|
||||
else
|
||||
return NO;
|
||||
}
|
||||
|
||||
// MANAGING THE STORAGE CAPACITY;
|
||||
|
||||
static inline void _makeRoomForAnotherIfNecessary(Storage *self)
|
||||
{
|
||||
if (self->numElements == self->maxElements)
|
||||
{
|
||||
self->maxElements *= 2;
|
||||
self->dataPtr = (void*)
|
||||
objc_realloc (self->dataPtr, self->maxElements*self->elementSize);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void _shrinkIfDesired(Storage *self)
|
||||
{
|
||||
if (self->numElements < (self->maxElements / 2))
|
||||
{
|
||||
self->maxElements /= 2;
|
||||
self->dataPtr = (void *)
|
||||
objc_realloc (self->dataPtr, self->maxElements*self->elementSize);
|
||||
}
|
||||
}
|
||||
|
||||
- setAvailableCapacity:(unsigned)numSlots
|
||||
{
|
||||
if (numSlots > numElements)
|
||||
{
|
||||
maxElements = numSlots;
|
||||
dataPtr = (void*) objc_realloc (dataPtr, maxElements * elementSize);
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- setNumSlots:(unsigned)numSlots
|
||||
{
|
||||
if (numSlots > numElements)
|
||||
{
|
||||
maxElements = numSlots;
|
||||
dataPtr = (void*) objc_realloc (dataPtr, maxElements * elementSize);
|
||||
bzero(STORAGE_NTH(numElements), (maxElements-numElements)*elementSize);
|
||||
}
|
||||
else if (numSlots < numElements)
|
||||
{
|
||||
numElements = numSlots;
|
||||
_shrinkIfDesired (self);
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
/* Manipulating objects by index */
|
||||
|
||||
#define CHECK_INDEX(IND) if (IND >= numElements) return 0
|
||||
|
||||
- (unsigned) count
|
||||
{
|
||||
return numElements;
|
||||
}
|
||||
|
||||
- (void*) elementAt: (unsigned)index
|
||||
{
|
||||
CHECK_INDEX(index);
|
||||
return STORAGE_NTH (index);
|
||||
}
|
||||
|
||||
- addElement: (void*)anElement
|
||||
{
|
||||
_makeRoomForAnotherIfNecessary(self);
|
||||
memcpy(STORAGE_NTH(numElements), anElement, elementSize);
|
||||
numElements++;
|
||||
return self;
|
||||
}
|
||||
|
||||
- insertElement: (void*)anElement at: (unsigned)index
|
||||
{
|
||||
int i;
|
||||
|
||||
CHECK_INDEX(index);
|
||||
_makeRoomForAnotherIfNecessary(self);
|
||||
#ifndef STABLE_MEMCPY
|
||||
for (i = numElements; i >= index; i--)
|
||||
memcpy (STORAGE_NTH(i+1), STORAGE_NTH(i), elementSize);
|
||||
#else
|
||||
memcpy (STORAGE_NTH (index+1),
|
||||
STORAGE_NTH (index),
|
||||
elementSize*(numElements-index));
|
||||
#endif
|
||||
memcpy(STORAGE_NTH(i), anElement, elementSize);
|
||||
numElements++;
|
||||
return self;
|
||||
}
|
||||
|
||||
- removeElementAt: (unsigned)index
|
||||
{
|
||||
int i;
|
||||
|
||||
CHECK_INDEX(index);
|
||||
numElements--;
|
||||
#ifndef STABLE_MEMCPY
|
||||
for (i = index; i < numElements; i++)
|
||||
memcpy(STORAGE_NTH(i),
|
||||
STORAGE_NTH(i+1),
|
||||
elementSize);
|
||||
#else
|
||||
memcpy (STORAGE_NTH (index),
|
||||
STORAGE_NTH (index+1),
|
||||
elementSize*(numElements-index-1));
|
||||
#endif
|
||||
_shrinkIfDesired(self);
|
||||
return self;
|
||||
}
|
||||
|
||||
- removeLastElement
|
||||
{
|
||||
if (numElements)
|
||||
{
|
||||
numElements--;
|
||||
_shrinkIfDesired(self);
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- replaceElementAt:(unsigned)index with:(void*)newElement
|
||||
{
|
||||
CHECK_INDEX(index);
|
||||
memcpy(STORAGE_NTH(index), newElement, elementSize);
|
||||
return self;
|
||||
}
|
||||
|
||||
/* Emptying the Storage */
|
||||
|
||||
- empty
|
||||
{
|
||||
numElements = 0;
|
||||
maxElements = 1;
|
||||
dataPtr = (void*) objc_realloc (dataPtr, maxElements * elementSize);
|
||||
return self;
|
||||
}
|
||||
|
||||
/* Archiving */
|
||||
|
||||
- write: (TypedStream*)aStream
|
||||
{
|
||||
int i;
|
||||
|
||||
[super write:aStream];
|
||||
objc_write_types(aStream, "III*",
|
||||
&numElements, &maxElements, &elementSize, &description);
|
||||
for (i = 0; i < numElements; i++)
|
||||
objc_write_type(aStream, description, STORAGE_NTH(i));
|
||||
return self;
|
||||
}
|
||||
|
||||
- read: (TypedStream*)aStream
|
||||
{
|
||||
int i;
|
||||
|
||||
[super read:aStream];
|
||||
objc_read_types(aStream, "III*",
|
||||
&numElements, &maxElements, &elementSize, &description);
|
||||
dataPtr = (void*) objc_malloc (maxElements * elementSize);
|
||||
for (i = 0; i < numElements; i++)
|
||||
objc_read_type(aStream, description, STORAGE_NTH(i));
|
||||
return self;
|
||||
}
|
||||
|
||||
+ new
|
||||
{
|
||||
return [[self alloc] init];
|
||||
}
|
||||
|
||||
+ newCount:(unsigned)count elementSize:(unsigned)sizeInBytes
|
||||
description:(const char *)descriptor
|
||||
{
|
||||
return [[self alloc] initCount:count elementSize:sizeInBytes
|
||||
description:descriptor];
|
||||
}
|
||||
|
||||
@end
|
|
@ -1,108 +0,0 @@
|
|||
/* Interface for Objective C NeXT-compatible HashTable object
|
||||
Copyright (C) 1993, 1994, 1996 Free Software Foundation, Inc.
|
||||
|
||||
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
|
||||
Created: May 1993
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/******************************************************************
|
||||
TODO:
|
||||
Does not implement methods for archiving itself.
|
||||
Does not implement -freeKeys:values:.
|
||||
******************************************************************/
|
||||
|
||||
#ifndef __HashTable_h_INCLUDE_GNU
|
||||
#define __HashTable_h_INCLUDE_GNU
|
||||
|
||||
#include <objc/Object.h>
|
||||
#include <base/preface.h>
|
||||
#include <objc/hash.h>
|
||||
|
||||
typedef node_ptr NXHashState;
|
||||
|
||||
@interface HashTable: Object
|
||||
{
|
||||
unsigned count; /* Current number of associations */
|
||||
const char *keyDesc; /* Description of keys */
|
||||
const char *valueDesc; /* Description of values */
|
||||
unsigned _nbBuckets; /* Current size of the array */
|
||||
cache_ptr _buckets; /* Data array */
|
||||
}
|
||||
/* We include some instance vars we don't need so we are compatible
|
||||
with NeXT programs that expect them to be there */
|
||||
|
||||
|
||||
/* Initializing */
|
||||
|
||||
- init;
|
||||
- initKeyDesc: (const char *)aKeyDesc;
|
||||
- initKeyDesc:(const char *)aKeyDesc
|
||||
valueDesc:(const char *)aValueDesc;
|
||||
- initKeyDesc: (const char *) aKeyDesc
|
||||
valueDesc: (const char *)aValueDesc
|
||||
capacity: (unsigned) aCapacity;
|
||||
|
||||
/* Freeing */
|
||||
|
||||
- free;
|
||||
- freeObjects;
|
||||
- freeKeys:(void (*) (void *))keyFunc
|
||||
values:(void (*) (void *))valueFunc;
|
||||
- empty;
|
||||
|
||||
/* Copying */
|
||||
|
||||
- shallowCopy;
|
||||
- deepen;
|
||||
|
||||
/* Manipulating */
|
||||
|
||||
- (unsigned)count;
|
||||
- (BOOL)isKey:(const void *)aKey;
|
||||
- (void *)valueForKey:(const void *)aKey;
|
||||
- (void *)insertKey:(const void *)aKey value:(void *)aValue;
|
||||
- (void *)removeKey:(const void *)aKey;
|
||||
|
||||
/* Iterating */
|
||||
|
||||
- (NXHashState)initState;
|
||||
- (BOOL)nextState:(NXHashState *)aState
|
||||
key:(const void **)aKey
|
||||
value:(void **)aValue;
|
||||
|
||||
/* Archiving */
|
||||
|
||||
- read: (TypedStream*)aStream;
|
||||
- write: (TypedStream*)aStream;
|
||||
|
||||
/* Old-style creation */
|
||||
|
||||
+ newKeyDesc: (const char *)aKeyDesc;
|
||||
+ newKeyDesc:(const char *)aKeyDesc
|
||||
valueDesc:(const char *)aValueDesc;
|
||||
+ newKeyDesc:(const char *)aKeyDesc
|
||||
valueDesc:(const char *)aValueDesc
|
||||
capacity:(unsigned)aCapacity;
|
||||
|
||||
/* Sending messages to elements of the hashtable */
|
||||
|
||||
- makeObjectsPerform:(SEL)aSel;
|
||||
- makeObjectsPerform:(SEL)aSel with:anObject;
|
||||
|
||||
@end
|
||||
|
||||
#endif /* __HashTable_h_INCLUDE_GNU */
|
|
@ -1,103 +0,0 @@
|
|||
/* Interface for Objective-C NeXT-compatible List object
|
||||
Copyright (C) 1993,1994 Free Software Foundation, Inc.
|
||||
|
||||
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
|
||||
Date: May 1993
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef __List_h_INCLUDE_GNU
|
||||
#define __List_h_INCLUDE_GNU
|
||||
|
||||
#include <objc/Object.h>
|
||||
|
||||
@interface List : Object
|
||||
{
|
||||
@public
|
||||
id *dataPtr; /* data of the List object */
|
||||
unsigned numElements; /* Actual number of elements */
|
||||
unsigned maxElements; /* Total allocated elements */
|
||||
}
|
||||
|
||||
/* Creating, copying, freeing */
|
||||
|
||||
- free;
|
||||
- freeObjects;
|
||||
- shallowCopy;
|
||||
- deepen;
|
||||
|
||||
/* Initializing */
|
||||
|
||||
- init;
|
||||
- initCount:(unsigned)numSlots;
|
||||
|
||||
/* Comparing two lists */
|
||||
|
||||
- (BOOL)isEqual: anObject;
|
||||
|
||||
/* Managing the storage capacity */
|
||||
|
||||
- (unsigned)capacity;
|
||||
- setAvailableCapacity:(unsigned)numSlots;
|
||||
|
||||
/* Manipulating objects by index */
|
||||
|
||||
- (unsigned)count;
|
||||
- objectAt:(unsigned)index;
|
||||
- lastObject;
|
||||
- addObject:anObject;
|
||||
- insertObject:anObject at:(unsigned)index;
|
||||
- removeObjectAt:(unsigned)index;
|
||||
- removeLastObject;
|
||||
- replaceObjectAt:(unsigned)index with:newObject;
|
||||
- appendList: (List *)otherList;
|
||||
|
||||
/* Manipulating objects by id */
|
||||
|
||||
- (unsigned)indexOf:anObject;
|
||||
- addObjectIfAbsent:anObject;
|
||||
- removeObject:anObject;
|
||||
- replaceObject:anObject with:newObject;
|
||||
|
||||
/* Emptying the list */
|
||||
|
||||
- empty;
|
||||
|
||||
/* Archiving */
|
||||
|
||||
- read: (TypedStream*)aStream;
|
||||
- write: (TypedStream*)aStream;
|
||||
|
||||
/* Sending messages to elements of the list */
|
||||
|
||||
- makeObjectsPerform:(SEL)aSel;
|
||||
- makeObjectsPerform:(SEL)aSel with:anObject;
|
||||
|
||||
/* old-style creation */
|
||||
|
||||
+ newCount:(unsigned)numSlots;
|
||||
|
||||
@end
|
||||
|
||||
typedef struct {
|
||||
@defs(List)
|
||||
} NXListId;
|
||||
|
||||
#define NX_ADDRESS(x) (((NXListId *)(x))->dataPtr)
|
||||
|
||||
#define NX_NOT_IN_LIST 0xffffffff
|
||||
|
||||
#endif /* __List_h_INCLUDE_GNU */
|
|
@ -1,57 +0,0 @@
|
|||
/* Interface for Objective C NeXT-compatible NXStringTable object
|
||||
Copyright (C) 1993,1994, 1997 Free Software Foundation, Inc.
|
||||
|
||||
Written by: Adam Fedor <adam@bastille.rmnug.org>
|
||||
|
||||
This file is part of the GNU Objective-C Collection library.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
StringTable.h - Hash table for strings in the NeXT StringTable style
|
||||
|
||||
*/
|
||||
|
||||
#ifndef __NXStringTable_h_INCLUDE_GNU
|
||||
#define __NXStringTable_h_INCLUDE_GNU
|
||||
|
||||
#include <objc/HashTable.h>
|
||||
|
||||
#define MAX_NXSTRINGTABLE_LENGTH 1024
|
||||
|
||||
@interface NXStringTable: HashTable
|
||||
|
||||
- init;
|
||||
|
||||
- (const char *)valueForStringKey:(const char *)aString;
|
||||
|
||||
- readFromStream:(FILE *)stream;
|
||||
- readFromFile:(const char *)fileName;
|
||||
|
||||
- writeToStream:(FILE *)stream;
|
||||
- writeToFile:(const char *)fileName;
|
||||
|
||||
@end
|
||||
|
||||
#if 0
|
||||
static inline const char *STRVAL(NXStringTable *table, const char *key) {
|
||||
return [table valueForStringKey:key];
|
||||
}
|
||||
#else
|
||||
#define STRVAL(TABLE,KEY) ([TABLE valueForStringKey: KEY])
|
||||
#endif
|
||||
|
||||
#endif /* __NXStringTable_h_INCLUDE_GNU */
|
|
@ -1,85 +0,0 @@
|
|||
/* Interface for Objective C NeXT-compatible Storage object
|
||||
Copyright (C) 1993,1994 Free Software Foundation, Inc.
|
||||
|
||||
Written by: Kresten Krab Thorup <krab@iesd.auc.dk>
|
||||
Dept. of Mathematics and Computer Science, Aalborg U., Denmark
|
||||
|
||||
This file is part of the Gnustep Base Library.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/******************************************************************
|
||||
TODO:
|
||||
Does not implement methods for archiving itself.
|
||||
******************************************************************/
|
||||
|
||||
#ifndef __Storage_h_INCLUDE_GNU
|
||||
#define __Storage_h_INCLUDE_GNU
|
||||
|
||||
#include <objc/Object.h>
|
||||
|
||||
@interface Storage : Object
|
||||
{
|
||||
@public
|
||||
void *dataPtr; /* data of the Storage object */
|
||||
const char *description; /* Element description */
|
||||
unsigned numElements; /* Actual number of elements */
|
||||
unsigned maxElements; /* Total allocated elements */
|
||||
unsigned elementSize; /* Element size */
|
||||
}
|
||||
|
||||
/* Creating, freeing, initializing, and emptying */
|
||||
|
||||
- init;
|
||||
- initCount:(unsigned)numSlots elementSize:(unsigned)sizeInBytes
|
||||
description:(const char*)elemDesc;
|
||||
- free;
|
||||
- empty;
|
||||
- shallowCopy;
|
||||
|
||||
/* Manipulating the elements */
|
||||
|
||||
- (BOOL)isEqual: anObject;
|
||||
- (const char *)description;
|
||||
- (unsigned)count;
|
||||
- (void *)elementAt:(unsigned)index;
|
||||
- replaceElementAt:(unsigned)index with:(void *)anElement;
|
||||
- setNumSlots:(unsigned)numSlots;
|
||||
- setAvailableCapacity:(unsigned)numSlots;
|
||||
- addElement:(void *)anElement;
|
||||
- removeLastElement;
|
||||
- insertElement:(void *)anElement at:(unsigned)index;
|
||||
- removeElementAt:(unsigned)index;
|
||||
|
||||
/* Archiving */
|
||||
|
||||
- write:(TypedStream *)stream;
|
||||
- read:(TypedStream *)stream;
|
||||
|
||||
/* old-style creation */
|
||||
|
||||
+ new;
|
||||
+ newCount:(unsigned)count elementSize:(unsigned)sizeInBytes
|
||||
description:(const char *)descriptor;
|
||||
|
||||
@end
|
||||
|
||||
typedef struct {
|
||||
@defs(Storage)
|
||||
} NXStorageId;
|
||||
|
||||
|
||||
#endif /* __Storage_h_INCLUDE_GNU */
|
|
@ -1,31 +0,0 @@
|
|||
#ifndef __zone_h_OBJECTS_INCLUDE
|
||||
#define __zone_h_OBJECTS_INCLUDE
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
typedef struct _NXZone
|
||||
{
|
||||
void *(*realloc)(struct _NXZone *zonep, void *ptr, size_t size);
|
||||
void *(*malloc)(struct _NXZone *zonep, size_t size);
|
||||
void (*free)(struct _NXZone *zonep, void *ptr);
|
||||
void (*destroy)(struct _NXZone *zonep);
|
||||
} NXZone;
|
||||
|
||||
#define NX_NOZONE ((NXZone *)0)
|
||||
#define NXZoneMalloc(zonep, size) ((*(zonep)->malloc)(zonep, size))
|
||||
#define NXZoneRealloc(zonep, ptr, size) ((*(zonep)->realloc)(zonep, ptr, size))
|
||||
#define NXZoneFree(zonep, ptr) ((*(zonep)->free)(zonep, ptr))
|
||||
#define NXDestroyZone(zonep) ((*(zonep)->destroy)(zonep))
|
||||
|
||||
extern NXZone *NXDefaultMallocZone(void);
|
||||
extern NXZone *NXCreateZone(size_t startSize, size_t granularity, int canFree);
|
||||
extern NXZone *NXCreateChildZone(NXZone *parentZone, size_t startSize,
|
||||
size_t granularity, int canFree);
|
||||
extern void NXMergeZone(NXZone *zonep);
|
||||
extern void *NXZoneCalloc(NXZone *zonep, size_t numElems, size_t byteSize);
|
||||
extern NXZone *NXZoneFromPtr(void *ptr);
|
||||
extern void NXZonePtrInfo(void *ptr);
|
||||
extern void NXNameZone(NXZone *z, const char *name);
|
||||
extern int NXMallocCheck(void);
|
||||
|
||||
#endif /* __zone_h_OBJECTS_INCLUDE */
|
Loading…
Reference in a new issue