Major refactoring of DOH List/Hash iterators. See CHANGES

git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk/SWIG@5101 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
Dave Beazley 2003-09-11 20:26:57 +00:00
commit 8ae4c60d39
35 changed files with 657 additions and 636 deletions

View file

@ -31,6 +31,8 @@ First(obj) Return first object (iterator)
Next(obj) Return next object
Dump(obj,out) Serialize on out
Load(in) Unserialize from in
First(obj) Iterator
Next(iter) Next iterator
Mapping Operations (for hash table behavior)
--------------------------------------------

View file

@ -192,6 +192,51 @@ DohCmp(const DOH *obj1, const DOH *obj2) {
return 1;
}
/* -----------------------------------------------------------------------------
* DohFirst()
* ----------------------------------------------------------------------------- */
DohIterator
DohFirst(DOH *obj) {
DohIterator iter;
DohBase *b;
DohObjInfo *binfo;
b = (DohBase *) obj;
if (DohCheck(b)) {
binfo = b->type;
if (binfo->doh_first) {
return (binfo->doh_first)(b);
}
}
iter.object = 0;
iter.item = 0;
iter.key = 0;
return iter;
}
/* -----------------------------------------------------------------------------
* DohNext()
* ----------------------------------------------------------------------------- */
DohIterator
DohNext(DohIterator iter) {
DohIterator niter;
if (iter.object) {
DohBase *b;
DohObjInfo *binfo;
b = (DohBase *) iter.object;
binfo = b->type;
if (binfo->doh_next) {
return (binfo->doh_next)(iter);
}
}
niter = iter;
return niter;
}
/* -----------------------------------------------------------------------------
* DohIsMapping()
* ----------------------------------------------------------------------------- */
@ -249,35 +294,7 @@ DohDelattr(DOH *obj, const DOH *name) {
}
/* -----------------------------------------------------------------------------
* DohFirstkey()
* ----------------------------------------------------------------------------- */
DOH *
DohFirstkey(DOH *obj) {
DohBase *b = (DohBase *) obj;
DohObjInfo *objinfo = b->type;
if (objinfo->doh_hash && objinfo->doh_hash->doh_firstkey) {
return (objinfo->doh_hash->doh_firstkey)(b);
}
return 0;
}
/* -----------------------------------------------------------------------------
* DohNextkey()
* ----------------------------------------------------------------------------- */
DOH *
DohNextkey(DOH *obj) {
DohBase *b = (DohBase *) obj;
DohObjInfo *objinfo = b->type;
if (objinfo && objinfo->doh_hash->doh_nextkey) {
return (objinfo->doh_hash->doh_nextkey)(b);
}
return 0;
}
/* -----------------------------------------------------------------------------
* DohNextkey()
* DohKeys()
* ----------------------------------------------------------------------------- */
DOH *
@ -474,34 +491,6 @@ DohDelslice(DOH *obj, int sindex, int eindex) {
return -1;
}
/* -----------------------------------------------------------------------------
* DohFirstitem()
* ----------------------------------------------------------------------------- */
DOH *
DohFirstitem(DOH *obj) {
DohBase *b = (DohBase *) obj;
DohObjInfo *objinfo = b->type;
if (objinfo->doh_list && objinfo->doh_list->doh_firstitem) {
return (objinfo->doh_list->doh_firstitem)(b);
}
return 0;
}
/* -----------------------------------------------------------------------------
* DohNextitem()
* ----------------------------------------------------------------------------- */
DOH *
DohNextitem(DOH *obj) {
DohBase *b = (DohBase *) obj;
DohObjInfo *objinfo = b->type;
if (objinfo->doh_list && objinfo->doh_list->doh_nextitem) {
return (objinfo->doh_list->doh_nextitem)(b);
}
return 0;
}
/* -----------------------------------------------------------------------------
* DohIsFile()
* ----------------------------------------------------------------------------- */

View file

@ -44,8 +44,6 @@
#define DohGetattr DOH_NAMESPACE(Getattr)
#define DohSetattr DOH_NAMESPACE(Setattr)
#define DohDelattr DOH_NAMESPACE(Delattr)
#define DohFirstkey DOH_NAMESPACE(Firstkey)
#define DohNextkey DOH_NAMESPACE(Nextkey)
#define DohKeys DOH_NAMESPACE(Keys)
#define DohGetInt DOH_NAMESPACE(GetInt)
#define DohGetDouble DOH_NAMESPACE(GetDouble)
@ -60,8 +58,6 @@
#define DohDelitem DOH_NAMESPACE(Delitem)
#define DohInsertitem DOH_NAMESPACE(Insertitem)
#define DohDelslice DOH_NAMESPACE(Delslice)
#define DohFirstitem DOH_NAMESPACE(Firstitem)
#define DohNextitem DOH_NAMESPACE(Nextitem)
#define DohWrite DOH_NAMESPACE(Write)
#define DohRead DOH_NAMESPACE(Read)
#define DohSeek DOH_NAMESPACE(Seek)
@ -113,7 +109,9 @@
#define DohHashType DOH_NAMESPACE(HashType)
#define DohFileType DOH_NAMESPACE(FileType)
#define DohVoidType DOH_NAMESPACE(VoidType)
#define DohIterator DOH_NAMESPACE(Iterator)
#define DohFirst DOH_NAMESPACE(First)
#define DohNext DOH_NAMESPACE(Next)
#endif
#include <stdio.h>
@ -143,6 +141,16 @@ typedef void DOH;
#define DOH_CUR -3
#define DOH_CURRENT -3
/* Iterator objects */
typedef struct {
void *key; /* Current key (if any) */
void *item; /* Current item */
void *object; /* Object being iterated over */
void *_current; /* Internal use */
int _index; /* Internal use */
} DohIterator;
/* Memory management */
#ifndef DohMalloc
@ -176,8 +184,6 @@ extern void DohIncref(DOH *obj);
extern DOH *DohGetattr(DOH *obj, const DOHString_or_char *name);
extern int DohSetattr(DOH *obj, const DOHString_or_char *name, const DOHObj_or_char *value);
extern int DohDelattr(DOH *obj, const DOHString_or_char *name);
extern DOH *DohFirstkey(DOH *obj);
extern DOH *DohNextkey(DOH *obj);
extern DOH *DohKeys(DOH *obj);
extern int DohGetInt(DOH *obj, const DOHString_or_char *name);
extern double DohGetDouble(DOH *obj, const DOHString_or_char *name);
@ -194,8 +200,6 @@ extern int DohSetitem(DOH *obj, int index, const DOHObj_or_char *value
extern int DohDelitem(DOH *obj, int index);
extern int DohInsertitem(DOH *obj, int index, const DOHObj_or_char *value);
extern int DohDelslice(DOH *obj, int sindex, int eindex);
extern DOH *DohFirstitem(DOH *obj);
extern DOH *DohNextitem(DOH *obj);
/* File methods */
@ -207,7 +211,11 @@ extern int DohGetc(DOHFile *obj);
extern int DohPutc(int ch, DOHFile *obj);
extern int DohUngetc(int ch, DOHFile *obj);
/* Positional */
/* Iterators */
extern DohIterator DohFirst(DOH *obj);
extern DohIterator DohNext(DohIterator x);
/* Positional */
extern int DohGetline(DOH *obj);
extern void DohSetline(DOH *obj, int line);
@ -321,8 +329,6 @@ extern void DohMemoryDebug(void);
#define Append(s,x) DohInsertitem(s,DOH_END,x)
#define Push(s,x) DohInsertitem(s,DOH_BEGIN,x)
#define Len DohLen
#define Firstkey DohFirstkey
#define Nextkey DohNextkey
#define Data DohData
#define Char (char *) Data
#define Cmp DohCmp
@ -349,8 +355,6 @@ extern void DohMemoryDebug(void);
#define SetDouble DohSetDouble
#define SetChar DohSetattr
#define SetVoid DohSetVoid
#define Firstitem DohFirstitem
#define Nextitem DohNextitem
#define Readline DohReadline
#define Replace DohReplace
#define Chop DohChop
@ -378,6 +382,9 @@ extern void DohMemoryDebug(void);
#define Getmark DohGetmark
#define None DohNone
#define Call DohCall
#define First DohFirst
#define Next DohNext
#define Iterator DohIterator
#endif
#ifdef NIL

View file

@ -29,20 +29,16 @@ typedef struct {
DOH *(*doh_getattr)(DOH *obj, DOH *name); /* Get attribute */
int (*doh_setattr)(DOH *obj, DOH *name, DOH *value); /* Set attribute */
int (*doh_delattr)(DOH *obj, DOH *name); /* Del attribute */
DOH *(*doh_firstkey)(DOH *obj); /* First key */
DOH *(*doh_nextkey)(DOH *obj); /* Next key */
DOH *(*doh_keys)(DOH *obj); /* All keys as a list */
} DohHashMethods;
/* List objects */
typedef struct {
DOH *(*doh_getitem)(DOH *obj, int index); /* Get item */
int (*doh_setitem)(DOH *obj, int index, DOH *value); /* Set item */
int (*doh_delitem)(DOH *obj, int index); /* Delete item */
int (*doh_insitem)(DOH *obj, int index, DOH *value); /* Insert item */
int (*doh_delslice)(DOH *obj, int sindex, int eindex); /* Delete slice */
DOH *(*doh_firstitem)(DOH *obj); /* Iterators */
DOH *(*doh_nextitem)(DOH *obj);
DOH *(*doh_getitem)(DOH *obj, int index); /* Get item */
int (*doh_setitem)(DOH *obj, int index, DOH *value); /* Set item */
int (*doh_delitem)(DOH *obj, int index); /* Delete item */
int (*doh_insitem)(DOH *obj, int index, DOH *value); /* Insert item */
int (*doh_delslice)(DOH *obj, int sindex, int eindex); /* Delete slice */
} DohListMethods;
/* File methods */
@ -87,6 +83,10 @@ typedef struct DohObjInfo {
/* Compare */
int (*doh_cmp)(DOH *obj1, DOH *obj2);
/* Iterators */
DohIterator (*doh_first)(DOH *obj);
DohIterator (*doh_next)(DohIterator );
/* Positional */
void (*doh_setfile)(DOH *obj, DOHString_or_char *file);
DOH *(*doh_getfile)(DOH *obj);
@ -105,14 +105,15 @@ typedef struct {
void *data; /* Data pointer */
DohObjInfo *type;
void *meta; /* Meta data */
int flag_intern : 1; /* Interned object */
int flag_marked : 1; /* Mark flag. Used to avoid recursive loops in places */
int flag_user : 1; /* User flag */
int flag_usermark : 1; /* User marked */
int refcount : 28; /* Reference count (max 16 million) */
int flag_intern : 1; /* Interned object */
int flag_marked : 1; /* Mark flag. Used to avoid recursive loops in places */
int flag_user : 1; /* User flag */
int flag_usermark : 1; /* User marked */
int refcount : 28; /* Reference count (max 16 million) */
} DohBase;
/* Macros for decrefing and increfing (safe for null objects). */
#define Decref(a) if (a) ((DohBase *) a)->refcount--
#define Incref(a) if (a) ((DohBase *) a)->refcount++
#define Refcount(a) ((DohBase *) a)->refcount
@ -124,7 +125,7 @@ typedef struct {
#define ObjType(a) ((DohBase *)a)->type
extern DOH *DohObjMalloc(DohObjInfo *type, void *data); /* Allocate a DOH object */
extern void DohObjFree(DOH *ptr); /* Free a DOH object */
extern void DohObjFree(DOH *ptr); /* Free a DOH object */
#endif /* DOHINT_H */

View file

@ -214,6 +214,8 @@ static DohObjInfo DohFileType = {
0, /* doh_len */
0, /* doh_hash */
0, /* doh_cmp */
0, /* doh_first */
0, /* doh_next */
0, /* doh_setfile */
0, /* doh_getfile */
0, /* doh_setline */

View file

@ -28,9 +28,7 @@ typedef struct Hash {
int line;
HashNode **hashtable;
int hashsize;
int currentindex;
int nitems;
HashNode *current;
} Hash;
/* Key interning structure */
@ -288,11 +286,6 @@ Hash_delattr(DOH *ho, DOH *k) {
} else {
h->hashtable[hv] = n->next;
}
/* Need to check for iterator location */
if (n == h->current) {
h->current = prev; /* Move back to previous node. When next is called, will move to next node */
if (!h->current) h->currentindex--; /* No previous node. Move back one slot */
}
DelNode(n);
h->nitems--;
return 1;
@ -303,63 +296,53 @@ Hash_delattr(DOH *ho, DOH *k) {
return 0;
}
/* General purpose iterators */
static HashNode *
hash_first(DOH *ho) {
Hash *h = (Hash *) ObjData(ho);
h->currentindex = 0;
h->current = 0;
while ((h->currentindex < h->hashsize) && !h->hashtable[h->currentindex])
h->currentindex++;
if (h->currentindex >= h->hashsize) return 0;
h->current = h->hashtable[h->currentindex];
return h->current;
static DohIterator
Hash_firstiter(DOH *ho) {
DohIterator iter;
Hash *h = (Hash *) ObjData(ho);
iter.object = ho;
iter._current = 0;
iter.item = 0;
iter.key = 0;
iter._index = 0; /* Index in hash table */
while ((iter._index < h->hashsize) && !h->hashtable[iter._index])
iter._index++;
if (iter._index >= h->hashsize) {
return iter;
}
iter._current = h->hashtable[iter._index];
iter.item = ((HashNode *) iter._current)->object;
iter.key = ((HashNode *) iter._current)->key;
/* Actually save the next slot in the hash. This makes it possible to
delete the item being iterated over without trashing the universe */
iter._current = ((HashNode*)iter._current)->next;
return iter;
}
static HashNode *
hash_next(DOH *ho) {
Hash *h = (Hash *) ObjData(ho);
if (h->currentindex < 0) return hash_first(ho);
/* Try to move to the next entry */
if (h->current) {
h->current = h->current->next;
static DohIterator
Hash_nextiter(DohIterator iter) {
Hash *h = (Hash *) ObjData(iter.object);
if (!iter._current) {
iter._index++;
while ((iter._index < h->hashsize) && !h->hashtable[iter._index]) {
iter._index++;
}
if (h->current) {
return h->current;
if (iter._index >= h->hashsize) {
iter.item = 0;
iter.key = 0;
iter._current = 0;
return iter;
}
h->currentindex++;
while ((h->currentindex < h->hashsize) && !h->hashtable[h->currentindex])
h->currentindex++;
if (h->currentindex >= h->hashsize) return 0;
h->current = h->hashtable[h->currentindex];
return h->current;
}
iter._current = h->hashtable[iter._index];
}
iter.key = ((HashNode *) iter._current)->key;
iter.item = ((HashNode *) iter._current)->object;
/* -----------------------------------------------------------------------------
* Hash_firstkey()
*
* Return first hash-table key.
* ----------------------------------------------------------------------------- */
static DOH *
Hash_firstkey(DOH *ho) {
HashNode *hn = hash_first(ho);
if (hn) return hn->key;
return 0;
}
/* -----------------------------------------------------------------------------
* Hash_nextkey()
*
* Return next hash table key.
* ----------------------------------------------------------------------------- */
static DOH *
Hash_nextkey(DOH *ho) {
HashNode *hn = hash_next(ho);
if (hn) return hn->key;
return 0;
/* Store the next node to iterator on */
iter._current = ((HashNode*)iter._current)->next;
return iter;
}
/* -----------------------------------------------------------------------------
@ -371,13 +354,11 @@ Hash_nextkey(DOH *ho) {
static DOH *
Hash_keys(DOH *so) {
DOH *keys;
DOH *k;
Iterator i;
keys = NewList();
k = Firstkey(so);
while (k) {
Append(keys,k);
k = Nextkey(so);
for (i = First(so); i.key; i = Next(i)) {
Append(keys,i.key);
}
return keys;
}
@ -451,8 +432,6 @@ CopyHash(DOH *ho) {
for (i = 0; i < nh->hashsize; i++) {
nh->hashtable[i] = 0;
}
nh->currentindex = -1;
nh->current = 0;
nh->nitems = 0;
nh->line = h->line;
nh->file = h->file;
@ -512,8 +491,6 @@ static DohHashMethods HashHashMethods = {
Hash_getattr,
Hash_setattr,
Hash_delattr,
Hash_firstkey,
Hash_nextkey,
Hash_keys,
};
@ -528,6 +505,8 @@ DohObjInfo DohHashType = {
Hash_len, /* doh_len */
0, /* doh_hash */
0, /* doh_cmp */
Hash_firstiter, /* doh_first */
Hash_nextiter, /* doh_next */
Hash_setfile, /* doh_setfile */
Hash_getfile, /* doh_getfile */
Hash_setline, /* doh_setline */
@ -556,8 +535,6 @@ DohNewHash() {
for (i = 0; i < h->hashsize; i++) {
h->hashtable[i] = 0;
}
h->currentindex = -1;
h->current = 0;
h->nitems = 0;
h->file = 0;
h->line = 0;

View file

@ -16,7 +16,6 @@ char cvsroot_list_c[] = "$Header$";
typedef struct List {
int maxitems; /* Max size */
int nitems; /* Num items */
int iter; /* Iterator */
DOH *file;
int line;
DOH **items;
@ -46,7 +45,6 @@ CopyList(DOH *lo) {
nl->nitems = l->nitems;
nl->maxitems = l->maxitems;
nl->items = (void **) DohMalloc(l->maxitems*sizeof(void *));
nl->iter = 0;
for (i = 0; i < l->nitems; i++) {
nl->items[i] = l->items[i];
Incref(nl->items[i]);
@ -195,12 +193,19 @@ List_set(DOH *lo, int n, DOH *val) {
* Return the first item in the list.
* ----------------------------------------------------------------------------- */
static DOH *
static DohIterator
List_first(DOH *lo) {
List *l = (List *) ObjData(lo);
l->iter = 0;
if (l->iter >= l->nitems) return 0;
return l->items[l->iter];
DohIterator iter;
List *l = (List *) ObjData(lo);
iter.object = lo;
iter._index = 0;
iter.key = 0;
if (l->nitems > 0) {
iter.item = l->items[0];
} else {
iter.item = 0;
}
return iter;
}
/* -----------------------------------------------------------------------------
@ -209,12 +214,17 @@ List_first(DOH *lo) {
* Return the next item in the list.
* ----------------------------------------------------------------------------- */
static DOH *
List_next(DOH *lo) {
List *l = (List *) ObjData(lo);
l->iter++;
if (l->iter >= l->nitems) return 0;
return l->items[l->iter];
static DohIterator
List_next(DohIterator iter) {
List *l = (List *) ObjData(iter.object);
iter._index = iter._index + 1;
if (iter._index >= l->nitems) {
iter.item = 0;
iter.key = 0;
} else {
iter.item = l->items[iter._index];
}
return iter;
}
/* -----------------------------------------------------------------------------
@ -300,8 +310,6 @@ static DohListMethods ListListMethods = {
List_remove,
List_insert,
0, /* delslice */
List_first,
List_next,
};
DohObjInfo DohListType = {
@ -315,6 +323,8 @@ DohObjInfo DohListType = {
List_len, /* doh_len */
0, /* doh_hash */
0, /* doh_cmp */
List_first, /* doh_first */
List_next, /* doh_next */
List_setfile, /* doh_setfile */
List_getfile, /* doh_getfile */
List_setline, /* doh_setline */
@ -346,7 +356,6 @@ DohNewList() {
for (i = 0; i < MAXLISTITEMS; i++) {
l->items[i] = 0;
}
l->iter = 0;
l->file = 0;
l->line = 0;
return DohObjMalloc(&DohListType,l);

View file

@ -874,8 +874,6 @@ static DohListMethods StringListMethods = {
String_delitem, /* doh_delitem */
String_insert, /* doh_insitem */
String_delslice, /* doh_delslice */
0, /* doh_first */
0, /* doh_next */
};
static DohFileMethods StringFileMethods = {
@ -905,6 +903,8 @@ DohObjInfo DohStringType = {
String_len, /* doh_len */
String_hash, /* doh_hash */
String_cmp, /* doh_cmp */
0, /* doh_first */
0, /* doh_next */
String_setfile, /* doh_setfile */
String_getfile, /* doh_getfile */
String_setline, /* doh_setline */

View file

@ -69,6 +69,8 @@ static DohObjInfo DohVoidType = {
0, /* doh_len */
0, /* doh_hash */
0, /* doh_cmp */
0, /* doh_first */
0, /* doh_next */
0, /* doh_setfile */
0, /* doh_getfile */
0, /* doh_setline */