mirror of
https://github.com/gnustep/libs-base.git
synced 2025-06-01 09:02:01 +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
7ea6dcb5e1
commit
6d8484769e
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>
|
Tue Feb 9 14:08:00 1999 Richard Frith-Macdonald <richard@brainstorm.co.uk>
|
||||||
|
|
||||||
* Source/NSProcessInfo.m: Fixed login in #if construct so things
|
* Source/NSProcessInfo.m: Fixed login in #if construct so things
|
||||||
|
|
|
@ -251,29 +251,6 @@ RNGBerkeley.h \
|
||||||
RandomGenerating.h \
|
RandomGenerating.h \
|
||||||
Time.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
|
# GNUStep source files
|
||||||
|
|
||||||
BASE_MFILES = \
|
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"` >$@
|
echo '#define TYPE_ORDER' `echo $@ | sed -e "s,[^0-9],,g"` >$@
|
||||||
cat $(srcdir)/NSConcreteNumber.m >> $@
|
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
|
$(GNUSTEP_OBJ_DIR)/objc-load${OEXT}: dynamic-load.h
|
||||||
|
|
||||||
dynamic-load.h: ../config.status
|
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…
Add table
Add a link
Reference in a new issue