diff options
author | Dave Beazley <dave-swig@dabeaz.com> | 1999-08-09 23:02:33 +0000 |
---|---|---|
committer | Dave Beazley <dave-swig@dabeaz.com> | 1999-08-09 23:02:33 +0000 |
commit | bff836ae6a5bf6a8dc3702e9e117bdf72db708f1 (patch) | |
tree | b0114520e866785d70f20a0b5dc90fc4d79269c9 /Source/DOH | |
parent | b199b4a034e24de52b3e41cb3ec8909c8462c609 (diff) | |
download | swig-bff836ae6a5bf6a8dc3702e9e117bdf72db708f1.tar.gz |
*** empty log message ***
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk/SWIG@9 626c5289-ae23-0410-ae9c-e8d60b6d4f22
Diffstat (limited to 'Source/DOH')
-rw-r--r-- | Source/DOH/Doh/Makefile | 4 | ||||
-rw-r--r-- | Source/DOH/Doh/base.c | 156 | ||||
-rw-r--r-- | Source/DOH/Doh/file.c | 57 | ||||
-rw-r--r-- | Source/DOH/Doh/fio.c | 385 | ||||
-rw-r--r-- | Source/DOH/Doh/hash.c | 7 | ||||
-rw-r--r-- | Source/DOH/Doh/list.c | 20 | ||||
-rw-r--r-- | Source/DOH/Doh/string.c | 487 | ||||
-rw-r--r-- | Source/DOH/Include/doh.h | 28 |
8 files changed, 620 insertions, 524 deletions
diff --git a/Source/DOH/Doh/Makefile b/Source/DOH/Doh/Makefile index 02c18a994..28893b757 100644 --- a/Source/DOH/Doh/Makefile +++ b/Source/DOH/Doh/Makefile @@ -24,9 +24,9 @@ AR = ar # Normally, you shouldn't have to change anything below this point # ######################################################################## -LIBOBJS = memory.o base.o file.o list.o hash.o string.o +LIBOBJS = fio.o memory.o base.o file.o list.o hash.o string.o -LIBSRCS = memory.c base.c file.c list.c hash.c string.c +LIBSRCS = fio.c memory.c base.c file.c list.c hash.c string.c LIBHEADERS = ../Include/doh.h LIB = ../libdoh.a diff --git a/Source/DOH/Doh/base.c b/Source/DOH/Doh/base.c index aca790e3e..7262ba762 100644 --- a/Source/DOH/Doh/base.c +++ b/Source/DOH/Doh/base.c @@ -31,6 +31,7 @@ static DohObjInfo DohBaseType = { 0, /* doh_clear */ 0, /* doh_str */ 0, /* doh_data */ + 0, /* doh_dump */ 0, /* doh_len */ 0, /* doh_hash */ 0, /* doh_cmp */ @@ -139,13 +140,24 @@ DOH *DohStr(DOH *obj) { return (b->objinfo->doh_str)(b); } s = NewString("<Object "); - Appendf(s,"'%s' at %x>", b->objinfo->objname, b); + Printf(s,"'%s' at %x>", b->objinfo->objname, b); return s; } else { return NewString(obj); } } +/* Serialize an object */ +int DohDump(DOH *obj, DOH *out) { + DohBase *b = (DohBase *) obj; + if (DohCheck(obj)) { + if (b->objinfo->doh_dump) { + return (b->objinfo->doh_dump)(b,out); + } + } + return 0; +} + /* Get the length */ int DohLen(DOH *obj) { int s; @@ -282,6 +294,7 @@ DOH *DohGetattr(DOH *obj, DOH *name) { return 0; } +#ifdef OLD /* Getattrf */ int DohGetattrf(DOH *obj, DOH *name, char *format, ...) { va_list ap; @@ -299,7 +312,7 @@ int DohGetattrf(DOH *obj, DOH *name, char *format, ...) { } return ret; } - +#endif /* Set an attribute in an object */ int DohSetattr(DOH *obj, DOH *name, DOH *value) { @@ -481,60 +494,6 @@ void DohInsertitem(DOH *obj, int index, DOH *value) { } } -/* Set an item in an object */ -void DohInsertitemf(DOH *obj, int index, char *format, ...) { - va_list ap; - DohBase *b = (DohBase *) obj; - if (DohIsSequence(obj)) { - if (b->objinfo->doh_sequence->doh_insertf) { - va_start(ap,format); - (b->objinfo->doh_sequence->doh_insertf)(obj,index,format,ap); - va_end(ap); - return; - } - printf("No insertf method defined for type '%s'\n", b->objinfo->objname); - } -} - -/* Set an item in an object */ -void DohvInsertitemf(DOH *obj, int index, char *format, va_list ap) { - DohBase *b = (DohBase *) obj; - if (DohIsSequence(obj)) { - if (b->objinfo->doh_sequence->doh_insertf) { - (b->objinfo->doh_sequence->doh_insertf)(obj,index,format,ap); - return; - } - printf("No insertf method defined for type '%s'\n", b->objinfo->objname); - } -} - -/* Append an item to an object */ -void DohAppendf(DOH *obj, char *format, ...) { - va_list ap; - DohBase *b = (DohBase *) obj; - if (DohIsSequence(obj)) { - if (b->objinfo->doh_sequence->doh_insertf) { - va_start(ap,format); - (b->objinfo->doh_sequence->doh_insertf)(obj,DOH_END,format,ap); - va_end(ap); - return; - } - printf("No appendf method defined for type '%s'\n", b->objinfo->objname); - } -} - -/* Append an item to an object */ -void DohvAppendf(DOH *obj, char *format, va_list ap) { - DohBase *b = (DohBase *) obj; - if (DohIsSequence(obj)) { - if (b->objinfo->doh_sequence->doh_insertf) { - (b->objinfo->doh_sequence->doh_insertf)(obj,DOH_END,format,ap); - return; - } - printf("No appendf method defined for type '%s'\n", b->objinfo->objname); - } -} - /* ----------------------------------------------------------------------------- * File methods * ----------------------------------------------------------------------------- */ @@ -557,7 +516,7 @@ int DohRead(DOH *obj, void *buffer, int length) { } else { /* Hmmm. Not a file. Maybe it's a real FILE */ if (!DohCheck(b)) { - return fread(buffer,length,1,(FILE *) b); + return fread(buffer,1,length,(FILE *) b); } } return -1; @@ -573,7 +532,7 @@ int DohWrite(DOH *obj, void *buffer, int length) { printf("No write method defined for type '%s'\n", b->objinfo->objname); } else { if (!DohCheck(b)) { - return fwrite(buffer,length,1,(FILE *) b); + return fwrite(buffer,1,length,(FILE *) b); } } return -1; @@ -611,83 +570,52 @@ long DohTell(DOH *obj) { return -1; } -/* Printf */ -int DohPrintf(DOH *obj, char *format, ...) { - va_list ap; - int ret; +/* Getc */ +int DohGetc(DOH *obj) { DohBase *b = (DohBase *) obj; if (DohIsFile(obj)) { - if (b->objinfo->doh_file->doh_printf) { - va_start(ap,format); - ret = (b->objinfo->doh_file->doh_printf)(obj,format,ap); - va_end(ap); - return ret; + if (b->objinfo->doh_file->doh_getc) { + return (b->objinfo->doh_file->doh_getc)(obj); } - printf("No printf method defined for type '%s'\n", b->objinfo->objname); + printf("No getc method defined for type '%s'\n", b->objinfo->objname); } else { - if (!DohCheck(obj)) { - DOH *str; - str = NewString(""); - va_start(ap,format); - DohvAppendf(str,format,ap); - va_end(ap); - ret = fprintf((FILE *) obj, "%s", Data(str)); - Delete(str); - return ret; + if (!DohCheck(b)) { + return fgetc((FILE *) b); } } - return -1; + return EOF; } -/* vPrintf */ -int DohvPrintf(DOH *obj, char *format, va_list ap) { - int ret; +/* Putc */ +int DohPutc(int ch, DOH *obj) { DohBase *b = (DohBase *) obj; if (DohIsFile(obj)) { - if (b->objinfo->doh_file->doh_printf) { - return (b->objinfo->doh_file->doh_printf)(obj,format,ap); + if (b->objinfo->doh_file->doh_putc) { + return (b->objinfo->doh_file->doh_putc)(obj,ch); } - printf("No printf method defined for type '%s'\n", b->objinfo->objname); + printf("No putc method defined for type '%s'\n", b->objinfo->objname); } else { - if (!DohCheck(obj)) { - DOH *str; - str = NewString(""); - DohvAppendf(str,format,ap); - ret = fprintf((FILE *) obj, "%s", Data(str)); - Delete(str); - return ret; + if (!DohCheck(b)) { + return fputc(ch,(FILE *) b); } } - return -1; + return EOF; } -/* Printf */ -int DohScanf(DOH *obj, char *format, ...) { - va_list ap; - int ret; +/* ungetc */ +int DohUngetc(int ch, DOH *obj) { DohBase *b = (DohBase *) obj; if (DohIsFile(obj)) { - if (b->objinfo->doh_file->doh_scanf) { - va_start(ap,format); - ret = (b->objinfo->doh_file->doh_scanf)(obj,format,ap); - va_end(ap); - return ret; + if (b->objinfo->doh_file->doh_ungetc) { + return (b->objinfo->doh_file->doh_ungetc)(obj,ch); } - printf("No scanf method defined for type '%s'\n", b->objinfo->objname); - } - return -1; -} - -/* vPrintf */ -int DohvScanf(DOH *obj, char *format, va_list ap) { - DohBase *b = (DohBase *) obj; - if (DohIsFile(obj)) { - if (b->objinfo->doh_file->doh_scanf) { - return (b->objinfo->doh_file->doh_scanf)(obj,format,ap); + printf("No ungetc method defined for type '%s'\n", b->objinfo->objname); + } else { + if (!DohCheck(b)) { + return ungetc(ch,(FILE *) b); } - printf("No scanf method defined for type '%s'\n", b->objinfo->objname); } - return -1; + return EOF; } int DohClose(DOH *obj) { diff --git a/Source/DOH/Doh/file.c b/Source/DOH/Doh/file.c index 1d93bf1df..3d768f342 100644 --- a/Source/DOH/Doh/file.c +++ b/Source/DOH/Doh/file.c @@ -33,16 +33,22 @@ typedef struct File { void DelFile(DOH *s); int File_read(DOH *s, void *buffer, int length); int File_write(DOH *s, void *buffer, int length); +int File_putc(DOH *s, int ch); +int File_getc(DOH *s); +int File_ungetc(DOH *s, int ch); int File_seek(DOH *s, long offset, int whence); long File_tell(DOH *s); -int File_printf(DOH *s, char *fmt, va_list ap); + static DohFileMethods FileFileMethods = { - File_read, + File_read, File_write, + File_putc, + File_getc, + File_ungetc, File_seek, File_tell, - File_printf, + 0, }; static DohObjInfo FileType = { @@ -53,6 +59,7 @@ static DohObjInfo FileType = { 0, /* sm_clear */ 0, /* sm_str */ 0, /* doh_data */ + 0, /* doh_dump */ 0, /* sm_len */ 0, /* sm_hash */ 0, /* doh_cmp */ @@ -143,7 +150,7 @@ File_check(DOH *f) int File_read(DOH *so, void *buffer, int len) { File *s = (File *) so; - return (size_t) fread(buffer,len,1,s->filep); + return (size_t) fread(buffer,1,len,s->filep); } /* ----------------------------------------------------------------------------- @@ -154,7 +161,7 @@ File_read(DOH *so, void *buffer, int len) { int File_write(DOH *so, void *buffer, int len) { File *s = (File *) so; - return (size_t) fwrite(buffer,len,1,s->filep); + return (size_t) fwrite(buffer,1,len,s->filep); } /* ----------------------------------------------------------------------------- @@ -180,22 +187,36 @@ File_tell(DOH *so) { } /* ----------------------------------------------------------------------------- - * int File_printf(DOH *so, char *format, ...) + * int File_putc(DOH *obj, int ch) * + * Put a character on the output * ----------------------------------------------------------------------------- */ -int -File_printf(DOH *so, char *format, va_list ap) -{ - int len, wlen; - DOH *nso; - File *s = (File *) so; - nso = NewString(""); - vAppendf(nso,format,ap); - len = Len(nso); - wlen = File_write(so,Data(nso),len); - Delete(nso); - return wlen; +int File_putc(DOH *obj, int ch) { + File *s = (File *) obj; + return fputc(ch,s->filep); +} + +/* ----------------------------------------------------------------------------- + * int File_getc(DOH *obj) + * + * Get a character + * ----------------------------------------------------------------------------- */ + +int File_getc(DOH *obj) { + File *s = (File *) obj; + return fgetc(s->filep); +} + +/* ----------------------------------------------------------------------------- + * int File_ungetc(DOH *obj, int ch) + * + * Put a character back onto the input + * ----------------------------------------------------------------------------- */ + +int File_ungetc(DOH *obj, int ch) { + File *s = (File *) obj; + return ungetc(ch, s->filep); } diff --git a/Source/DOH/Doh/fio.c b/Source/DOH/Doh/fio.c new file mode 100644 index 000000000..809147da9 --- /dev/null +++ b/Source/DOH/Doh/fio.c @@ -0,0 +1,385 @@ +/**************************************************************************** + * DOH (Dynamic Object Hack) + * + * Author : David Beazley + * + * Department of Computer Science + * University of Chicago + * 1100 E 58th Street + * Chicago, IL 60637 + * beazley@cs.uchicago.edu + * + * Please read the file LICENSE for the copyright and terms by which SWIG + * can be used and distributed. + ****************************************************************************/ + +#include "doh.h" + +/* ----------------------------------------------------------------------------- + * fio.c + * + * Support for formatted I/O via fprintf, fscanf. + * ----------------------------------------------------------------------------- */ + +/* ----------------------------------------------------------------------------- + * DohvPrintf(DOH *so, char *format, va_list ap) + * + * printf + * ----------------------------------------------------------------------------- */ + +int +DohvPrintf(DOH *so, char *format, va_list ap) +{ + static char *fmt_codes = "dioxXucsSfeEgGpnbB"; + int state = 0; + char *p = format; + char newformat[256]; + char *fmt; + char temp[64]; + int widthval = 0; + int precval = 0; + int maxwidth; + char *w, *prec; + int ivalue; + int dvalue; + + while (*p) { + switch(state) { + case 0: /* Ordinary text */ + if (*p != '%') { + Putc(*p,so); + } else{ + fmt = newformat; + widthval = 0; + precval = 0; + *(fmt++) = *p; + state = 10; + } + break; + case 10: /* Look for a width and precision */ + if (isdigit(*p) && (*p != '0')) { + w = temp; + *(w++) = *p; + *(fmt++) = *p; + state = 20; + } else if (strchr(fmt_codes,*p)) { + /* Got one of the formatting codes */ + p--; + state = 100; + } else if (*p == '*') { + /* Width field is specified in the format list */ + widthval = va_arg(ap,int); + sprintf(temp,"%d",widthval); + for (w = temp; *w; w++) { + *(fmt++) = *w; + } + state = 30; + } else if (*p == '%') { + Putc(*p,so); + fmt = newformat; + state = 0; + } else { + *(fmt++) = *p; + } + break; + + case 20: /* Hmmm. At the start of a width field */ + if (isdigit(*p)) { + *(w++) = *p; + *(fmt++) = *p; + } else if (strchr(fmt_codes,*p)) { + /* Got one of the formatting codes */ + /* Figure out width */ + *w = 0; + widthval = atoi(temp); + p--; + state = 100; + } else if (*p == '.') { + *w = 0; + widthval = atoi(temp); + w = temp; + *(fmt++) = *p; + state = 40; + } else { + /* ??? */ + *w = 0; + widthval = atoi(temp); + state = 50; + } + break; + + case 30: /* Parsed a width from an argument. Look for a . */ + if (*p == '.') { + w = temp; + *(fmt++) = *p; + state = 40; + } else if (strchr(fmt_codes,*p)) { + /* Got one of the formatting codes */ + /* Figure out width */ + p--; + state = 100; + } else { + /* hmmm. Something else. */ + state = 50; + } + break; + + case 40: + /* Start of precision expected */ + if (isdigit(*p) && (*p != '0')) { + *(fmt++) = *p; + *(w++) = *p; + state = 41; + } else if (*p == '*') { + /* Precision field is specified in the format list */ + precval = va_arg(ap,int); + sprintf(temp,"%d",precval); + for (w = temp; *w; w++) { + *(fmt++) = *w; + } + state = 50; + } else if (strchr(fmt_codes,*p)) { + p--; + state = 100; + } else { + *(fmt++) = *p; + state = 50; + } + break; + case 41: + if (isdigit(*p)) { + *(fmt++) = *p; + *(w++) = *p; + } else if (strchr(fmt_codes,*p)) { + /* Got one of the formatting codes */ + /* Figure out width */ + *w = 0; + precval = atoi(temp); + p--; + state = 100; + } else { + *w = 0; + precval = atoi(temp); + *(fmt++) = *p; + state = 50; + } + break; + /* Hang out, wait for format specifier */ + case 50: + if (strchr(fmt_codes,*p)) { + p--; + state = 100; + } else { + *(fmt++) = *p; + } + break; + case 100: + /* Got a formatting code */ + if (widthval < precval) maxwidth = precval; + else maxwidth = widthval; + if ((*p == 's') || (*p == 'S')) { /* Null-Terminated string */ + DOH *doh; + DOH *Sval; + char *temps; + doh = va_arg(ap, DOH *); + if (DohCheck(doh)) { + /* Is an object at least */ + if (String_check(doh)) { + Sval = doh; + } else { + Sval = Str(doh); + } + maxwidth = maxwidth+strlen(newformat)+Len(Sval); + *(fmt++) = 's'; + *fmt = 0; + temps = (char *) malloc(maxwidth+1); + sprintf(temps,newformat,Data(Sval)); + Write(so,temps,strlen(temps)); + if ((DOH *) Sval != doh) { + Delete(Sval); + } + if (*p == 'S') { + Delete(doh); + } + free(temps); + } else { + maxwidth = maxwidth+strlen(newformat)+strlen((char *) doh); + *(fmt++) = 's'; + *fmt = 0; + temps = (char *) malloc(maxwidth+1); + sprintf(temps,newformat,doh); + free(temps); + } + } else { + int ivalue; + double dvalue; + void *pvalue; + char *stemp; + *(fmt++) = *p; + *fmt = 0; + maxwidth = maxwidth+strlen(newformat)+64; + stemp = (char *) malloc(maxwidth+1); + switch(*p) { + case 'd': + case 'i': + case 'o': + case 'u': + case 'x': + case 'X': + case 'c': + ivalue = va_arg(ap,int); + sprintf(stemp,newformat,ivalue); + break; + case 'f': + case 'g': + case 'e': + case 'E': + case 'G': + dvalue = va_arg(ap,double); + sprintf(stemp,newformat,dvalue); + break; + case 'p': + pvalue = va_arg(ap,void *); + sprintf(stemp,newformat,pvalue); + break; + default: + break; + } + Write(so,stemp,strlen(stemp)); + free(stemp); + } + state = 0; + break; + } + p++; + } + if (state) { + *fmt = 0; + Write(so,fmt,strlen(fmt)); + } + return 1; +} + +/* Printf */ +int DohPrintf(DOH *obj, char *format, ...) { + va_list ap; + int ret; + va_start(ap,format); + ret = DohvPrintf(obj,format,ap); + va_end(ap); + return ret; +} + +#ifdef OLD + +/* ---------------------------------------------------------------------- + * int String_scanfv(DOH *doh, char *format, va_list ap) + * + * Do a string scanf. Somewhat broken compared to C scanf. + * ---------------------------------------------------------------------- */ + +int String_scanfv(DOH *doh, char *format, va_list ap) { + static char *fmt_chars = "diouxcsefgp"; + String *s; + char newformat[256]; + char *fmt; + char *p; + int state; + void *ptr; + int total = 0; + int i; + + s = (String *) doh; + state = 0; + p = format; + while (*p) { + switch(state) { + case 0: + if (*p == '%') { + fmt = newformat; + *(fmt++) = *p; + state = 10; + } + break; + case 10: + if (strchr(fmt_chars,*p)) { + int len; + *(fmt++) = *p; + *fmt = 0; + ptr = va_arg(ap, void *); + len = sscanf(s->str+s->sp,newformat,ptr); + for (i = 0; i < len; i++) { + while (s->sp < s->len) { + if (!isspace(s->str[s->sp])) break; + s->sp++; + } + while (s->sp < s->len) { + if (isspace(s->str[s->sp])) break; + s->sp++; + } + } + total += len; + state = 0; + fmt = newformat; + } else { + *(fmt++) = *p; + } + break; + } + p++; + } + return total; +} + +/* vPrintf */ +int DohvPrintf(DOH *obj, char *format, va_list ap) { + int ret; + DohBase *b = (DohBase *) obj; + if (DohIsFile(obj)) { + if (b->objinfo->doh_file->doh_printf) { + return (b->objinfo->doh_file->doh_printf)(obj,format,ap); + } + printf("No printf method defined for type '%s'\n", b->objinfo->objname); + } else { + if (!DohCheck(obj)) { + DOH *str; + str = NewString(""); + DohvAppendf(str,format,ap); + ret = fprintf((FILE *) obj, "%s", Data(str)); + Delete(str); + return ret; + } + } + return -1; +} + +/* Printf */ +int DohScanf(DOH *obj, char *format, ...) { + va_list ap; + int ret; + DohBase *b = (DohBase *) obj; + if (DohIsFile(obj)) { + if (b->objinfo->doh_file->doh_scanf) { + va_start(ap,format); + ret = (b->objinfo->doh_file->doh_scanf)(obj,format,ap); + va_end(ap); + return ret; + } + printf("No scanf method defined for type '%s'\n", b->objinfo->objname); + } + return -1; +} + +/* vPrintf */ +int DohvScanf(DOH *obj, char *format, va_list ap) { + DohBase *b = (DohBase *) obj; + if (DohIsFile(obj)) { + if (b->objinfo->doh_file->doh_scanf) { + return (b->objinfo->doh_file->doh_scanf)(obj,format,ap); + } + printf("No scanf method defined for type '%s'\n", b->objinfo->objname); + } + return -1; +} + +#endif diff --git a/Source/DOH/Doh/hash.c b/Source/DOH/Doh/hash.c index ab1176cea..0011fe716 100644 --- a/Source/DOH/Doh/hash.c +++ b/Source/DOH/Doh/hash.c @@ -89,6 +89,7 @@ static DohObjInfo HashType = { Hash_clear, /* sm_clear */ Hash_str, /* sm_str */ 0, /* doh_data */ + 0, /* doh_dump */ Hash_len, /* sm_len */ 0, /* sm_hash */ 0, /* doh_cmp */ @@ -446,15 +447,15 @@ Hash_str(DOH *ho) { Append(s,"}\n"); #else s = NewString("Hash"); - Appendf(s,"(%x) {",h); + Printf(s,"(%x) {",h); for (i = 0; i < h->hashsize; i++) { n = h->hashtable[i]; while (n) { - Appendf(s,"'%o',", n->key); + Printf(s,"'%o',", n->key); n = n->next; } } - Appendf(s,"}"); + Printf(s,"}"); #endif return s; } diff --git a/Source/DOH/Doh/list.c b/Source/DOH/Doh/list.c index 14e9841ae..cc6dfe3fa 100644 --- a/Source/DOH/Doh/list.c +++ b/Source/DOH/Doh/list.c @@ -44,6 +44,7 @@ int List_len(DOH *); DOH *List_first(DOH *); DOH *List_next(DOH *); DOH *List_str(DOH *); +int List_dump(DOH *, DOH *); #define MAXLISTITEMS 8 @@ -52,7 +53,6 @@ static DohSequenceMethods ListSeqMethods = { List_set, List_remove, List_insert, - 0, List_first, List_next, }; @@ -65,6 +65,7 @@ static DohObjInfo ListType = { List_clear, /* sm_clear */ List_str, /* sm_str */ 0, /* doh_data */ + List_dump, /* doh_dump */ List_len, /* sm_len */ 0, /* sm_hash */ 0, /* doh_cmp */ @@ -326,13 +327,26 @@ List_str(DOH *lo) List *l = (List *) lo; s = NewString(""); for (i = 0; i < l->nitems; i++) { - Appendf(s, "%o", l->items[i]); + Printf(s, "%o", l->items[i]); if ((i+1) < l->nitems) - Append(s,", "); + Printf(s,", "); } return s; } +int +List_dump(DOH *lo, DOH *out) { + int nsent = 0; + int i,ret; + List *l = (List *) lo; + for (i = 0; i < l->nitems; i++) { + ret = Dump(l->items[i],out); + if (ret < 0) return -1; + nsent += ret; + } + return nsent; +} + #ifdef SORT /* ----------------------------------------------------------------------------- * void List_sort(DOH *DOH) diff --git a/Source/DOH/Doh/string.c b/Source/DOH/Doh/string.c index 7bf62ed9e..5be745da5 100644 --- a/Source/DOH/Doh/string.c +++ b/Source/DOH/Doh/string.c @@ -30,6 +30,8 @@ typedef struct String { int sp; /* Current position */ int lsp; /* Last returned position */ char *str; /* String data */ + char pb[4]; /* Pushback data */ + int pbi; } String; /* Forward references */ @@ -46,30 +48,32 @@ int String_insert(DOH *s, int pos, DOH *DOH); void *String_data(DOH *s); int String_cmp(DOH *, DOH *); int String_hash(DOH *s); +int String_dump(DOH *s, DOH *out); int String_read(DOH *s, void *buffer, int length); int String_write(DOH *s, void *buffer, int length); +int String_getc(DOH *s); +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_printf(DOH *s, char *fmt, va_list ap); -int String_scanfv(DOH *s, char *fmt, va_list ap); static DohSequenceMethods StringSeqMethods = { - 0, - 0, - String_delitem, - String_insert, - String_insertfv, - 0, - 0, + 0, /* doh_getitem */ + 0, /* doh_setitem */ + String_delitem, /* doh_delitem */ + String_insert, /* doh_insitem */ + 0, /* doh_first */ + 0, /* doh_next */ }; static DohFileMethods StringFileMethods = { String_read, String_write, + String_putc, + String_getc, + String_ungetc, String_seek, String_tell, - String_printf, - String_scanfv, 0, }; @@ -81,6 +85,7 @@ static DohObjInfo StringType = { String_clear, /* sm_clear */ String_str, /* sm_str */ String_data, /* doh_data */ + String_dump, /* doh_dump */ String_len, /* sm_len */ String_hash, /* sm_hash */ String_cmp, /* doh_cmp */ @@ -107,6 +112,27 @@ void *String_data(DOH *so) { } /* ----------------------------------------------------------------------------- + * int String_dump(DOH *so, DOH *out) + * + * Serialize a string onto out + * ----------------------------------------------------------------------------- */ + +int String_dump(DOH *so, DOH *out) { + int nsent; + int ret; + String *s; + + s = (String *) so; + nsent = 0; + while (nsent < s->len) { + ret = Write(out,s->str+nsent,(s->len-nsent)); + if (ret < 0) return ret; + nsent += ret; + } + return nsent; +} + +/* ----------------------------------------------------------------------------- * NewString(const char *c) - Create a new string * ----------------------------------------------------------------------------- */ DOH * @@ -120,6 +146,7 @@ NewString(char *s) str->hashkey = -1; str->sp = 0; str->lsp = 0; + str->pbi = 0; str->line = 1; max = INIT_MAXSIZE; if (s) { @@ -154,6 +181,7 @@ CopyString(DOH *so) { str->sp = 0; str->lsp = 0; str->line = 1; + str->pbi = 0; max = s->maxsize; str->str = (char *) malloc(max); memmove(str->str, s->str, max); @@ -251,6 +279,7 @@ add(String *s, const char *newstr) { s->maxsize = newmaxsize; } strcpy(s->str+s->len,newstr); + if (s->sp >= s->len) s->sp+=l; s->len += l; } @@ -267,6 +296,7 @@ addstr(String *s, String *s1) { s->maxsize = newmaxsize; } memmove(s->str+s->len,s1->str,s1->len); + if (s->sp >= s->len) s->sp+=l; s->len += l; } @@ -281,8 +311,9 @@ String_addchar(DOH *so, char c) { assert(s->str = (char *) realloc(s->str,2*s->maxsize)); s->maxsize *= 2; } - s->str[s->len++] = c; - s->str[s->len] = 0; + s->str[s->len] = c; + if (s->sp >= s->len) s->sp++; + s->len++; } /* Expand a string to accomodate a write */ @@ -309,327 +340,8 @@ String_clear(DOH *so) s->sp = 0; s->lsp = 0; s->line = 1; + s->pbi = 0; } - -/* ----------------------------------------------------------------------------- - * void String_appendfv(String *s, char *format, va_list ap) - * - * Formats a string into s. This is an incredibly gross hack. - * -----------------------------------------------------------------------------*/ -void -String_appendfv(DOH *so, char *format, va_list ap) -{ - static char *fmt_codes = "dioxXucsSfeEgGpnbB"; - int state = 0; - char *p = format; - char newformat[256]; - char *fmt; - char temp[64]; - int widthval = 0; - int precval = 0; - int maxwidth; - char *w, *prec; - int ivalue; - int dvalue; - String *s; - - s = (String *) so; - - while (*p) { - switch(state) { - case 0: /* Ordinary text */ - if (*p != '%') { - String_addchar(s,*p); - } else{ - fmt = newformat; - widthval = 0; - precval = 0; - *(fmt++) = *p; - state = 10; - } - break; - case 10: /* Look for a width and precision */ - if (isdigit(*p) && (*p != '0')) { - w = temp; - *(w++) = *p; - *(fmt++) = *p; - state = 20; - } else if (strchr(fmt_codes,*p)) { - /* Got one of the formatting codes */ - p--; - state = 100; - } else if (*p == '*') { - /* Width field is specified in the format list */ - widthval = va_arg(ap,int); - sprintf(temp,"%d",widthval); - for (w = temp; *w; w++) { - *(fmt++) = *w; - } - state = 30; - } else if (*p == '%') { - String_addchar(s,*p); - fmt = newformat; - state = 0; - } else { - *(fmt++) = *p; - } - break; - - case 20: /* Hmmm. At the start of a width field */ - if (isdigit(*p)) { - *(w++) = *p; - *(fmt++) = *p; - } else if (strchr(fmt_codes,*p)) { - /* Got one of the formatting codes */ - /* Figure out width */ - *w = 0; - widthval = atoi(temp); - p--; - state = 100; - } else if (*p == '.') { - *w = 0; - widthval = atoi(temp); - w = temp; - *(fmt++) = *p; - state = 40; - } else { - /* ??? */ - *w = 0; - widthval = atoi(temp); - state = 50; - } - break; - - case 30: /* Parsed a width from an argument. Look for a . */ - if (*p == '.') { - w = temp; - *(fmt++) = *p; - state = 40; - } else if (strchr(fmt_codes,*p)) { - /* Got one of the formatting codes */ - /* Figure out width */ - p--; - state = 100; - } else { - /* hmmm. Something else. */ - state = 50; - } - break; - - case 40: - /* Start of precision expected */ - if (isdigit(*p) && (*p != '0')) { - *(fmt++) = *p; - *(w++) = *p; - state = 41; - } else if (*p == '*') { - /* Precision field is specified in the format list */ - precval = va_arg(ap,int); - sprintf(temp,"%d",precval); - for (w = temp; *w; w++) { - *(fmt++) = *w; - } - state = 50; - } else if (strchr(fmt_codes,*p)) { - p--; - state = 100; - } else { - *(fmt++) = *p; - state = 50; - } - break; - case 41: - if (isdigit(*p)) { - *(fmt++) = *p; - *(w++) = *p; - } else if (strchr(fmt_codes,*p)) { - /* Got one of the formatting codes */ - /* Figure out width */ - *w = 0; - precval = atoi(temp); - p--; - state = 100; - } else { - *w = 0; - precval = atoi(temp); - *(fmt++) = *p; - state = 50; - } - break; - /* Hang out, wait for format specifier */ - case 50: - if (strchr(fmt_codes,*p)) { - p--; - state = 100; - } else { - *(fmt++) = *p; - } - break; - case 100: - /* Got a formatting code */ - if (widthval < precval) maxwidth = precval; - else maxwidth = widthval; - if ((*p == 's') || (*p == 'S')) { /* Null-Terminated string */ - DOH *doh; - String *Sval; - doh = va_arg(ap, DOH *); - if (DohCheck(doh)) { - /* Is an object at least */ - if (String_check(doh)) { - Sval = (String *) doh; - } else { - Sval = (String *) Str(doh); - } - maxwidth = maxwidth+strlen(newformat)+strlen(Sval->str); - String_expand(s,maxwidth); - *(fmt++) = 's'; - *fmt = 0; - sprintf(s->str+s->len,newformat,Sval->str); - s->len = s->len + strlen(s->str+s->len); - if ((DOH *) Sval != doh) { - Delete(Sval); - } - if (*p == 'S') { - Delete(doh); - } - } else { - maxwidth = maxwidth+strlen(newformat)+strlen((char *) doh); - String_expand(s,maxwidth); - *(fmt++) = 's'; - *fmt = 0; - sprintf(s->str+s->len,newformat,doh); - s->len = s->len + strlen(s->str+s->len); - } - } else if ((*p == 'b') || (*p == 'B')) { - /* Raw binary mode */ - DOH *doh, *Sval; - doh = va_arg(ap, DOH *); - if (DohCheck(doh)) { - void *ptr; - int len; - Sval = Str(doh); - ptr = Data(Sval); - len = Len(Sval); - if ((widthval > 0) && (widthval < len)) len = widthval; - String_expand(s,len); - if (ptr) { - memmove(s->str+s->len,ptr,len); - s->len += len; - } - if (*p == 'B') { - Delete(doh); - } - Delete(Sval); - } else { - String_expand(s,widthval); - memmove(s->str+s->len,doh,widthval); - s->len+=widthval; - } - } else { - int ivalue; - double dvalue; - void *pvalue; - *(fmt++) = *p; - *fmt = 0; - maxwidth = maxwidth+strlen(newformat)+64; - String_expand(s,maxwidth); - switch(*p) { - case 'd': - case 'i': - case 'o': - case 'u': - case 'x': - case 'X': - case 'c': - ivalue = va_arg(ap,int); - sprintf(s->str+s->len,newformat,ivalue); - break; - case 'f': - case 'g': - case 'e': - case 'E': - case 'G': - dvalue = va_arg(ap,double); - sprintf(s->str+s->len,newformat,dvalue); - break; - case 'p': - pvalue = va_arg(ap,void *); - sprintf(s->str+s->len,newformat,pvalue); - break; - default: - break; - } - s->len = s->len + strlen(s->str+s->len); - } - state = 0; - break; - } - p++; - } - if (state) { - *fmt = 0; - add(s,fmt); - } -} - -/* ---------------------------------------------------------------------- - * int String_scanfv(DOH *doh, char *format, va_list ap) - * - * Do a string scanf. Somewhat broken compared to C scanf. - * ---------------------------------------------------------------------- */ - -int String_scanfv(DOH *doh, char *format, va_list ap) { - static char *fmt_chars = "diouxcsefgp"; - String *s; - char newformat[256]; - char *fmt; - char *p; - int state; - void *ptr; - int total = 0; - int i; - - s = (String *) doh; - state = 0; - p = format; - while (*p) { - switch(state) { - case 0: - if (*p == '%') { - fmt = newformat; - *(fmt++) = *p; - state = 10; - } - break; - case 10: - if (strchr(fmt_chars,*p)) { - int len; - *(fmt++) = *p; - *fmt = 0; - ptr = va_arg(ap, void *); - len = sscanf(s->str+s->sp,newformat,ptr); - for (i = 0; i < len; i++) { - while (s->sp < s->len) { - if (!isspace(s->str[s->sp])) break; - s->sp++; - } - while (s->sp < s->len) { - if (isspace(s->str[s->sp])) break; - s->sp++; - } - } - total += len; - state = 0; - fmt = newformat; - } else { - *(fmt++) = *p; - } - break; - } - p++; - } - return total; -} void raw_insert(String *s, int pos, char *data, int len) @@ -675,27 +387,6 @@ String_insert(DOH *so, int pos, DOH *str) } /* ----------------------------------------------------------------------------- - * void String_insertf(DOH *so, char *format, ...) - Insert a string - * -----------------------------------------------------------------------------*/ - -int -String_insertfv(DOH *so, int pos, char *format, va_list ap) -{ - String *s; - String *temp; - s = (String *) so; - if (pos == DOH_END) { - String_appendfv(so,format,ap); - return 0; - } - temp = NewString(""); - String_appendfv(temp,format,ap); - raw_insert(s,pos, temp->str,temp->len); - Delete(temp); - return 0; -} - -/* ----------------------------------------------------------------------------- * int String_delitem(DOH *so, int pos) * * Delete an individual item @@ -734,12 +425,26 @@ String_str(DOH *so) { * ----------------------------------------------------------------------------- */ int String_read(DOH *so, void *buffer, int len) { - int reallen; + int reallen, retlen; + int i; + char *cb; String *s = (String *) so; - if ((s->sp + len) > s->len) reallen = (s->len - s->sp); - memmove(buffer, s->str+s->sp, reallen); - s->sp += reallen; - return reallen; + if (((s->sp-s->pbi) + len) > s->len) reallen = (s->len - (s->sp-s->pbi)); + + cb = (char *) buffer; + retlen = reallen; + + /* Read the push-back buffer contents first */ + while (reallen > 0) { + if (s->pbi <= 0) break; + *(cb++) = (char) s->pb[--s->pbi]; + reallen--; + } + if (reallen > 0) { + memmove(cb, s->str+s->sp, reallen); + s->sp += reallen; + } + return retlen; } /* ----------------------------------------------------------------------------- @@ -757,8 +462,10 @@ String_write(DOH *so, void *buffer, int len) { s->maxsize = newlen; s->len = s->sp + len; } + if (newlen > s->len) s->len = newlen; memmove(s->str+s->sp,buffer,len); s->sp += len; + s->pbi = 0; return len; } @@ -780,6 +487,7 @@ String_seek(DOH *so, long offset, int whence) { s->sp = pos + offset; if (s->sp < 0) s->sp = 0; if (s->sp > s->len) s->sp = s->len; + s->pbi = 0; return 0; } @@ -791,26 +499,63 @@ String_seek(DOH *so, long offset, int whence) { long String_tell(DOH *so) { String *s = (String *) so; - return (long) s->sp; + return (long) (s->sp - s->pbi); } /* ----------------------------------------------------------------------------- - * int String_printf(DOH *so, char *format, ...) + * int String_putc(DOH *so, int ch) * + * Put a character into the string. * ----------------------------------------------------------------------------- */ int -String_printf(DOH *so, char *format, va_list ap) -{ - int len; - DOH *nso; +String_putc(DOH *so, int ch) { String *s = (String *) so; - nso = NewString(""); - String_appendfv(nso,format,ap); - len = ((String *) nso)->len; - String_write(so,Data(nso),len); - Delete(nso); - return len; + if (s->sp >= s->len) { + String_addchar(s,(char) ch); + } else { + s->str[s->sp] = (char) ch; + s->sp++; + } + s->pbi = 0; + return ch; +} + +/* ----------------------------------------------------------------------------- + * int String_getc(DOH *so) + * + * Get a character from the string + * ----------------------------------------------------------------------------- */ + +int String_getc(DOH *so) { + 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++]; +} + +/* ----------------------------------------------------------------------------- + * int String_ungetc(DOH *so, int ch) + * + * Put a character back on to the input stream. + * ----------------------------------------------------------------------------- */ + +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) { + s->pb[0] = s->pb[1]; + s->pb[1] = s->pb[2]; + s->pb[2] = s->pb[3]; + s->pb[3] = (char) ch; + } else { + s->pb[s->pbi++] = (char) ch; + } + return ch; } /* ----------------------------------------------------------------------------- diff --git a/Source/DOH/Include/doh.h b/Source/DOH/Include/doh.h index db5816e42..aaf898d41 100644 --- a/Source/DOH/Include/doh.h +++ b/Source/DOH/Include/doh.h @@ -51,7 +51,6 @@ typedef struct { int (*doh_setitem)(DOH *obj, int index, DOH *value); int (*doh_delitem)(DOH *obj, int index); int (*doh_insitem)(DOH *obj, int index, DOH *value); - int (*doh_insertf)(DOH *obj, int index, char *format, va_list ap); DOH *(*doh_first)(DOH *obj); DOH *(*doh_next)(DOH *obj); } DohSequenceMethods; @@ -60,10 +59,11 @@ typedef struct { typedef struct { int (*doh_read)(DOH *obj, void *buffer, int nbytes); int (*doh_write)(DOH *obj, void *buffer, int nbytes); + int (*doh_putc)(DOH *obj, int ch); + int (*doh_getc)(DOH *obj); + int (*doh_ungetc)(DOH *obj, int ch); int (*doh_seek)(DOH *obj, long offset, int whence); long (*doh_tell)(DOH *obj); - int (*doh_printf)(DOH *obj, char *format, va_list ap); - int (*doh_scanf)(DOH *obj, char *format, va_list ap); int (*doh_close)(DOH *obj); } DohFileMethods; @@ -83,8 +83,9 @@ typedef struct DohObjInfo { void (*doh_clear)(DOH *obj); /* Clear an object */ /* Output methods */ - DOH *(*doh_str)(DOH *obj); /* Make a full string */ - void *(*doh_data)(DOH *obj); /* Return raw data */ + DOH *(*doh_str)(DOH *obj); /* Make a full string */ + void *(*doh_data)(DOH *obj); /* Return raw data */ + int (*doh_dump)(DOH *obj, DOH *out); /* Serialize on out */ /* Length and hash values */ int (*doh_len)(DOH *obj); @@ -120,6 +121,7 @@ extern DOH *DohCopy(DOH *obj); extern void DohClear(DOH *obj); extern int DohCmp(DOH *obj1, DOH *obj2); extern DOH *DohStr(DOH *obj); +extern int DohDump(DOH *obj, DOH *out); extern DOH *DohGetattr(DOH *obj, DOH *name); extern int DohGetattrf(DOH *obj, DOH *name, char *fmt, ...); extern int DohSetattr(DOH *obj, DOH *name, DOH *value); @@ -130,10 +132,6 @@ extern DOH *DohGetitem(DOH *obj, int index); extern void DohSetitem(DOH *obj, int index, DOH *value); extern void DohDelitem(DOH *obj, int index); extern void DohInsertitem(DOH *obj, int index, DOH *value); -extern void DohInsertf(DOH *obj, int index, char *format, ...); -extern void DohvInsertf(DOH *obj, int index, char *format, va_list ap); -extern void DohAppendf(DOH *obj, char *format, ...); -extern void DohvAppendf(DOH *obj, char *format, va_list ap); extern int DohLen(DOH *obj); extern DOH *DohFirst(DOH *obj); extern DOH *DohNext(DOH *obj); @@ -152,6 +150,10 @@ 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 long DohTell(DOH *obj); +extern int DohGetc(DOH *obj); +extern int DohPutc(int ch, DOH *obj); +extern int DohUngetc(int ch, DOH *obj); + extern int DohPrintf(DOH *obj, char *format, ...); extern int DohvPrintf(DOH *obj, char *format, va_list ap); extern int DohScanf(DOH *obj, char *format, ...); @@ -164,6 +166,7 @@ extern int DohvScanf(DOH *obj, char *format, va_list ap); #define Copy DohCopy #define Clear DohClear #define Str DohStr +#define Dump DohDump #define Signature DohSignature #define Getattr DohGetattr #define Getattrf DohGetattrf @@ -175,11 +178,7 @@ extern int DohvScanf(DOH *obj, char *format, va_list ap); #define Setitem DohSetitem #define Delitem DohDelitem #define Insert DohInsertitem -#define Insertf DohInsertitemf -#define vInsertf DohvInsertitemf #define Append(s,x) DohInsertitem(s,DOH_END,x) -#define Appendf DohAppendf -#define vAppendf DohvAppendf #define Push(s,x) DohInsertitem(s,DOH_BEGIN,x) #define Len DohLen #define First DohFirst @@ -198,6 +197,9 @@ extern int DohvScanf(DOH *obj, char *format, va_list ap); #define Seek DohSeek #define Tell DohTell #define Printf DohPrintf +#define Getc DohGetc +#define Putc DohPutc +#define Ungetc DohUngetc #define vPrintf DohvPrintf #define Scanf DohScanf #define vScanf DohvScanf |