Major changes
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk/SWIG@28 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
parent
34851a45f5
commit
0a3ba3f73d
10 changed files with 532 additions and 160 deletions
|
|
@ -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!
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
****************************************************************************/
|
||||
|
||||
#include "dohint.h"
|
||||
#include <unistd.h>
|
||||
|
||||
/* ---------------------------------------------------------------------------
|
||||
* $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;
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue