diff --git a/SWIG/Source/DOH/Doh/Makefile b/SWIG/Source/DOH/Doh/Makefile index 562dc91cc..bdbe7e5b5 100644 --- a/SWIG/Source/DOH/Doh/Makefile +++ b/SWIG/Source/DOH/Doh/Makefile @@ -9,7 +9,7 @@ # Set your C++ compiler here. g++ works on most machines, # but you might have to change it depending on your installation. # -CC = cc -g +CC = gcc -g -Wall -DDOH_STRING_UPDATE_LINES -O2 prefix = /usr/local # Comment out the following line if you're on an SGI or don't have ranlib! diff --git a/SWIG/Source/DOH/Doh/base.c b/SWIG/Source/DOH/Doh/base.c index 2bf97c8ed..57da08ff3 100644 --- a/SWIG/Source/DOH/Doh/base.c +++ b/SWIG/Source/DOH/Doh/base.c @@ -45,6 +45,7 @@ static DohObjInfo DohBaseType = { 0, /* doh_del */ 0, /* doh_copy */ 0, /* doh_clear */ + 0, /* doh_scope */ 0, /* doh_str */ 0, /* doh_data */ 0, /* doh_dump */ @@ -85,8 +86,12 @@ static DOH *find_internal(DOH *co) { StringNode *r, *s; int d; char *c; + DOH *n; if (DohCheck(co)) return co; c = (char *) co; + n = NewString(c); + return n; + if (doh_debug_level) { DohError(DOH_CONVERSION,"Unknown object '%s' being treated as 'char *'.\n", c); } @@ -120,26 +125,24 @@ void DohDestroy(DOH *obj) { DohBase *b = (DohBase *) obj; DohError(DOH_CALLS,"DohDestroy %x\n",obj); if (!DohCheck(b)) return; + if (b->flags & DOH_FLAG_INTERN) return; b->refcount--; - if (b->refcount <= 0) { - if (doh_debug_level >= DOH_MEMORY) { - if (DohObjFreeCheck(obj)) { - DohError(DOH_MEMORY,"DohDestroy. %x was already released! (ignoring for now)\n", obj); - return; - } - } + if (b->refcount == 0) { if (b->objinfo->doh_del) { - (b->objinfo->doh_del)(obj); - return; - } else { - /* free(b); */ + (b->objinfo->doh_del)(obj); } + return; } } +void DohIntern(DOH *obj) { + DohBase *b = (DohBase *) obj; + if (!DohCheck(b)) return; + b->flags = b->flags | DOH_FLAG_INTERN; +} + /* Copy an object */ DOH *DohCopy(DOH *obj) { - DOH *result; DohBase *b = (DohBase *) obj; DohError(DOH_CALLS,"DohCopy %x\n",obj); if (!DohCheck(b)) { @@ -167,6 +170,20 @@ void DohClear(DOH *obj) { DohError(DOH_UNSUPPORTED, "No clear method defined for type '%s'\n", b->objinfo->objname); } +void DohSetScope(DOH *obj, int s) { + DohBase *b = (DohBase *) obj; + DohError(DOH_CALLS,"DohScope %x\n",obj); + if (!DohCheck(b)) { + DohError(DOH_UNKNOWN,"Unknown object %x passed to Scope.\n",obj); + return; + } + if (b->objinfo->doh_scope) { + (b->objinfo->doh_scope)(obj,s); + return; + } + if (s < b->scope) b->scope = s; +} + /* Turn an object into a string */ DOH *DohStr(DOH *obj) { DOH *s; @@ -202,7 +219,6 @@ int DohDump(DOH *obj, DOH *out) { /* Get the length */ int DohLen(DOH *obj) { - int s; DohBase *b = (DohBase *) obj; DohError(DOH_CALLS,"DohLen %x\n",obj); if (!b) return 0; @@ -220,7 +236,6 @@ int DohLen(DOH *obj) { /* Get the hash value */ int DohHashval(DOH *obj) { - int s; DohBase *b = (DohBase *) obj; DohError(DOH_CALLS,"DohHashval %x\n",obj); if (DohCheck(b)) { @@ -237,7 +252,6 @@ int DohHashval(DOH *obj) { /* Get raw data */ void *DohData(DOH *obj) { char *c; - char *s; DohBase *b = (DohBase *) obj; DohError(DOH_CALLS,"DohData %x\n",obj); c = (char *) obj; @@ -312,7 +326,6 @@ void DohSetfile(DOH *obj, DOH *file) { /* Get an attribute from an object */ int DohCmp(DOH *obj1, DOH *obj2) { - int s; DohBase *b1, *b2; DohError(DOH_CALLS,"DohCmp %x, %x\n",obj1,obj2); b1 = (DohBase *) obj1; @@ -347,15 +360,12 @@ int DohIsMapping(DOH *obj) { /* Get an attribute from an object */ DOH *DohGetattr(DOH *obj, DOH *name) { - DOH *s; - DOH *name_obj; DohBase *b = (DohBase *) obj; DohError(DOH_CALLS,"DohGetattr %x, %x\n",obj,name); if (!name) return 0; if (DohIsMapping(b)) { - name_obj = find_internal(name); if (b->objinfo->doh_mapping->doh_getattr) { - return (b->objinfo->doh_mapping->doh_getattr)(obj,name_obj); + return (b->objinfo->doh_mapping->doh_getattr)(obj,name); } } if (DohCheck(b)) { @@ -368,21 +378,12 @@ DOH *DohGetattr(DOH *obj, DOH *name) { /* Set an attribute in an object */ int DohSetattr(DOH *obj, DOH *name, DOH *value) { - int s; - DOH *name_obj, *value_obj; DohBase *b = (DohBase *) obj; DohError(DOH_CALLS,"DohSetattr %x, %x, %x\n",obj,name, value); if ((!name) || (!value)) return 0; if (DohIsMapping(b)) { - name_obj = find_internal(name); - if (!DohCheck(value)) { - DohError(DOH_CONVERSION,"Unknown object %x converted to a string in Setattr.\n",value); - value_obj = NewString(value); - } else { - value_obj = value; - } if (b->objinfo->doh_mapping->doh_setattr) { - return (b->objinfo->doh_mapping->doh_setattr)(obj,name_obj,value_obj); + return (b->objinfo->doh_mapping->doh_setattr)(obj,name,value); } } if (DohCheck(b)) { @@ -395,14 +396,12 @@ int DohSetattr(DOH *obj, DOH *name, DOH *value) { /* Delete an attribute from an object */ void DohDelattr(DOH *obj, DOH *name) { - DOH *name_obj; DohBase *b = (DohBase *) obj; DohError(DOH_CALLS,"DohDelattr %x, %x\n",obj,name); if (!name) return; if (DohIsMapping(obj)) { - name_obj = find_internal(name); if (b->objinfo->doh_mapping->doh_delattr) { - (b->objinfo->doh_mapping->doh_delattr)(obj,name_obj); + (b->objinfo->doh_mapping->doh_delattr)(obj,name); return; } } @@ -416,7 +415,6 @@ void DohDelattr(DOH *obj, DOH *name) { /* Get first item in an object */ DOH *DohFirst(DOH *obj) { - DOH *s; DohBase *b = (DohBase *) obj; DohError(DOH_CALLS,"DohFirst %x\n",obj); if (DohIsMapping(obj)) { @@ -434,7 +432,6 @@ DOH *DohFirst(DOH *obj) { /* Get next item in an object */ DOH *DohNext(DOH *obj) { - DOH *s; DohBase *b = (DohBase *) obj; DohError(DOH_CALLS,"DohNext %x\n",obj); if (DohIsMapping(obj)) { @@ -453,7 +450,6 @@ DOH *DohNext(DOH *obj) { /* Get first item in an object */ DOH *DohFirstkey(DOH *obj) { - DOH *s; DohBase *b = (DohBase *) obj; DohError(DOH_CALLS,"DohFirstkey %x\n",obj); if (DohIsMapping(obj)) { @@ -471,7 +467,6 @@ DOH *DohFirstkey(DOH *obj) { /* Get next item in an object */ DOH *DohNextkey(DOH *obj) { - DOH *s; DohBase *b = (DohBase *) obj; DohError(DOH_CALLS,"DohNextkey %x\n",obj); if (DohIsMapping(obj)) { @@ -488,7 +483,6 @@ DOH *DohNextkey(DOH *obj) { } int DohGetInt(DOH *obj, DOH *name) { - int ival; DOH *val; DohError(DOH_CALLS,"DohGetInt %x, %x\n",obj,name); val = Getattr(obj,name); @@ -500,7 +494,6 @@ int DohGetInt(DOH *obj, DOH *name) { } double DohGetDouble(DOH *obj, DOH *name) { - double dval; DOH *val; DohError(DOH_CALLS,"DohGetDouble %x, %x\n",obj,name); val = Getattr(obj,name); @@ -512,7 +505,6 @@ double DohGetDouble(DOH *obj, DOH *name) { } char *DohGetChar(DOH *obj, DOH *name) { - double dval; DOH *val; DohError(DOH_CALLS,"DohGetChar %x, %x\n",obj,name); val = Getattr(obj,name); @@ -553,7 +545,6 @@ int DohIsSequence(DOH *obj) { /* Get an item from an object */ DOH *DohGetitem(DOH *obj, int index) { - DOH *s; DohBase *b = (DohBase *) obj; DohError(DOH_CALLS,"DohGetitem %x, %d\n",obj,index); if (DohIsSequence(obj)) { @@ -621,7 +612,6 @@ void DohInsertitem(DOH *obj, int index, DOH *value) { DohError(DOH_CONVERSION,"Unknown object %x being converted to a string in Insertitem.\n", value); value_obj = NewString(value); no = 1; - Incref(value_obj); } else { value_obj = value; } @@ -827,10 +817,38 @@ int DohClose(DOH *obj) { return 0; } +/* ----------------------------------------------------------------------------- + * String methods + * ----------------------------------------------------------------------------- */ + +int DohIsString(DOH *obj) { + DohBase *b = (DohBase *) obj; + if (!DohCheck(b)) return 0; + if (b->objinfo->doh_string) return 1; + else return 0; +} + +int DohReplace(DOH *src, DOH *token, DOH *rep, int flags) { + DohBase *b = (DohBase *) src; + DohError(DOH_CALLS, "DohReplace %x\n", src); + if (DohIsString(src)) { + if (b->objinfo->doh_string->doh_replace) { + return (b->objinfo->doh_string->doh_replace)(src,token,rep,flags); + } + } + if (DohCheck(b)) { + DohError(DOH_UNSUPPORTED, "No replace method defined for type '%s'\n", b->objinfo->objname); + } else { + DohError(DOH_UNKNOWN,"Unknown object %x passed to Replace\n", b); + } + return 0; +} + void DohInit(DOH *b) { DohBase *bs = (DohBase *) b; - bs->refcount =0; + bs->refcount = 1; bs->objinfo = &DohBaseType; bs->line = 0; bs->file = 0; + bs->flags = 0; } diff --git a/SWIG/Source/DOH/Doh/file.c b/SWIG/Source/DOH/Doh/file.c index 3a5b37131..338fbe5ab 100644 --- a/SWIG/Source/DOH/Doh/file.c +++ b/SWIG/Source/DOH/Doh/file.c @@ -14,6 +14,7 @@ ****************************************************************************/ #include "dohint.h" +#include /* --------------------------------------------------------------------------- * $Header$ @@ -58,6 +59,7 @@ static DohObjInfo FileType = { DelFile, /* doh_del */ 0, /* doh_copy */ 0, /* doh_clear */ + 0, /* doh_scope */ 0, /* doh_str */ 0, /* doh_data */ 0, /* doh_dump */ @@ -95,7 +97,6 @@ NewFile(DOH *fn, char *mode) fclose(file); return 0; } - DohInit(f); f->objinfo = &FileType; f->filep = file; f->fd = fileno(file); @@ -113,7 +114,6 @@ NewFileFromFile(FILE *file) File *f; f = (File *) DohObjMalloc(sizeof(File)); if (!f) return 0; - DohInit(f); f->objinfo = &FileType; f->filep = file; f->fd = fileno(file); @@ -131,7 +131,6 @@ NewFileFromFd(int fd) File *f; f = (File *) DohObjMalloc(sizeof(File)); if (!f) return 0; - DohInit(f); f->objinfo = &FileType; f->filep = 0; f->fd = fd; diff --git a/SWIG/Source/DOH/Doh/fio.c b/SWIG/Source/DOH/Doh/fio.c index bdcf6f030..c462b3c21 100644 --- a/SWIG/Source/DOH/Doh/fio.c +++ b/SWIG/Source/DOH/Doh/fio.c @@ -77,18 +77,18 @@ DohvPrintf(DOH *so, char *format, va_list ap) char *p = format; char newformat[256]; char obuffer[OBUFLEN]; - char *fmt; + char *fmt = 0; char temp[64]; int widthval = 0; int precval = 0; int maxwidth; - char *w, *prec; + char *w = 0; int ivalue; double dvalue; void *pvalue; char *stemp; int nbytes = 0; - char encoder[128], *ec; + char encoder[128], *ec = 0; while (*p) { switch(state) { diff --git a/SWIG/Source/DOH/Doh/hash.c b/SWIG/Source/DOH/Doh/hash.c index 8c86c4b23..f12ec3c96 100644 --- a/SWIG/Source/DOH/Doh/hash.c +++ b/SWIG/Source/DOH/Doh/hash.c @@ -40,17 +40,62 @@ typedef struct Hash { HashNode *current; } Hash; + +/* ----------------------------------------------------------------------------- + Key interning. This is used for getattr,setattr functions. + + The following structure maps raw char * entries to string objects. + ----------------------------------------------------------------------------- */ + +typedef struct KeyValue { + char *cstr; + DOH *sstr; + struct KeyValue *left; + struct KeyValue *right; +} KeyValue; + +static KeyValue *root = 0; + +static DOH *find_key(char *c) { + KeyValue *r, *s; + int d = 0; + r = root; + s = 0; + while (r) { + s = r; + d = strcmp(r->cstr,c); + if (d == 0) return r->sstr; + if (d < 0) r = r->left; + else r = r->right; + } + /* fprintf(stderr,"Interning '%s'\n", c); */ + r = (KeyValue *) DohMalloc(sizeof(KeyValue)); + r->cstr = (char *) DohMalloc(strlen(c)+1); + strcpy(r->cstr,c); + r->sstr = NewString(c); + DohIntern(r->sstr); + r->left = 0; + r->right = 0; + if (!s) { root = r; } + else { + if (d < 0) s->left = r; + else s->right = r; + } + return r->sstr; +} + /* Forward references */ DOH *CopyHash(DOH *h); -void DelHash(DOH *h); -void Hash_clear(DOH *); -int Hash_setattr(DOH *, DOH *k, DOH *obj); +void DelHash(DOH *h); +void Hash_clear(DOH *); +void Hash_scope(DOH *, int); +int Hash_setattr(DOH *, DOH *k, DOH *obj); DOH *Hash_getattr(DOH *h, DOH *k); int Hash_delattr(DOH *h, DOH *k); DOH *Hash_firstkey(DOH *h); DOH *Hash_nextkey(DOH *h); DOH *Hash_str(DOH *h); -int Hash_len(DOH *h); +int Hash_len(DOH *h); #define HASH_INIT_SIZE 7 @@ -87,6 +132,7 @@ static DohObjInfo HashType = { DelHash, /* doh_del */ CopyHash, /* doh_copy */ Hash_clear, /* doh_clear */ + Hash_scope, /* doh_scope */ Hash_str, /* doh_str */ 0, /* doh_data */ 0, /* doh_dump */ @@ -121,7 +167,6 @@ DOH *NewHash() { Hash *h; int i; h = (Hash *) DohObjMalloc(sizeof(Hash)); - DohInit(h); h->hashsize = HASH_INIT_SIZE; h->hashtable = (HashNode **) DohMalloc(h->hashsize*sizeof(HashNode *)); for (i = 0; i < h->hashsize; i++) { @@ -142,11 +187,9 @@ DOH *CopyHash(DOH *ho) { Hash *h, *nh; HashNode *n; int i; - DOH *key; h = (Hash *) ho; nh = (Hash *) DohObjMalloc(sizeof(Hash)); - DohInit(nh); nh->hashsize = h->hashsize; nh->hashtable = (HashNode **) DohMalloc(nh->hashsize*sizeof(HashNode *)); @@ -159,7 +202,7 @@ DOH *CopyHash(DOH *ho) { nh->objinfo = h->objinfo; for (i = 0; i < h->hashsize; i++) { - if (n = h->hashtable[i]) { + if ((n = h->hashtable[i])) { while (n) { Hash_setattr(nh, n->key, n->object); n = n->next; @@ -181,7 +224,7 @@ void DelHash(DOH *ho) h = (Hash *) ho; for (i = 0; i < h->hashsize; i++) { - if (n = h->hashtable[i]) { + if ((n = h->hashtable[i])) { while (n) { next = n->next; DelNode(n); @@ -190,6 +233,8 @@ void DelHash(DOH *ho) } } DohFree(h->hashtable); + h->hashtable = 0; + h->hashsize = 0; DohObjFree(h); } @@ -205,7 +250,7 @@ void Hash_clear(DOH *ho) h = (Hash *) ho; for (i = 0; i < h->hashsize; i++) { - if (n = h->hashtable[i]) { + if ((n = h->hashtable[i])) { while (n) { next = n->next; DelNode(n); @@ -217,6 +262,31 @@ void Hash_clear(DOH *ho) h->nitems = 0; } +/* ----------------------------------------------------------------------------- + * Hash_scope(DOH *ho, int s) - Clear all entries in a hash table + * ----------------------------------------------------------------------------- */ + +void Hash_scope(DOH *ho, int s) +{ + Hash *h; + HashNode *n; + int i; + h = (Hash *) ho; + if (h->flags & DOH_FLAG_SETSCOPE) return; + if (s < h->scope) h->scope = s; + h->flags = h->flags | DOH_FLAG_SETSCOPE; + for (i = 0; i < h->hashsize; i++) { + if ((n = h->hashtable[i])) { + while (n) { + Setscope(n->object,s); + Setscope(n->key,s); + n = n->next; + } + } + } + h->flags = h->flags & ~DOH_FLAG_SETSCOPE; +} + /* ----------------------------------------------------------------------------- * static resize(Hash *h) - Resizes the hash table * ----------------------------------------------------------------------------- */ @@ -275,6 +345,10 @@ Hash_setattr(DOH *ho, DOH *k, DOH *obj) { HashNode *n, *prev; Hash *h; + if (!DohCheck(k)) k = find_key(k); + if (!DohCheck(obj)) { + obj = NewString((char *) obj); + } h = (Hash *) ho; hv = (Hashval(k)) % h->hashsize; n = h->hashtable[hv]; @@ -299,6 +373,8 @@ Hash_setattr(DOH *ho, DOH *k, DOH *obj) { } /* Add this to the table */ n = NewNode(k,obj); + Setscope(n->key,h->scope); + Setscope(n->object,h->scope); if (prev) prev->next = n; else h->hashtable[hv] = n; h->nitems++; @@ -316,6 +392,7 @@ Hash_getattr(DOH *ho, DOH *k) { HashNode *n; Hash *h; + if (!DohCheck(k)) k = find_key(k); h = (Hash *) ho; hv = Hashval(k) % h->hashsize; n = h->hashtable[hv]; @@ -337,6 +414,7 @@ Hash_delattr(DOH *ho, DOH *k) int hv; Hash *h; + if (!DohCheck(k)) k = find_key(k); h = (Hash *) ho; hv = Hashval(k) % h->hashsize; n = h->hashtable[hv]; @@ -434,6 +512,11 @@ Hash_str(DOH *ho) { h = (Hash *) ho; s = NewString(""); + if (h->flags & DOH_FLAG_PRINT) { + Printf(s,"Hash(0x%x)",h); + return s; + } + h->flags = h->flags | DOH_FLAG_PRINT; Printf(s,"Hash {\n"); for (i = 0; i < h->hashsize; i++) { n = h->hashtable[i]; @@ -443,18 +526,7 @@ Hash_str(DOH *ho) { } } Printf(s,"}\n"); -#ifdef old - s = NewString("Hash"); - Printf(s,"(%x) {",h); - for (i = 0; i < h->hashsize; i++) { - n = h->hashtable[i]; - while (n) { - Printf(s,"'%o',", n->key); - n = n->next; - } - } - Printf(s,"}"); -#endif + h->flags = h->flags & ~DOH_FLAG_PRINT; return s; } diff --git a/SWIG/Source/DOH/Doh/list.c b/SWIG/Source/DOH/Doh/list.c index 31d164264..c4eacd82b 100644 --- a/SWIG/Source/DOH/Doh/list.c +++ b/SWIG/Source/DOH/Doh/list.c @@ -36,6 +36,7 @@ typedef struct List { DOH *CopyList(DOH *); void DelList(DOH *); void List_clear(DOH *); +void List_scope(DOH *, int s); DOH *List_get(DOH *, int pos); int List_set(DOH *, int pos, DOH *obj); int List_insert(DOH *, int pos, DOH *item); @@ -63,6 +64,7 @@ static DohObjInfo ListType = { DelList, /* doh_del */ CopyList, /* doh_copy */ List_clear, /* doh_clear */ + List_scope, /* doh_scope */ List_str, /* doh_str */ 0, /* doh_data */ List_dump, /* doh_dump */ @@ -72,6 +74,7 @@ static DohObjInfo ListType = { 0, /* doh_cmp */ 0, /* doh_mapping */ &ListSeqMethods, /* doh_sequence */ + 0, /* doh_file */ 0, /* doh_string */ 0, /* doh_callable */ }; @@ -120,7 +123,6 @@ NewList() { List *l; int i; l = (List *) DohObjMalloc(sizeof(List)); - DohInit(l); l->objinfo = &ListType; l->nitems = 0; l->maxitems = MAXLISTITEMS; @@ -142,7 +144,6 @@ CopyList(DOH *lo) { int i; l = (List *) lo; nl = (List *) DohObjMalloc(sizeof(List)); - DohInit(nl); nl->objinfo = l->objinfo; nl->nitems = l->nitems; nl->maxitems = l->maxitems; @@ -171,6 +172,7 @@ DelList(DOH *lo) { Delete(l->items[i]); } DohFree(l->items); + l->items = 0; DohObjFree(l); } @@ -190,6 +192,23 @@ List_clear(DOH *lo) { l->nitems = 0; } +/* ----------------------------------------------------------------------------- + * void List_scope(DOH *lo, int s) + * ----------------------------------------------------------------------------- */ +void +List_scope(DOH *lo, int s) { + List *l; + int i; + l = (List *) lo; + if (l->flags & DOH_FLAG_SETSCOPE) return; + l->flags = l->flags | DOH_FLAG_SETSCOPE; + if (s < l->scope) l->scope = (unsigned char) s; + for (i = 0; i < l->nitems; i++) { + Setscope(l->items[i],s); + } + l->flags = l->flags & ~DOH_FLAG_SETSCOPE; +} + /* ----------------------------------------------------------------------------- * void List_insert(DOH *lo, int pos, DOH *item) - Insert an element * ----------------------------------------------------------------------------- */ @@ -201,7 +220,7 @@ List_insert(DOH *lo, int pos, DOH *item) DohBase *b; int i; - if (!item) return; + if (!item) return -1; b = (DohBase *) item; l = (List *) lo; @@ -214,6 +233,7 @@ List_insert(DOH *lo, int pos, DOH *item) } l->items[pos] = item; b->refcount++; + Setscope(b,l->scope); l->nitems++; return 0; } @@ -232,7 +252,7 @@ List_remove(DOH *lo, int pos) l = (List *) lo; if (pos == DOH_END) pos = l->nitems-1; if (pos == DOH_BEGIN) pos = 0; - if ((pos < 0) || (pos >= l->nitems)) return; + if ((pos < 0) || (pos >= l->nitems)) return -1; item = l->items[pos]; for (i = pos; i < l->nitems-1; i++) { l->items[i] = l->items[i+1]; @@ -285,6 +305,7 @@ List_set(DOH *lo, int n, DOH *val) Delete(l->items[n]); l->items[n] = val; Incref(val); + Setscope(val,l->scope); return 0; } @@ -324,6 +345,11 @@ List_str(DOH *lo) List *l = (List *) lo; s = NewString(""); + if (l->flags & DOH_FLAG_PRINT) { + Printf(s,"List(0x%x)",l); + return s; + } + l->flags = l->flags | DOH_FLAG_PRINT; Printf(s,"List[ "); for (i = 0; i < l->nitems; i++) { Printf(s, "%s", l->items[i]); @@ -331,6 +357,7 @@ List_str(DOH *lo) Printf(s,", "); } Printf(s," ]\n"); + l->flags = l->flags & ~DOH_FLAG_PRINT; return s; } @@ -341,7 +368,7 @@ List_dump(DOH *lo, DOH *out) { List *l = (List *) lo; for (i = 0; i < l->nitems; i++) { ret = Dump(l->items[i],out); - if (ret < 0) ret; + if (ret < 0) return -1; nsent += ret; } return nsent; diff --git a/SWIG/Source/DOH/Doh/memory.c b/SWIG/Source/DOH/Doh/memory.c index 9cb134472..9e2f502ae 100644 --- a/SWIG/Source/DOH/Doh/memory.c +++ b/SWIG/Source/DOH/Doh/memory.c @@ -16,17 +16,23 @@ #include "dohint.h" #ifndef DOH_POOL_SIZE -#define DOH_POOL_SIZE 65536 +#define DOH_POOL_SIZE 128000 #endif #ifndef DOH_MAX_FRAG #define DOH_MAX_FRAG 1024 #endif +#ifndef DOH_MAX_SCOPES +#define DOH_MAX_SCOPES 256 +#endif + static int _DohMemoryCurrent = 0; static int _DohMemoryHigh = 0; static int _PoolSize = DOH_POOL_SIZE; +DOH *DohNone = 0; + /* ----------------------------------------------------------------------------- * memory.c * @@ -51,6 +57,9 @@ typedef struct pool { static Pool *Pools = 0; static int pools_initialized = 0; +static DohBase *scopes[DOH_MAX_SCOPES]; +static int nscopes = 0; + /* ---------------------------------------------------------------------- * Pool *CreatePool(int size) @@ -87,6 +96,12 @@ static void InitPools() { } Pools = CreatePool(_PoolSize); /* Create initial pool */ pools_initialized = 1; + for (i = 0; i < DOH_MAX_SCOPES; i++) { + scopes[i] = 0; + } + DohNewScope(); /* Initialize the scope system */ + DohNone = NewVoid(0,0); + DohIntern(DohNone); } /* ---------------------------------------------------------------------- @@ -125,6 +140,122 @@ int DohObjFreeCheck(DOH *ptr) { return 0; } +/* ---------------------------------------------------------------------- + * int DohNewScope() + * + * Create a new scope in which objects will be placed + * ---------------------------------------------------------------------- */ +int DohNewScope() +{ + assert(nscopes < DOH_MAX_SCOPES); + if (!pools_initialized) InitPools(); + scopes[nscopes] = 0; + nscopes++; + return nscopes - 1; +} + +/* ---------------------------------------------------------------------- + * void DohDelScope(int s) - Delete scope s + * ---------------------------------------------------------------------- */ + +void DohDelScope(int s) +{ + int ns; + DohBase *b, *b1; + ns = s; + assert((s >= 0) && (s < nscopes)); + s = nscopes - 1; + while (s >= ns) { + b = scopes[s]; + b1 = 0; + while (b) { + if (s <= b->scope) { + if (!(b->flags & DOH_FLAG_DELSCOPE)) { + Delete(b); + b->flags = b->flags | DOH_FLAG_DELSCOPE; + } + } + b1 = b; + b = (DohBase *) (b->nextptr); + } + if (ns > 0) { /* Add objects to highest non-deleted scope */ + if (b1) { + b1->nextptr = (DOH *) scopes[ns-1]; + scopes[ns-1] = (DohBase *) scopes[s]; + } + } + scopes[s] = 0; + s--; + } + nscopes = ns; +} + +/* ---------------------------------------------------------------------- + * void real_objfree(DOH *ptr) - Free a DOH object for real. + * ---------------------------------------------------------------------- */ +static void real_objfree(DOH *ptr) { + DohBase *b; + Fragment *f; + b = (DohBase *) ptr; + + if (!b->objinfo) { + DohError(DOH_MEMORY,"DohObjFree. %x not properly defined. No objinfo structure.\n", ptr); + return; /* Improperly initialized object. leak some more */ + } + f = (Fragment *) DohMalloc(sizeof(Fragment)); + f->ptr = (char *) ptr; + f->len = (b->objinfo->objsize + 7) & ~0x07; + f->next = FreeFragments[f->len]; + FreeFragments[f->len] = f; + +} + +/* ---------------------------------------------------------------------- + * void DohGarbageCollect() + * + * This walks through all of the scopes and does garbage collection. + * + * 1. Objects with refcount <= 0 are released. + * 2. The scopes data structures are rebuilt and compacted. + * ---------------------------------------------------------------------- */ + +void +DohGarbageCollect() { + int s; + DohBase *b, *b1; + int ndeleted = 1; + + DohError(DOH_MEMORY,"Garbage collecting.\n"); + while (ndeleted) { + ndeleted = 0; + s = nscopes - 1; + while (s >= 0) { + b = scopes[s]; + b1 = 0; + while (b) { + if ((b->refcount <= 0)) { + if (b1) { + b1->nextptr = b->nextptr; + } else { + scopes[s] = b->nextptr; + } + if (!(b->flags & DOH_FLAG_INTERN)) { + assert(!(b->flags & DOH_FLAG_GC)); + real_objfree(b); /* Release the object */ + b->flags = b->flags | DOH_FLAG_GC; + } + ndeleted++; + } else { + b1 = b; + } + b = (DohBase *) b->nextptr; + } + s--; + } + } + DohError(DOH_MEMORY,"Done garbage collecting.\n"); +} + /* ---------------------------------------------------------------------- * void *DohObjMalloc(size_t size) * @@ -135,26 +266,50 @@ void *DohObjMalloc(size_t size) { Pool *p; Fragment *f; void *ptr = 0; + int garbage_collected = 0; if (size > DOH_MAX_FRAG) return 0; if (!pools_initialized) InitPools(); + /* adjust the size for double word alignment */ + size = (size + 7) & ~0x07; + + retry: p = Pools; f = FreeFragments[size]; if (f) { ptr = (void *) f->ptr; FreeFragments[size] = f->next; DohFree(f); + DohInit(ptr); + if (nscopes) { + ((DohBase *) ptr)->scope = nscopes-1; + ((DohBase *) ptr)->nextptr = scopes[nscopes-1]; + scopes[nscopes-1] = (DohBase *) ptr; + } return ptr; } /* No free fragments. See if the pool is large enough */ - if (size < (p->len - p->current)) { + if ((int) size < (p->len - p->current)) { ptr = (void *) (p->ptr + p->current); - p->current = (p->current + size + 7) & ~0x3; + /* p->current = (p->current + size + 7) & ~0x3; */ + p->current = p->current + size; + DohInit(ptr); + if (nscopes) { + ((DohBase *) ptr)->scope = nscopes-1; + ((DohBase *) ptr)->nextptr = scopes[nscopes-1]; + scopes[nscopes-1] = (DohBase *) ptr; + } return ptr; } + if (!garbage_collected) { + garbage_collected = 1; + DohGarbageCollect(); + goto retry; + } + /* Pool is not large enough. Create a new pool */ if (p->len - p->current > 0) { f = (Fragment *) DohMalloc(sizeof(Fragment)); @@ -174,15 +329,11 @@ void *DohObjMalloc(size_t size) { /* ---------------------------------------------------------------------- * void DohObjFree(DOH *ptr) * - * Free a DOH object. Important! It must be a properly allocated - * DOH object. Not something else. + * Free a DOH object. This function doesn't do much of anything with GC. * ---------------------------------------------------------------------- */ void DohObjFree(DOH *ptr) { DohBase *b; - Fragment *f; - extern int doh_debug_level; - if (!DohCheck(ptr)) { DohError(DOH_MEMORY,"DohObjFree. %x not a DOH object!\n", ptr); @@ -193,11 +344,6 @@ void DohObjFree(DOH *ptr) { DohError(DOH_MEMORY,"DohObjFree. %x not properly defined. No objinfo structure.\n", ptr); return; /* Improperly initialized object. leak some more */ } - f = (Fragment *) DohMalloc(sizeof(Fragment)); - f->ptr = (char *) ptr; - f->len = b->objinfo->objsize; - f->next = FreeFragments[f->len]; - FreeFragments[f->len] = f; } /* ----------------------------------------------------------------------------- @@ -245,10 +391,10 @@ void *DohRealloc(void *ptr, size_t newsize) { void DohFree(void *ptr) { char *cptr = (char *) ptr; int size; + if (!ptr) return; size = *((int *) (cptr - 8)); free(cptr-8); _DohMemoryCurrent = _DohMemoryCurrent - (size+8); - /* printf("Free %x %d\n", ptr, size);*/ } /* ----------------------------------------------------------------------------- @@ -273,3 +419,12 @@ int DohPoolSize(int poolsize) { } return ps; } + + + + + + + + + diff --git a/SWIG/Source/DOH/Doh/string.c b/SWIG/Source/DOH/Doh/string.c index 38ec03337..701f9b3a0 100644 --- a/SWIG/Source/DOH/Doh/string.c +++ b/SWIG/Source/DOH/Doh/string.c @@ -56,7 +56,9 @@ int String_putc(DOH *s, int ch); int String_ungetc(DOH *s, int ch); int String_seek(DOH *s, long offset, int whence); long String_tell(DOH *s); - +int String_replace(DOH *str, DOH *token, DOH *rep, int flags); +void String_chop(DOH *str); + static DohSequenceMethods StringSeqMethods = { 0, /* doh_getitem */ 0, /* doh_setitem */ @@ -77,12 +79,17 @@ static DohFileMethods StringFileMethods = { 0, }; +static DohStringMethods StringStringMethods = { + String_replace, +}; + static DohObjInfo StringType = { "String", /* objname */ sizeof(String), /* objsize */ DelString, /* doh_del */ CopyString, /* doh_copy */ String_clear, /* doh_clear */ + 0, /* doh_scope */ String_str, /* doh_str */ String_data, /* doh_data */ String_dump, /* doh_dump */ @@ -93,7 +100,7 @@ static DohObjInfo StringType = { 0, /* doh_mapping */ &StringSeqMethods, /* doh_sequence */ &StringFileMethods,/* doh_file */ - 0, /* doh_string */ + &StringStringMethods, /* doh_string */ 0, /* doh_callable */ }; @@ -139,10 +146,9 @@ int String_dump(DOH *so, DOH *out) { DOH * NewString(char *s) { - int l, max; + int l = 0, max; String *str; str = (String *) DohObjMalloc(sizeof(String)); - DohInit(str); str->objinfo = &StringType; str->hashkey = -1; str->sp = 0; @@ -172,11 +178,10 @@ NewString(char *s) DOH * CopyString(DOH *so) { String *s; - int l, max; + int max; String *str; s = (String *) so; str = (String *) DohObjMalloc(sizeof(String)); - DohInit(str); str->objinfo = &StringType; str->hashkey = -1; str->sp = 0; @@ -200,7 +205,9 @@ DelString(DOH *so) { String *s; s = (String *) so; assert(s->refcount <= 0); - DohFree(s->str); + if (s->str) + DohFree(s->str); + s->str = 0; DohObjFree(s); } @@ -240,7 +247,7 @@ String_cmp(DOH *so1, DOH *so2) { String *s1, *s2; char *c1, *c2; - int maxlen,i,ret; + int maxlen,i; s1 = (String *) so1; s2 = (String *) so2; maxlen = s1->len; @@ -284,7 +291,7 @@ int String_hash(DOH *so) { static void add(String *s, const char *newstr) { - int newlen, newmaxsize, l; + int newlen, newmaxsize, l, i; if (!newstr) return; s->hashkey = -1; l = (int) strlen(newstr); @@ -292,47 +299,39 @@ add(String *s, const char *newstr) { if (newlen >= s->maxsize-1) { newmaxsize = 2*s->maxsize; if (newlen >= newmaxsize -1) newmaxsize = newlen + 1; - assert(s->str = (char *) DohRealloc(s->str,newmaxsize)); + s->str = (char *) DohRealloc(s->str,newmaxsize); + assert(s->str); s->maxsize = newmaxsize; } strcpy(s->str+s->len,newstr); - if (s->sp >= s->len) - s->sp+=l; - s->len += l; -} - -static void -addstr(String *s, String *s1) { - int newlen, newmaxsize, l; - s->hashkey = -1; - l = s1->len; - newlen = s->len+l + 1; - if (newlen >= s->maxsize-1) { - newmaxsize = 2*s->maxsize; - if (newlen >= newmaxsize -1) newmaxsize = newlen + 1; - assert(s->str = (char *) DohRealloc(s->str,newmaxsize)); - s->maxsize = newmaxsize; + if (s->sp >= s->len) { +#ifdef DOH_STRING_UPDATE_LINES + for (i = s->sp; i < s->len+l; i++) { + if (s->str[i] == '\n') s->line++; + } +#endif + s->sp = s->len+l; } - memmove(s->str+s->len,s1->str,s1->len); - if (s->sp >= s->len) s->sp+=l; s->len += l; } - /* Add a single character to s */ - void String_addchar(DOH *so, char c) { String *s = (String *) so; s->hashkey = -1; if ((s->len+1) > (s->maxsize-1)) { - assert(s->str = (char *) DohRealloc(s->str,2*s->maxsize)); + s->str = (char *) DohRealloc(s->str,2*s->maxsize); + assert(s->str); s->maxsize *= 2; } s->str[s->len] = c; if (s->sp >= s->len) { - s->sp++; + s->sp = s->len+1; s->str[s->len+1] = 0; +#ifdef DOH_STRING_UPDATE_LINES + if (c == '\n') s->line++; +#endif } s->len++; } @@ -341,7 +340,8 @@ String_addchar(DOH *so, char c) { void String_expand(String *s, int width) { if ((s->len + width) > (s->maxsize-1)) { - assert(s->str = (char *) DohRealloc(s->str,(s->len + width)+1)); + s->str = (char *) DohRealloc(s->str,(s->len + width)+1); + assert(s->str); s->maxsize = s->len + width + 1; } } @@ -357,7 +357,7 @@ String_clear(DOH *so) s = (String *) so; s->hashkey = -1; s->len = 0; - s->str[0] = 0; + *(s->str) = 0; s->sp = 0; s->lsp = 0; s->line = 1; @@ -380,11 +380,22 @@ raw_insert(String *s, int pos, char *data, int len) /* See if there is room to insert the new data */ while (s->maxsize <= s->len+len) { - assert(s->str = (char *) DohRealloc(s->str,2*s->maxsize)); + s->str = (char *) DohRealloc(s->str,2*s->maxsize); + assert(s->str); s->maxsize *= 2; } memmove(s->str+pos+len, s->str+pos, (s->len - pos)); memcpy(s->str+pos,data,len); + if (s->sp >= s->len) { + int i; + s->sp = s->len; +#ifdef DOH_STRING_UPDATE_LINES + for (i = 0; i < len; i++) { + if (data[i] == '\n') s->line++; + } +#endif + s->sp+=len; + } s->len += len; s->str[s->len] = 0; } @@ -399,7 +410,7 @@ String_insert(DOH *so, int pos, DOH *str) char *c; int len; s = (String *) so; - assert(s->refcount <= 1); + /* assert(s->refcount <= 1); */ s1 = (String *) str; len = s1->len; c = s1->str; @@ -419,9 +430,14 @@ int String_delitem(DOH *so, int pos) s->hashkey = -1; if (pos == DOH_END) pos = s->len-1; if (pos == DOH_BEGIN) pos = 0; + if (s->len == 0) return 0; - if (s->len == 0) return; - + if (s->sp > pos) { + s->sp--; +#ifdef DOH_STRING_UPDATE_LINES + if (s->str[pos] == '\n') s->line--; +#endif + } memmove(s->str+pos, s->str+pos+1, ((s->len-1) - pos)); s->len--; s->str[s->len] = 0; @@ -448,10 +464,10 @@ String_str(DOH *so) { int String_read(DOH *so, void *buffer, int len) { int reallen, retlen; - int i; char *cb; String *s = (String *) so; if (((s->sp-s->pbi) + len) > s->len) reallen = (s->len - (s->sp-s->pbi)); + else reallen = len; cb = (char *) buffer; retlen = reallen; @@ -476,12 +492,13 @@ String_read(DOH *so, void *buffer, int len) { * ----------------------------------------------------------------------------- */ int String_write(DOH *so, void *buffer, int len) { - int reallen, newlen, newmaxsize; + int newlen; String *s = (String *) so; s->hashkey = -1; newlen = s->sp + len+1; if (newlen > s->maxsize) { - assert(s->str = (char *) DohRealloc(s->str,newlen)); + s->str = (char *) DohRealloc(s->str,newlen); + assert(s->str); s->maxsize = newlen; s->len = s->sp + len; } @@ -499,23 +516,34 @@ String_write(DOH *so, void *buffer, int len) { * ----------------------------------------------------------------------------- */ int String_seek(DOH *so, long offset, int whence) { - int pos; + int pos, nsp, inc; String *s = (String *) so; if (whence == SEEK_SET) pos = 0; - if (whence == SEEK_CUR) pos = s->sp; - if (whence == SEEK_END) { + else if (whence == SEEK_CUR) pos = s->sp; + else if (whence == SEEK_END) { pos = s->len; offset = -offset; } - s->sp = pos + offset; - if (s->sp < 0) s->sp = 0; - if (s->sp > s->len) s->sp = s->len; + else pos = s->sp; + + nsp = pos + offset; + if (nsp < 0) nsp = 0; + if (nsp > s->len) nsp = s->len; + if (nsp > s->sp) inc = 1; + else inc = -1; +#ifdef DOH_STRING_UPDATE_LINES + while (s->sp != nsp) { + if (s->str[s->sp-1] == '\n') s->line += inc; + s->sp += inc; + } +#endif + s->sp = nsp; s->pbi = 0; return 0; } /* ----------------------------------------------------------------------------- - * long String_seek(DOH *so) + * long String_tell(DOH *so) * * Return current position * ----------------------------------------------------------------------------- */ @@ -540,6 +568,9 @@ String_putc(DOH *so, int ch) { } else { s->str[s->sp] = (char) ch; s->sp++; +#ifdef DOH_STRING_UPDATE_LINES + if (ch == '\n') s->line++; +#endif } s->pbi = 0; return ch; @@ -548,28 +579,30 @@ String_putc(DOH *so, int ch) { /* ----------------------------------------------------------------------------- * int String_getc(DOH *so) * - * Get a character from the string + * Get a character from the string. Updates the line number. * ----------------------------------------------------------------------------- */ int String_getc(DOH *so) { + int c; String *s = (String *) so; if (s->pbi) { - return (int) s->pb[--s->pbi]; - } - if (s->sp >= s->len) return EOF; - else return (int) s->str[s->sp++]; + c = (int) s->pb[--s->pbi]; + } else if (s->sp >= s->len) c = EOF; + else c = (int) s->str[s->sp++]; +#ifdef DOH_STRING_UPDATE_LINES + if (c == '\n') s->line++; +#endif + return c; } /* ----------------------------------------------------------------------------- * int String_ungetc(DOH *so, int ch) * - * Put a character back on to the input stream. + * Put a character back on to the input stream. Updates the line count. * ----------------------------------------------------------------------------- */ - int String_ungetc(DOH *so, int ch) { String *s = (String *) so; - int i; if (ch == EOF) return ch; if ((s->sp - s->pbi) <= 0) return EOF; if (s->pbi == 4) { @@ -580,11 +613,14 @@ int String_ungetc(DOH *so, int ch) { } else { s->pb[s->pbi++] = (char) ch; } +#ifdef DOH_STRING_UPDATE_LINES + if (ch == '\n') s->line--; +#endif return ch; } /* ----------------------------------------------------------------------------- - * static void replace_internal(String *str, char *token, char *rep, int flags, char *start, int count) + * int replace_internal(String *str, char *token, char *rep, int flags, char *start, int count) * * Replaces token with rep. flags is as follows: * @@ -596,11 +632,13 @@ int String_ungetc(DOH *so, int ch) { * start is a starting position. count is a count. * ----------------------------------------------------------------------------- */ -void replace_internal(String *str, char *token, char *rep, int flags, char *start, int count) +static +int replace_internal(String *str, char *token, char *rep, int flags, char *start, int count) { char *s, *c, *t; int tokenlen; int state; + int repcount = 0; /* Copy the current string representation */ @@ -646,6 +684,7 @@ void replace_internal(String *str, char *token, char *rep, int flags, char *star c += (tokenlen-1); t = c+1; count--; + repcount++; } } else if (isalpha(*c) || (*c == '_') || (*c == '$')) { char temp = *c; @@ -668,6 +707,7 @@ void replace_internal(String *str, char *token, char *rep, int flags, char *star if (strcmp(token,t) == 0) { add(str,rep); count--; + repcount++; } else { add(str,t); } @@ -698,20 +738,50 @@ void replace_internal(String *str, char *token, char *rep, int flags, char *star } DohFree(s); } + return repcount; } /* ----------------------------------------------------------------------------- - * void String_replace(DOH *str, DOH *token, DOH *rep, int flags) + * int String_replace(DOH *str, DOH *token, DOH *rep, int flags) * ----------------------------------------------------------------------------- */ -void +int String_replace(DOH *stro, DOH *token, DOH *rep, int flags) { int count = -1; String *str; - if (!String_check(stro)) return; + if (!String_check(stro)) return 0; str = (String *) stro; - assert(!str->refcount); + assert(str->refcount); + /* assert(!str->refcount); */ if (flags & DOH_REPLACE_FIRST) count = 1; - replace_internal(str,Char(token),Char(rep),flags,str->str,count); + return replace_internal(str,Char(token),Char(rep),flags,str->str,count); } + +/* ----------------------------------------------------------------------------- + * void String_chop(DOH *str) + * ----------------------------------------------------------------------------- */ + +void +String_chop(DOH *s) { + char *c; + String *str = (String *) s; + if (!String_check(s)) return; + /* assert(!str->refcount); */ + + /* Replace trailing whitespace */ + c = str->str + str->len - 1; + while ((str->len >= 0) && (isspace(*c))) { + if (str->sp >= str->len) { + str->sp--; +#ifdef DOH_STRING_UPDATE_LINES + if (*c == '\n') str->line--; +#endif + } + str->len--; + c--; + } + str->hashkey = -1; + str->pbi = 0; +} + diff --git a/SWIG/Source/DOH/Doh/void.c b/SWIG/Source/DOH/Doh/void.c index 82ee1052d..2df3a398f 100644 --- a/SWIG/Source/DOH/Doh/void.c +++ b/SWIG/Source/DOH/Doh/void.c @@ -37,6 +37,7 @@ static DohObjInfo DohVoidType = { Void_delete, /* doh_del */ Void_copy, /* doh_copy */ 0, /* doh_clear */ + 0, /* doh_scope */ 0, /* doh_str */ Void_data, /* doh_data */ 0, /* doh_dump */ @@ -62,7 +63,6 @@ static DohObjInfo DohVoidType = { DOH *NewVoid(void *obj, void (*del)(void *)) { VoidObj *v; v = (VoidObj *) DohObjMalloc(sizeof(VoidObj)); - DohInit(v); v->objinfo = &DohVoidType; v->ptr = obj; v->del = del; @@ -74,6 +74,7 @@ void Void_delete(DOH *vo) { if (v->del) { (*v->del)(v->ptr); } + v->del = 0; DohObjFree(v); } diff --git a/SWIG/Source/DOH/Include/doh.h b/SWIG/Source/DOH/Include/doh.h index 8974bf6e6..95d821c49 100644 --- a/SWIG/Source/DOH/Include/doh.h +++ b/SWIG/Source/DOH/Include/doh.h @@ -103,6 +103,7 @@ typedef struct DohObjInfo { void (*doh_del)(DOH *obj); /* Delete object */ DOH *(*doh_copy)(DOH *obj); /* Copy and object */ void (*doh_clear)(DOH *obj); /* Clear an object */ + void (*doh_scope)(DOH *obj, int s); /* Change the scope on an object */ /* Output methods */ DOH *(*doh_str)(DOH *obj); /* Make a full string */ @@ -133,6 +134,7 @@ typedef struct DohObjInfo { /* Memory management */ extern void *DohMalloc(size_t size); +extern void *DohRealloc(void *, size_t size); extern void *DohObjMalloc(size_t size); extern void DohFree(DOH *ptr); extern void DohObjFree(DOH *ptr); @@ -142,6 +144,11 @@ extern int DohFreeCheck(DOH *ptr); extern int DohMemoryUse(); extern int DohMemoryHigh(); extern int DohPoolSize(int); +extern int DohNewScope(); +extern void DohDelScope(int); +extern void DohGarbageCollect(); +extern void DohSetScope(DOH *, int scp); +extern void DohIntern(DOH *); /* Low-level doh methods. Do not call directly (well, unless you want to). */ extern void DohError(int level, char *fmt,...); @@ -184,7 +191,7 @@ extern void DohSetDouble(DOH *obj, DOH *name, double); extern int DohWrite(DOH *obj, void *buffer, int length); extern int DohRead(DOH *obj, void *buffer, int length); -extern int DohSeek(DOH *obj, long offser, int whence); +extern int DohSeek(DOH *obj, long offset, int whence); extern long DohTell(DOH *obj); extern int DohGetc(DOH *obj); extern int DohPutc(int ch, DOH *obj); @@ -196,6 +203,7 @@ extern int DohvPrintf(DOH *obj, char *format, va_list ap); /* extern int DohScanf(DOH *obj, char *format, ...); extern int DohvScanf(DOH *obj, char *format, va_list ap); */ +extern int DohReplace(DOH *src, DOH *token, DOH *rep, int flags); extern DOH *DohReadline(DOH *in); #ifndef DOH_LONG_NAMES @@ -247,6 +255,9 @@ extern DOH *DohReadline(DOH *in); #define Firstitem DohFirstitem #define Nextitem DohNextitem #define Readline DohReadline +#define Replace DohReplace +#define NewScope DohNewScope +#define DelScope DohDelScope #endif @@ -258,8 +269,11 @@ extern DOH *DohReadline(DOH *in); #define DOHCOMMON \ DohObjInfo *objinfo; \ + DOH *nextptr; \ int refcount; \ - int line; \ + short line; \ + unsigned char flags; \ + unsigned char scope; \ DOH *file typedef struct { @@ -267,17 +281,31 @@ typedef struct { } 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 Decref(a) if (a) ((DohBase *) a)->refcount-- +#define Incref(a) if (a) ((DohBase *) a)->refcount++ +#define Refcount(a) ((DohBase *) a)->refcount + +#define Getscope(a) ((DohBase *) a)->scope +#define Setscope(a,s) DohSetScope(a,s) + #define Objname(a) ((DohBase *) a)->objinfo->objname +/* Flags for various internal operations */ + +#define DOH_FLAG_SETSCOPE 0x01 +#define DOH_FLAG_PRINT 0x02 +#define DOH_FLAG_DELSCOPE 0x04 +#define DOH_FLAG_GC 0x08 +#define DOH_FLAG_INTERN 0x10 + /* ----------------------------------------------------------------------------- * Strings. * ----------------------------------------------------------------------------- */ extern DOH *NewString(char *c); extern int String_check(DOH *s); -extern void String_replace(DOH *s, DOH *token, DOH *rep, int flags); +extern int String_replace(DOH *s, DOH *token, DOH *rep, int flags); +extern void String_chop(DOH *s); /* String replacement flags */ @@ -322,6 +350,8 @@ extern DOH *NewVoid(void *ptr, void (*del)(void *)); extern DOH *DohSplit(DOH *input, char *chs, int nsplits); #define Split DohSplit +extern DOH *DohNone; + /* ----------------------------------------------------------------------------- * Error handling levels. * ----------------------------------------------------------------------------- */