diff --git a/Source/Swig/super.c b/Source/Swig/super.c index a05439d10..39a6f64ce 100644 --- a/Source/Swig/super.c +++ b/Source/Swig/super.c @@ -16,7 +16,7 @@ #include "doh.h" #include "swigcore.h" -#if 0 + static char cvstag[] = "$Header$"; /* @@ -25,32 +25,34 @@ static char cvstag[] = "$Header$"; * contain. */ -typedef struct SSTag { - int length; /* distance to the next tag */ - int line; /* of this character */ - DOH *filename; /* of this character */ +typedef struct SSTag +{ + int length; /* distance to the next tag */ + int line; /* of this character */ + DOH *filename; /* of this character */ } SSTag; -typedef struct Super { - DOHCOMMON; +typedef struct Super +{ + DOHCOMMON; + + /* -- from the regular string implementation */ + int maxsize; /* Max size allocated */ + int len; /* Current length */ + int hashkey; /* Hash key value */ + int sp; /* Current position */ + int lsp; /* Last returned position */ + char *str; /* String data */ + char pb[4]; /* Pushback data */ + int pbi; - /* -- from the regular string implementation */ - int maxsize; /* Max size allocated */ - int len; /* Current length */ - int hashkey; /* Hash key value */ - int sp; /* Current position */ - int lsp; /* Last returned position */ - char *str; /* String data */ - char pb[4]; /* Pushback data */ - int pbi; + /* -- specific to the SuperString implementation */ + SSTag *tags; /* array of tags */ + int maxtags; /* max size allocated for tags */ + int numtags; /* count of tags */ - /* -- specific to the SuperString implementation */ - SSTag *tags; /* array of tags */ - int maxtags; /* max size allocated for tags */ - int numtags; /* count of tags */ - - int curtag; /* last tag before point */ - int curtag_offset; /* offset into current tag */ + int curtag; /* last tag before point */ + int curtag_offset; /* offset into current tag */ } Super; /* Forward references for member functions */ @@ -89,11 +91,11 @@ static void Super_delete_tag(Super *s, int index); static void Super_count_newlines(char *s, int len); static void Super_string_insert(Super *s, int pos, char *str, int len, DOH *filename, int line); -static void Super_super_insert2(Super *s, int pos, Super *str, +static void Super_super_insert2(Super *s, int pos, char *str, int, DOH *, int); static void Super_super_insert(Super *s, int pos, Super *str); -typedef void (*callback)(Super *, int, DOH *, int, DOH *, int); +typedef void (*callback)(Super *, int, char *, int, DOH *, int); static int Super_raw_replace(Super *str, char *token, int flags, callback insert, DOH *rep, int rep_len, DOH *rep_fn, int rep_line); @@ -101,27 +103,27 @@ static int Super_raw_replace(Super *str, char *token, int flags, /* method tables */ static DohSequenceMethods SuperSeqMethods = { - 0, /* doh_getitem */ - 0, /* doh_setitem */ - Super_delitem, /* doh_delitem */ - Super_insert, /* doh_insitem */ - 0, /* doh_first */ - 0, /* doh_next */ + 0, /* doh_getitem */ + 0, /* doh_setitem */ + Super_delitem, /* doh_delitem */ + Super_insert, /* doh_insitem */ + 0, /* doh_first */ + 0, /* doh_next */ }; static DohFileMethods SuperFileMethods = { - Super_read, - Super_write, - Super_putc, - Super_getc, - Super_ungetc, - Super_seek, - Super_tell, - 0, - 0, - Super_setfile, - 0, - Super_setline + Super_read, + Super_write, + Super_putc, + Super_getc, + Super_ungetc, + Super_seek, + Super_tell, + 0, + 0, + Super_setfile, + 0, + Super_setline }; static DohSuperMethods SuperSuperMethods = { @@ -130,24 +132,24 @@ static DohSuperMethods SuperSuperMethods = { }; static DohObjInfo SuperType = { - "SuperString", /* objname */ - sizeof(Super), /* objsize */ - DelSuper, /* doh_del */ - CopySuper, /* doh_copy */ - Super_clear, /* doh_clear */ - 0, /* doh_scope */ - Super_str, /* doh_str */ - Super_data, /* doh_data */ - Super_dump, /* doh_dump */ - 0, /* doh_load */ - Super_len, /* doh_len */ - Super_hash, /* doh_hash */ - Super_cmp, /* doh_cmp */ - 0, /* doh_mapping */ - &SuperSeqMethods, /* doh_sequence */ - &SuperFileMethods, /* doh_file */ - &SuperStringMethods, /* doh_string */ - 0, /* doh_callable */ + "SuperString", /* objname */ + sizeof(Super), /* objsize */ + DelSuper, /* doh_del */ + CopySuper, /* doh_copy */ + Super_clear, /* doh_clear */ + 0, /* doh_scope */ + Super_str, /* doh_str */ + Super_data, /* doh_data */ + Super_dump, /* doh_dump */ + 0, /* doh_load */ + Super_len, /* doh_len */ + Super_hash, /* doh_hash */ + Super_cmp, /* doh_cmp */ + 0, /* doh_mapping */ + &SuperSeqMethods, /* doh_sequence */ + &SuperFileMethods, /* doh_file */ + &SuperStringMethods, /* doh_string */ + 0, /* doh_callable */ }; #define INIT_MAXSIZE 16 @@ -161,52 +163,52 @@ static DohObjInfo SuperType = { DOH * NewSuper(char *s, DOH *filename, int firstline) { - int l = 0, max; - Super *str; + int l = 0, max; + Super *str; - str = (Super *) DohObjMalloc(sizeof(Super)); - str->objinfo = &SuperType; - str->hashkey = -1; - str->sp = 0; - str->lsp = 0; - str->pbi = 0; + str = (Super *) DohObjMalloc(sizeof(Super)); + str->objinfo = &SuperType; + str->hashkey = -1; + str->sp = 0; + str->lsp = 0; + str->pbi = 0; - max = INIT_MAXSIZE; - if (s) - { - l = (int) strlen(s); - if ((l+1) > max) max = l+1; - } - str->maxsize = max; + max = INIT_MAXSIZE; + if (s) + { + l = (int) strlen(s); + if ((l+1) > max) max = l+1; + } + str->maxsize = max; - str->str = (char *) DohMalloc(max); - assert(str); - if (s) + str->str = (char *) DohMalloc(max); + assert(str); + if (s) copy_string(str->str,s); - else + else str->str[0] = 0; - str->line = firstline; - str->file = filename; /* don't incref: it's 'owned' by the + str->line = firstline; + str->file = filename; /* don't incref: it's 'owned' by the tag it comes from. */ - str->maxtags = INIT_MAXTAGS; - str->numtags = 1; - str->curtag = 0; - str->curtag_offset = 0; + str->maxtags = INIT_MAXTAGS; + str->numtags = 1; + str->curtag = 0; + str->curtag_offset = 0; - str->tags = (SSTag *) DohMalloc(max * sizeof(SSTag)); - assert(str->tags); - str->tags[0].position = 0; - str->tags[0].line = 1; - if (!String_check(filename) && !SuperString_check(filename)) + str->tags = (SSTag *) DohMalloc(max * sizeof(SSTag)); + assert(str->tags); + str->tags[0].position = 0; + str->tags[0].line = 1; + if (!String_check(filename) && !SuperString_check(filename)) filename = NewString(filename); - else + else Incref(filename); - str->tags[0].filename = filename; + str->tags[0].filename = filename; - str->len = l; - return (DOH *) str; + str->len = l; + return (DOH *) str; } /* ------------------------------------------------------------------------- @@ -215,7 +217,7 @@ NewSuper(char *s, DOH *filename, int firstline) int SuperString_check(DOH *s) { - return (s && DohCheck(s) && ((Super *) c)->objinfo == &SuperType); + return (s && DohCheck(s) && ((Super *) c)->objinfo == &SuperType); } /* ---- "Member" Functions ---- */ @@ -226,40 +228,40 @@ SuperString_check(DOH *s) static DOH * CopySuper(DOH *so) { - Super *s; - int max, i; - Super *str; - s = (Super *) so; - str = (Super *) DohObjMalloc(sizeof(Super)); - str->objinfo = &SuperType; - str->hashkey = -1; - str->sp = 0; - str->lsp = 0; - str->pbi = 0; + Super *s; + int max, i; + Super *str; + s = (Super *) so; + str = (Super *) DohObjMalloc(sizeof(Super)); + str->objinfo = &SuperType; + str->hashkey = -1; + str->sp = 0; + str->lsp = 0; + str->pbi = 0; - max = s->maxsize; - str->str = (char *) DohMalloc(max); - memmove(str->str, s->str, s->len); - str->maxsize = max; - str->len = s->len; - str->str[str->len] = 0; + max = s->maxsize; + str->str = (char *) DohMalloc(max); + memmove(str->str, s->str, s->len); + str->maxsize = max; + str->len = s->len; + str->str[str->len] = 0; - str->line = s->line; - str->file = s->file; Incref(str->file); + str->line = s->line; + str->file = s->file; Incref(str->file); - max = s->maxtags; - str->numtags = s->numtags; - str->maxtags = s->maxtags; - str->curtag = s->curtag; - str->curtag_offset = s->curtag_offset; + max = s->maxtags; + str->numtags = s->numtags; + str->maxtags = s->maxtags; + str->curtag = s->curtag; + str->curtag_offset = s->curtag_offset; - str->tags = (SSTag *) DohMalloc(max * sizeof(SSTag)); - memmove(str->tags, s->tags, s->numtags * sizeof(SSTag)); + str->tags = (SSTag *) DohMalloc(max * sizeof(SSTag)); + memmove(str->tags, s->tags, s->numtags * sizeof(SSTag)); - for (i = 0; i < str->numtags; i++) - Incref(str->tags[i].filename); + for (i = 0; i < str->numtags; i++) + Incref(str->tags[i].filename); - return (DOH *) str; + return (DOH *) str; } /* ------------------------------------------------------------------------- @@ -268,25 +270,25 @@ CopySuper(DOH *so) static void DelSuper(DOH *so) { - Super *s; - s = (Super *) so; - assert(s->refcount <= 0); + Super *s; + s = (Super *) so; + assert(s->refcount <= 0); - if (s->str) - DohFree(s->str); - s->str = 0; + if (s->str) + DohFree(s->str); + s->str = 0; - if (s->tags) - { + if (s->tags) + { int i; for (i = 0; i < s->numtags; i++) - Delete(s->tags[i].filename); + Delete(s->tags[i].filename); DohFree(s->tags); - } - s->tags = 0; + } + s->tags = 0; - DohObjFree(s); + DohObjFree(s); } /* ------------------------------------------------------------------------- @@ -295,9 +297,9 @@ DelSuper(DOH *so) static void * Super_data(DOH *so) { - Super *s = (Super *) so; - s->str[s->len] = 0; - return (void *) s->str; + Super *s = (Super *) so; + s->str[s->len] = 0; + return (void *) s->str; } /* ------------------------------------------------------------------------- @@ -309,19 +311,19 @@ Super_data(DOH *so) static int Super_dump(DOH *so, DOH *out) { - int nsent; - int ret; - Super *s; + int nsent; + int ret; + Super *s; - s = (Super *) so; - nsent = 0; - while (nsent < s->len) - { + s = (Super *) 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; + } + return nsent; } /* ------------------------------------------------------------------------- @@ -331,8 +333,8 @@ Super_dump(DOH *so, DOH *out) static int Super_len(DOH *so) { - Super *s = (Super *)so; - return s->len; + Super *s = (Super *)so; + return s->len; } /* ------------------------------------------------------------------------- @@ -342,27 +344,27 @@ Super_len(DOH *so) static int Super_cmp(DOH *so1, DOH *so2) { - /* we ignore all line number information */ - Super *s1, *s2; - char *c1, *c2; - int maxlen,i; - s1 = (Super *) so1; - s2 = (Super *) so2; - maxlen = s1->len; - if (s2->len < maxlen) - maxlen = s2->len; - c1 = s1->str; - c2 = s2->str; - for (i = 0; i < maxlen; i++,c1++,c2++) - if (*c1 != *c2) break; - if (i < maxlen) - { + /* we ignore all line number information */ + Super *s1, *s2; + char *c1, *c2; + int maxlen,i; + s1 = (Super *) so1; + s2 = (Super *) so2; + maxlen = s1->len; + if (s2->len < maxlen) + maxlen = s2->len; + c1 = s1->str; + c2 = s2->str; + for (i = 0; i < maxlen; i++,c1++,c2++) + if (*c1 != *c2) break; + if (i < maxlen) + { if (*c1 < *c2) return -1; else return 1; - } - if (s1->len == s2->len) return 0; - if (s1->len > s2->len) return 1; - return -1; + } + if (s1->len == s2->len) return 0; + if (s1->len > s2->len) return 1; + return -1; } /* ------------------------------------------------------------------------- @@ -372,20 +374,20 @@ Super_cmp(DOH *so1, DOH *so2) static int Super_hash(DOH *so) { - /* again, we ignore the line number information */ - Super *s = (Super *) so; - char *c; - int i, h = 0, len; - if (s->hashkey >= 0) return s->hashkey; - c = s->str; - len = s->len > 50 ? 50 : s->len; - for (i = 0; i < len; i++) - { + /* again, we ignore the line number information */ + Super *s = (Super *) so; + char *c; + int i, h = 0, len; + if (s->hashkey >= 0) return s->hashkey; + c = s->str; + len = s->len > 50 ? 50 : s->len; + for (i = 0; i < len; i++) + { h = (((h << 5) + *(c++))); - } - h = h & 0x7fffffff; - s->hashkey = h; - return h; + } + h = h & 0x7fffffff; + s->hashkey = h; + return h; } /* ------------------------------------------------------------------------- @@ -395,26 +397,26 @@ Super_hash(DOH *so) static void Super_clear(DOH *so) { - Super *s; - int i; + Super *s; + int i; - s = (Super *) so; - s->hashkey = -1; - s->len = 0; - *(s->str) = 0; - s->sp = 0; - s->lsp = 0; - s->pbi = 0; + s = (Super *) so; + s->hashkey = -1; + s->len = 0; + *(s->str) = 0; + s->sp = 0; + s->lsp = 0; + s->pbi = 0; - for (i = 1; i < s->numtags; i++) - Delete(s->tags[i].filename); - s->tags[0].length = 0; + for (i = 1; i < s->numtags; i++) + Delete(s->tags[i].filename); + s->tags[0].length = 0; - s->line = s->tags[0].line; - s->file = s->tags[0].filename; - s->numtags = 1; - s->curtag = 0; - s->curtag_offset = 0; + s->line = s->tags[0].line; + s->file = s->tags[0].filename; + s->numtags = 1; + s->curtag = 0; + s->curtag_offset = 0; } /* ------------------------------------------------------------------------- @@ -423,19 +425,19 @@ Super_clear(DOH *so) static int Super_insert(DOH *so, int pos, DOH *str) { - Super *s; - s = (Super *) so; + Super *s; + s = (Super *) so; - if (Super_check(str)) + if (Super_check(str)) Super_super_insert(s, pos, (Super *)str); - else if (DohCheck(str)) + else if (DohCheck(str)) Super_string_insert(s, pos, Char(str), Len(str), Getfile(str), Getline(str)); - else + else /* hmph. Nothin. */ Super_string_insert(s, pos, char *str, 0, 0); - return 0; + return 0; } /* ------------------------------------------------------------------------- @@ -446,38 +448,38 @@ Super_insert(DOH *so, int pos, DOH *str) static int Super_delitem(DOH *so, int pos) { - Super *s = (Super *) so; - int thistag, nexttag; + Super *s = (Super *) so; + int thistag, nexttag; - s->hashkey = -1; - if (pos == DOH_END) pos = s->len-1; - if (pos == DOH_BEGIN) pos = 0; - if (s->len == 0) return 0; + s->hashkey = -1; + if (pos == DOH_END) pos = s->len-1; + if (pos == DOH_BEGIN) pos = 0; + if (s->len == 0) return 0; - tag = Super_get_tag(s, pos, 0); + tag = Super_get_tag(s, pos, 0); - /* special handling for deleting the current character */ - if (s->sp == pos) - Super_move(s, 1); /* move ahead off of the character */ + /* special handling for deleting the current character */ + if (s->sp == pos) + Super_move(s, 1); /* move ahead off of the character */ - /* move the current point */ - else if (s->sp > pos) - { + /* move the current point */ + else if (s->sp > pos) + { s->sp--; if (s->curtag == tag) - s->curtag_offset--; - } + s->curtag_offset--; + } - /* move the string data */ - memmove(s->str+pos, s->str+pos+1, ((s->len-1) - pos)); - s->len--; - s->str[s->len] = 0; + /* move the string data */ + memmove(s->str+pos, s->str+pos+1, ((s->len-1) - pos)); + s->len--; + s->str[s->len] = 0; - /* and move the tags */ - if (! --s->tags[tag].length) - Super_delete_tag(tag); + /* and move the tags */ + if (! --s->tags[tag].length) + Super_delete_tag(tag); - return 0; + return 0; } /* ------------------------------------------------------------------------- @@ -487,10 +489,10 @@ static int Super_delitem(DOH *so, int pos) static DOH * Super_str(DOH *so) { - DOH *nstr; - Super *s = (Super *) so; - nstr = CopySuper(s); - return nstr; + DOH *nstr; + Super *s = (Super *) so; + nstr = CopySuper(s); + return nstr; } /* ------------------------------------------------------------------------- @@ -502,28 +504,28 @@ Super_str(DOH *so) static int Super_read(DOH *so, void *buffer, int len) { - int reallen, retlen; - char *cb; - Super *s = (Super *) so; + int reallen, retlen; + char *cb; + Super *s = (Super *) so; - if (((s->sp - s->pbi) + len) > s->len) - len = (s->len - (s->sp - s->pbi)); + if (((s->sp - s->pbi) + len) > s->len) + len = (s->len - (s->sp - s->pbi)); - cb = (char *) buffer; - retlen = len; + cb = (char *) buffer; + retlen = len; - /* Read the push-back buffer contents first */ - while (len > 0 && s->pbi) - { + /* Read the push-back buffer contents first */ + while (len > 0 && s->pbi) + { *cb = s->pb[--s->pbi]; if (*cb == (int)'\n') s->line++; cb++, len--; - } - if (len > 0) { - memmove(cb, s->str+s->sp, len); - Super_move(s, len); - } - return retlen; + } + if (len > 0) { + memmove(cb, s->str+s->sp, len); + Super_move(s, len); + } + return retlen; } /* ------------------------------------------------------------------------- @@ -535,34 +537,34 @@ Super_read(DOH *so, void *buffer, int len) static int Super_write(DOH *so, void *buffer, int len) { - int newsize; - Super *s = (Super *) so; + int newsize; + Super *s = (Super *) so; - /* zero the hash and pushback */ - s->hashkey = -1; - s->pbi = 0; + /* zero the hash and pushback */ + s->hashkey = -1; + s->pbi = 0; - /* update size */ - newsize = s->sp + len + 1; - if (newsize > s->maxsize) { - s->str = (char *) DohRealloc(s->str,newsize); - assert(s->str); - s->maxsize = newsize; - } + /* update size */ + newsize = s->sp + len + 1; + if (newsize > s->maxsize) { + s->str = (char *) DohRealloc(s->str,newsize); + assert(s->str); + s->maxsize = newsize; + } - /* update length */ - if ((s->sp + len) > s->len) - s->len = s->sp + len; + /* update length */ + if ((s->sp + len) > s->len) + s->len = s->sp + len; - /* update tag */ - s->tag[s->curtag].length += len; + /* update tag */ + s->tag[s->curtag].length += len; - /* and copy the data */ - memmove(s->str + s->sp, buffer, len); + /* and copy the data */ + memmove(s->str + s->sp, buffer, len); - /* move the point */ - Super_move(s, len); /* counts newlines */ - return len; + /* move the point */ + Super_move(s, len); /* counts newlines */ + return len; } /* ------------------------------------------------------------------------- @@ -574,15 +576,20 @@ Super_write(DOH *so, void *buffer, int len) static int Super_seek(DOH *so, long offset, int whence) { - Super *s = (Super *) so; - s->pbi = 0; + Super *s = (Super *) so; + s->pbi = 0; - if (whence == SEEK_SET) offset = -s->sp; - else if (whence == SEEK_END) offset = s->len - offset; + if (whence == SEEK_SET) offset = -s->sp; + else if (whence == SEEK_END) offset = s->len - s->sp - offset; - Super_move(s, offset); + if (offset + s->sp < 0) + offset = -s->sp; + else if (offset + s->sp > s->len) + offset = s->len - s->sp; - return 0; + Super_move(s, offset); + + return 0; } /* ------------------------------------------------------------------------- @@ -593,8 +600,8 @@ Super_seek(DOH *so, long offset, int whence) static long Super_tell(DOH *so) { - Super *s = (Super *) so; - return (long) (s->sp - s->pbi); + Super *s = (Super *) so; + return (long) (s->sp - s->pbi); } /* ------------------------------------------------------------------------- @@ -606,28 +613,28 @@ Super_tell(DOH *so) static int Super_putc(DOH *so, int ch) { - Super *s = (Super *) so; + Super *s = (Super *) so; - s->hashkey = -1; - s->pbi = 0; + s->hashkey = -1; + s->pbi = 0; - /* either append or overwrite */ - if (s->sp >= s->len) - { + /* either append or overwrite */ + if (s->sp >= s->len) + { if (s->len + 1 >= s->maxsize) { - s->str = (char *) DohRealloc(s->str ,2 * s->maxsize); - assert(s->str); - s->maxsize *= 2; + s->str = (char *) DohRealloc(s->str ,2 * s->maxsize); + assert(s->str); + s->maxsize *= 2; } s->str[s->len++] = c; s->str[s->len] = 0; - } - else - s->str[s->sp] = (char) ch; + } + else + s->str[s->sp] = (char) ch; - /* and move ahead over the new character */ - Super_move(s, 1) - return ch; + /* and move ahead over the new character */ + Super_move(s, 1) + return ch; } /* ------------------------------------------------------------------------- @@ -639,17 +646,17 @@ Super_putc(DOH *so, int ch) static int Super_getc(DOH *so) { - int c; - Super *s = (Super *) so; + int c; + Super *s = (Super *) so; - if (s->pbi) - return ((c = s->pb[--s->pbi]) == (int)'\n') ? (s->line++, c) : c; - else if (s->sp >= s->len) - return EOF; + if (s->pbi) + return ((c = s->pb[--s->pbi]) == (int)'\n') ? (s->line++, c) : c; + else if (s->sp >= s->len) + return EOF; - c = (int) s->str[s->sp]; - Super_move(s, 1); - return c; + c = (int) s->str[s->sp]; + Super_move(s, 1); + return c; } /* ------------------------------------------------------------------------- @@ -660,20 +667,20 @@ Super_getc(DOH *so) static int Super_ungetc(DOH *so, int ch) { - Super *s = (Super *) so; + Super *s = (Super *) so; - if (ch == EOF) return ch; - if ((s->sp - s->pbi) <= 0) return EOF; - if (s->pbi == 4) - { + 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; - if (ch == (int)'\n') - s->line--; - return ch; + } + else + s->pb[s->pbi++] = (char) ch; + if (ch == (int)'\n') + s->line--; + return ch; } @@ -693,7 +700,7 @@ Super_replace(DOH *stro, DOH *token, DOH *rep, int flags) static void Super_setfile(DOH *obj, DOH *f) { - assert(0); /* illegal operation */ + assert(0); /* illegal operation */ } /* ------------------------------------------------------------------------- @@ -703,7 +710,7 @@ Super_setfile(DOH *obj, DOH *f) static void Super_setline(DOH *obj, int l) { - assert(0); /* illegal operation */ + assert(0); /* illegal operation */ } /* ------------------------------------------------------------------------- @@ -712,34 +719,34 @@ Super_setline(DOH *obj, int l) void Super_chop(DOH *so) { - char *c; - int len, tag, offset; - Super *s = (Super *) so; + char *c; + int len, tag, offset; + Super *s = (Super *) so; - /* check this one for obiwans */ + /* check this one for obiwans */ - s->hashkey = -1; - s->pbi = 0; + s->hashkey = -1; + s->pbi = 0; - /* find trailing whitespace */ - c = s->str + s->len - 1; - while ((s->len >= 0) && (isspace(*c))) - c--; - len = c - str->str + 1; + /* find trailing whitespace */ + c = s->str + s->len - 1; + while ((s->len >= 0) && (isspace(*c))) + c--; + len = c - str->str + 1; - /* Move the point back if necessary */ - if (s->sp > len) - Super_move(len - s->sp); + /* Move the point back if necessary */ + if (s->sp > len) + Super_move(len - s->sp); - tag = Super_get_tag(s, len, &offset); + tag = Super_get_tag(s, len, &offset); - /* Delete any relevant tags... */ - while (--s->numtags > tag) + /* Delete any relevant tags... */ + while (--s->numtags > tag) Delete(s->tags[s->numtags].filename); - s->numtags++; - s->tags[tag].length = offset; + s->numtags++; + s->tags[tag].length = offset; - s->len = len; + s->len = len; } /* ---- internal functions ---- */ @@ -751,37 +758,37 @@ Super_chop(DOH *so) { static void Super_move(Super *s, int delta) { - int changed_tag = 0; - int curtag_offset = s->curtag_offset; - int line_offset; + int changed_tag = 0; + int curtag_offset = s->curtag_offset; + int line_offset; - if (delta > len - s->sp) - delta = len - s->sp; + if (delta > len - s->sp) + delta = len - s->sp; - while (1) - { + while (1) + { int remaining = s->tags[s->curtag].length - curtag_offset; if (delta > remaining) - { - delta -= remaining; - s->sp += remaining; - s->curtag++; - curtag_offset = 0; - } + { + delta -= remaining; + s->sp += remaining; + s->curtag++; + curtag_offset = 0; + } else - { - line_offset = Super_count_newlines(s->str + s->sp, delta); - curtag_offset += delta; - s->sp += delta; + { + line_offset = Super_count_newlines(s->str + s->sp, delta); + curtag_offset += delta; + s->sp += delta; - break; - } - } + break; + } + } - s->curtag_offset = curtag_offset; - s->file = s->tags[s->curtag].filename; - s->line = s->tags[s->curtag].line + line_offset; + s->curtag_offset = curtag_offset; + s->file = s->tags[s->curtag].filename; + s->line = s->tags[s->curtag].line + line_offset; } /* ------------------------------------------------------------------------- @@ -791,18 +798,18 @@ Super_move(Super *s, int delta) static int Super_get_tag(Super *s, int pos, int *offset) { - int tag = 0; - SSTag *tags = s->tags; + int tag = 0; + SSTag *tags = s->tags; - while (pos > tags->length) - { + while (pos > tags->length) + { pos -= tags->length; tags++; tag++; - } + } - if (offset) *offset = pos; - return tag; + if (offset) *offset = pos; + return tag; } /* ------------------------------------------------------------------------- @@ -814,20 +821,20 @@ static void Super_insert_tag(Super *s, int index, int length, int line, DOH *filename) { - if (s->numtags + 1 >= s->maxtags) - { + if (s->numtags + 1 >= s->maxtags) + { s->maxtags *= 2; s->tags = (SSTag *)DohRealloc(s->tags, s->maxtags * sizeof(SStag)); assert(s->tags); - } + } - memmove(s->tags + index + 1, s->tags + index, - (s->numtags - index) * sizeof(SStag)); - s->tags[index].length = length; - s->tags[index].line = line; - s->tags[index].filename = filename; - s->numtags++; + memmove(s->tags + index + 1, s->tags + index, + (s->numtags - index) * sizeof(SStag)); + s->tags[index].length = length; + s->tags[index].line = line; + s->tags[index].filename = filename; + s->numtags++; } /* ------------------------------------------------------------------------- @@ -837,12 +844,12 @@ Super_insert_tag(Super *s, int index, int length, static void Super_delete_tag(Super *s, int index) { - if (!tag) return; /* don't delete first tag */ - Delete(s->tags[index].filename); + if (!tag) return; /* don't delete first tag */ + Delete(s->tags[index].filename); - memmove(s->tags + index, s->tags + index + 1, - (s->numtags - index - 1) * sizeof(SStag)); - s->numtags--; + memmove(s->tags + index, s->tags + index + 1, + (s->numtags - index - 1) * sizeof(SStag)); + s->numtags--; } /* ------------------------------------------------------------------------- @@ -852,11 +859,11 @@ Super_delete_tag(Super *s, int index) static void Super_count_newlines(char *s, int len) { - register int retval = 0; - char *stop = s + len; - while (s < stop) - if (*(s++) == '\n') retval++; - return retval; + register int retval = 0; + char *stop = s + len; + while (s < stop) + if (*(s++) == '\n') retval++; + return retval; } /* ------------------------------------------------------------------------- @@ -866,13 +873,13 @@ Super_count_newlines(char *s, int len) static void Super_add_space(Super *s, int more_bytes) { - if (s->len + more_bytes >= s->maxsize) - { + if (s->len + more_bytes >= s->maxsize) + { newsize = (s->len + more_bytes) * 2; s->str = (char *)DohRealloc(s->str, newsize); assert(s->str); - s->maxsize = newsize - } + s->maxsize = newsize; + } } /* ------------------------------------------------------------------------- @@ -884,28 +891,28 @@ static void Super_string_insert(Super *s, int pos, char *str, int len, DOH *filename, int line) { - int offset, tag; - s->hashkey = -1; + int offset, tag; + s->hashkey = -1; - /* normalize the inputs */ - if (len == 0) len = strlen(str); - if (len == 0) return; + /* normalize the inputs */ + if (len == 0) len = strlen(str); + if (len == 0) return; - if (pos < 0) pos = 0; - else if (pos > s->len) pos = s->len; + if (pos < 0) pos = 0; + else if (pos > s->len) pos = s->len; - /* do the insertion */ - Super_add_space(s, len); - if (pos < s->len) - memmove(s->str+pos+len, s->str+pos, (s->len - pos)); - memmove(s->str+pos,str,len); - s->len += len; - s->str[s->len] = 0; + /* do the insertion */ + Super_add_space(s, len); + if (pos < s->len) + memmove(s->str+pos+len, s->str+pos, (s->len - pos)); + memmove(s->str+pos,str,len); + s->len += len; + s->str[s->len] = 0; - /* insert new tags for this string if necessary */ - tag = Super_get_tag(s, pos, &offset); - if (file) - { + /* insert new tags for this string if necessary */ + tag = Super_get_tag(s, pos, &offset); + if (file) + { int left_len = offset; int mid_len = len; int right_len = s->tags[tag].length - offset; @@ -913,41 +920,41 @@ Super_string_insert(Super *s, int pos, char *str, int len, DOH *right_filename = s->tags[tag].filename; if (right_len) - { - /* only calculate this if it will be used. */ - right_line = s->tags[tag].line + + { + /* only calculate this if it will be used. */ + right_line = s->tags[tag].line + Super_count_newlines(s->str + pos - offset, offset); - /* if a new tag uses filename, Incref it */ - Incref(right_filename); - } + /* if a new tag uses filename, Incref it */ + Incref(right_filename); + } /* don't leave any zero-length tags, and avoid deleting and then * inserting (such waste!) */ if (left_len) - { - s->tags[tag].length = left_len; - Super_insert_tag(s, ++tag, mid_len, line, filename); - } + { + s->tags[tag].length = left_len; + Super_insert_tag(s, ++tag, mid_len, line, filename); + } else - { /* replace the tag */ - Delete(s->tags[tag].filename); - s->tags[tag].length = mid_len; - s->tags[tag].line = line; - s->tags[tag].filename = filename; - } + { /* replace the tag */ + Delete(s->tags[tag].filename); + s->tags[tag].length = mid_len; + s->tags[tag].line = line; + s->tags[tag].filename = filename; + } if (right_len) - Super_insert_tag(s, ++tag, right_len, right_line, - right_filename); + Super_insert_tag(s, ++tag, right_len, right_line, + right_filename); - } - else /* no file/line info -- just extend */ - s->tags[tag].length += len; /* this tag a bit */ + } + else /* no file/line info -- just extend */ + s->tags[tag].length += len; /* this tag a bit */ - /* move the point if necessary */ - if (s->sp >= pos) - { + /* move the point if necessary */ + if (s->sp >= pos) + { int offset; s->sp += len; @@ -956,7 +963,7 @@ Super_string_insert(Super *s, int pos, char *str, int len, s->file = s->tags[s->curtag].filename; s->line = Super_count_newlines(s->str + s->sp - offset, offset); - } + } } /* ------------------------------------------------------------------------- @@ -964,92 +971,92 @@ Super_string_insert(Super *s, int pos, char *str, int len, * ------------------------------------------------------------------------- */ static void -Super_super_insert2(Super *s, int pos, Super *str, +Super_super_insert2(Super *s, int pos, char *str, int ignore1, DOH *ignore2, int ignore3) { /* this function's prototype matches Super_string_insert, so it can be used as a callback */ - Super_super_insert(s, pos, str); + Super_super_insert(s, pos, (Super *)str); } static void Super_super_insert(Super *s, int pos, Super *str) { - int offset, tag, len, i; - int left_len, right_len, new_tags; - int right_line; - DOH *right_filename; + int offset, tag, len, i; + int left_len, right_len, new_tags; + int right_line; + DOH *right_filename; - s->hashkey = -1; + s->hashkey = -1; - /* normalize the inputs */ - if (pos < 0) pos = 0; - else if (pos > s->len) pos = s->len; + /* normalize the inputs */ + if (pos < 0) pos = 0; + else if (pos > s->len) pos = s->len; - len = str->len; - if (len == 0) return; + len = str->len; + if (len == 0) return; - /* do the insertion */ - Super_add_space(s, len); - if (pos < s->len) - memmove(s->str+pos+len, s->str+pos, (s->len - pos)); - memmove(s->str+pos,str,len); - s->len += len; - s->str[s->len] = 0; + /* do the insertion */ + Super_add_space(s, len); + if (pos < s->len) + memmove(s->str+pos+len, s->str+pos, (s->len - pos)); + memmove(s->str+pos,str,len); + s->len += len; + s->str[s->len] = 0; - /* collect some factoids about the new layout of the tags */ - tag = Super_get_tag(s, pos, &offset); - left_len = offset; - right_len = s->tags[tag].length - offset; - right_filename = s->tags[tag].filename; + /* collect some factoids about the new layout of the tags */ + tag = Super_get_tag(s, pos, &offset); + left_len = offset; + right_len = s->tags[tag].length - offset; + right_filename = s->tags[tag].filename; - if (right_len) - { + if (right_len) + { /* only calculate this if it will be used */ right_line = s->tags[tag].line + - Super_count_newlines(s->str + pos - offset, offset); + Super_count_newlines(s->str + pos - offset, offset); /* if we will have another tag using filename, Incref it */ Incref(right_filename); - } + } - /* how many new tags shall we allocate? */ - new_tags = str->numtags + 1; - if (left_len == 0) - { + /* how many new tags shall we allocate? */ + new_tags = str->numtags + 1; + if (left_len == 0) + { new_tags--; Delete(s->tags[tag].filename); tag--; /* back up so we overwrite it. */ - } - if (right_len == 0) - new_tags--; + } + if (right_len == 0) + new_tags--; - /* allocate enough space for all those tags */ - if (s->numtags + new_tags >= s->maxtags) - { + /* allocate enough space for all those tags */ + if (s->numtags + new_tags >= s->maxtags) + { int newsize = (s->numtags + new_tags) * 2; s->tags = (SSTag *)DohRealloc(s->tags, newsize * sizeof(SSTag)); assert(s->tags); s->maxsize = newsize; - } + } - /* and start writing in the data */ - if (left_len) - s->tags[tag++].length = left_len; - memmove(s->tags + tag, str->tags, str->numtags * sizeof(SSTag)); - tags += str->numtags; - if (right_len) - { + /* and start writing in the data */ + if (left_len) + s->tags[tag++].length = left_len; + memmove(s->tags + tag, str->tags, str->numtags * sizeof(SSTag)); + tags += str->numtags; + if (right_len) + { s->tags[tag].length = right_len; s->tags[tag].line = right_line; s->tags[tag].filename = right_filename; tag++; - } + } - s->numtags += new_tags; + s->numtags += new_tags; - /* move the point if necessary */ - if (s->sp >= pos) - { + /* move the point if necessary */ + if (s->sp >= pos) + { int offset; s->sp += len; @@ -1058,7 +1065,7 @@ Super_super_insert(Super *s, int pos, Super *str) s->file = s->tags[s->curtag].filename; s->line = Super_count_newlines(s->str + s->sp - offset, offset); - } + } } /* ------------------------------------------------------------------------- @@ -1076,142 +1083,227 @@ Super_super_insert(Super *s, int pos, Super *str) * * ------------------------------------------------------------------------- */ +/* static variables for use in Super_raw_replace */ + +static Super *rr_dest; +static Super *rr_original; + +static void +Super_rr_append_chunk(int start, int len) +{ + SSTag initial, final; + SSTag new_initial, new_final; + int initial_tag, final_tag; + int old_numtags, old_len; + /* the job of this function: append a chunk to rr_dest from + rr_original. */ + + /* we use Super_move because it lets us move relatively within the + string instead of having to recalculate from the beginning every + time with Super_get_tag() */ + Super_move(rr_original, start - rr_original->sp); + initial_tag = rr_original->curtag; + initial = rr_original->tags[initial_tag]; + + new_initial.line = rr_original->line; + new_initial.filename = rr_original->filename; + new_initial.length = initial.length - rr_original->curtag_offset; + + Super_move(rr_original, len); + final_tag = rr_original->curtag; + + if (rr_original->curtag_offset ) + { + final = rr_original->tags[final_tag]; + new_final.line = rr_original->line; + new_final.filename = rr_original->filename; + new_final.length = rr_original->curtag_offset; + } + else /* avoid zero-length final tag */ + { + final_tag--; + final = rr_original->tags[final_tag]; + new_final = final; + } + + /* tuck away some other info */ + old_numtags = rr_original->numtags; + old_len = rr_original->len; + + /* OK, now we swap in our new tags, offset the tags and str fields + appropriately, set the lengths correctly, and call insert. */ + rr_original->tags[initial_tag] = new_initial; + rr_original->tags[final_tag] = new_final; + rr_original->numtags = final_tag - initial_tag + 1; + rr_original->tags += initial_tag; + rr_original->len = len; + rr_original->str += start; + + Super_super_insert(rr_dest, DOH_END, rr_original); /* easy!? */ + + rr_original->str -= start; + rr_original->len = old_len; + rr_original->tags -= initial_tag; + rr_original->numtags = old_numtags; + rr_original->tags[final_tag] = final; + rr_original->tags[initial_tag] = initial; +} + static int Super_raw_replace(Super *str, char *token, int flags, callback insert, DOH *rep, int rep_len, DOH *rep_fn, int rep_line) { - char *s, *t; - int tokenlen, state, i; - int repcount = 0; - Super fake; /* HACK! :) */ - SSTag *old_tags; - int old_numtags; - char *old_str; - int old_len; + char *match, *lastmatch_end; + int tokenlen, state, i; + int repcount = 0; + Super fake; /* HACK! :) */ + SSTag *old_tags; + int old_numtags; + char *old_str; + int old_len; - str->hashkey = -1; - - tokenlen = strlen(token); + str->hashkey = -1; + tokenlen = strlen(token); - /* first see if there is a match, using the speedy library - function */ - t = strstr(str->str, token); - if (!t) return 0; + /* first see if there is a match, using the speedy library + function */ + match = strstr(str->str, token); + if (!match) return 0; - /* otherwise, keep the current text of the string and its tags. */ - old_str = str->str; - old_len = str->len; - old_tags = str->tags; - old_numtags = str->numtags; - for (i = 0; i < old_numtags; i++) - Incref(old_tags[i].filename); /* we want to keep this! */ + /* if there is a match, then fill in the global variables. Note + that we only copy the necessary fields. */ + rr_dest = str; + rr_original = (Super *)CopySuper((DOH *)str); - /* and obliterate this super, allocating new space for both tags - and data. */ - Super_clear(str); - str->str = (char *) DohMalloc(str->maxsize); - assert(str->str); - str->tags = (SSTag *) DohMalloc(str->maxtags * sizeof(SSTag)); + /* Now obliterate our "destination". */ + Super_clear(rr_dest); - /* fill in the fake Super so we can use it for appending */ - fake.str = old_str; - fake.tags = old_tags; + /* if we can do this using library functions, get to work. */ + if (!(flags & (DOH_REPLACE_ID | DOH_REPLACE_NOQUOTE))) + { + lastmatch_end = rr_original->str; + while ((match = strstr(lastmatch_end, token))) + { + /* copy the unchanged stuff from the original */ + Super_rr_append_chunk(lastmatch_end - rr_original->str, + match - lastmatch_end); + + /* and now insert the replacement */ + (*insert)(rr_dest, DOH_END, (char *)rep, + rep_len, rep_fn, rep_line); - /* if we can do this using library functions, get to work. */ - if (!(flags & (DOH_REPLACE_ID | DOH_REPLACE_NOQUOTE))) - while (1) - { - int offset; - - if (t > fake.str) + /* now move our pointer up.. */ + lastmatch_end = match + tokenlen; + repcount++; + } + + /* copy the unchanged stuff from the end */ + Super_rr_append_chunk(lastmatch_end - rr_original->str, + rr_original->str + rr_original->len - + lastmatch_end); + + Delete(rr_original); + return repcount; + } + + /* otherwise we need to do our own kind of search, with Dave's + special little state machine to tell us when we're in quotes or + not at the beginning of an identifier. */ +#define RR_BEGIN_MATCH 0 +#define RR_INSIDE_IDENTIFIER 1 +#define RR_INSIDE_SINGLE_QUOTE 2 +#define RR_INSIDE_DOUBLE_QUOTE 3 +#define RR_DONE -1 + state = 0; + match = lastmatch_end = rr_original->str; + + while (*match && state != RR_DONE) + { + switch(state) + { + case RR_BEGIN_MATCH: + if (*match == *token && + strncmp(match,token,tokenlen) == 0) + { + /* skip if not the whole identifier */ + if (flags & DOH_REPLACE_ID) { - /* append a chunk from the old string */ - fake.len = t - fake.str; - fake.numtags = Super_get_tag(&fake, fake.len, &offset) + 1; - if (offset == 0) fake.numtags--; /* avoid an empty last tag */ - Super_super_insert(str, DOH_END, &fake); - - /* now move 'fake' over that chunk */ - fake.str += fake.len; - fake.tags += numtags - 1; - /* OBIWAN! */ /* - !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ + char after= *(match + tokenlen); + if (after == '_' || after == '$' || isalnum(after)) + { + match += tokenlen; + state = RR_INSIDE_IDENTIFIER; + continue; + } } - } - - while (1) - /* Depending on flags. We compare in different ways */ - state = 0; - t = c; - while ((*c) && (count)) { - switch(state) { - case 0: - if (*c == *token) { - if (!(flags & DOH_REPLACE_ID)) { - if (strncmp(c,token,tokenlen) == 0) { - char temp = *c; - *c = 0; - Super_add(str,t); - *c = temp; - Super_add(str,rep); - c += (tokenlen-1); - t = c+1; - count--; - repcount++; - } - } else if (isalpha(*c) || (*c == '_') || (*c == '$')) { - char temp = *c; - *c = 0; - Super_add(str,t); - *c = temp; - t = c; - state = 10; - } - } else if (flags & DOH_REPLACE_NOQUOTE) { - if (*c == '\"') state = 20; - else if (*c == '\'') state = 30; - } - break; - case 10: /* The start of an identifier */ - if (isalnum(*c) || (*c == '_') || (*c == '$')) state = 10; - else { - char temp = *c; - *c = 0; - if (strcmp(token,t) == 0) { - Super_add(str,rep); - count--; - repcount++; - } else { - Super_add(str,t); - } - *c = temp; - t = c; - state = 0; - } - break; - case 20: /* A Super */ - if (*c == '\"') state = 0; - else if (*c == '\\') c++; - break; - case 30: /* A Single quoted Super */ - if (*c == '\'') state = 0; - else if (*c == '\\') c++; - break; - } - c++; - } - if ((count) && (state == 10)) { - if (strcmp(token,t) == 0) { - Super_add(str,rep); - } else { - Super_add(str,t); - } - } else { - Super_add(str,t); - } - DohFree(s); - } - return repcount; + + /* copy the unchanged stuff from the original */ + Super_rr_append_chunk(lastmatch_end - rr_original->str, + match - lastmatch_end); + + /* and now insert the replacement */ + (*insert)(rr_dest, DOH_END, (char *)rep, + rep_len, rep_fn, rep_line); + + /* now move our pointer up.. */ + match = lastmatch_end = match + tokenlen; + repcount++; + + /* bail now if we only want to replace one */ + if (flags & DOH_REPLACE_FIRST) + state = RR_DONE; + + /* we're now not ready to replace another identifier, + if anybody cares */ + else if (flags & DOH_REPLACE_ID) + state = RR_INSIDE_IDENTIFIER; + + continue; + } + + if (flags & DOH_REPLACE_ID) + { + if (*match == '_' || *match == '*' || isalpha(*match)) + state = RR_INSIDE_IDENTIFIER; + } + + if (flags & DOH_REPLACE_NOQUOTE) + { + if (*match == '\"') state = RR_INSIDE_DOUBLE_QUOTES; + else if (*match == '\'') state = RR_INSIDE_SINGLE_QUOTES; + else if (*match == '\\' && + (*(match+1) == '\'' || *(match+1) == '\"')) + match++; + } + + break; + + case RR_IN_IDENTIFIER: + if (!(isalnum(*match) || (*match == '_') || (*match == '$'))) + state = RR_BEGIN_MATCH; + break; + + case RR_IN_DOUBLE_QUOTES: + if (*match == '\"') state = RR_BEGIN_MATCH; + else if (*match == '\\') match++; + break; + + case RR_IN_SINGLE_QUOTES: + if (*match == '\'') state = RR_BEGIN_MATCH; + else if (*match == '\\') match++; + break; + } + + match++; + } + + /* copy the unchanged stuff from the end */ + Super_rr_append_chunk(lastmatch_end - rr_original->str, + rr_original->str + rr_original->len - + lastmatch_end); + + + Delete(rr_original); + return repcount; } -#endif