Finished writing the thing -- I think

git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@104 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
Dustin Mitchell 2000-01-18 23:13:56 +00:00
commit 74b9dbf52e

View file

@ -16,7 +16,7 @@
#include "doh.h" #include "doh.h"
#include "swigcore.h" #include "swigcore.h"
#if 0
static char cvstag[] = "$Header$"; static char cvstag[] = "$Header$";
/* /*
@ -25,13 +25,15 @@ static char cvstag[] = "$Header$";
* contain. * contain.
*/ */
typedef struct SSTag { typedef struct SSTag
{
int length; /* distance to the next tag */ int length; /* distance to the next tag */
int line; /* of this character */ int line; /* of this character */
DOH *filename; /* of this character */ DOH *filename; /* of this character */
} SSTag; } SSTag;
typedef struct Super { typedef struct Super
{
DOHCOMMON; DOHCOMMON;
/* -- from the regular string implementation */ /* -- from the regular string implementation */
@ -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_count_newlines(char *s, int len);
static void Super_string_insert(Super *s, int pos, char *str, static void Super_string_insert(Super *s, int pos, char *str,
int len, DOH *filename, int line); 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); int, DOH *, int);
static void Super_super_insert(Super *s, int pos, Super *str); 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, static int Super_raw_replace(Super *str, char *token, int flags,
callback insert, DOH *rep, int rep_len, callback insert, DOH *rep, int rep_len,
DOH *rep_fn, int rep_line); DOH *rep_fn, int rep_line);
@ -578,7 +580,12 @@ Super_seek(DOH *so, long offset, int whence)
s->pbi = 0; s->pbi = 0;
if (whence == SEEK_SET) offset = -s->sp; if (whence == SEEK_SET) offset = -s->sp;
else if (whence == SEEK_END) offset = s->len - offset; else if (whence == SEEK_END) offset = s->len - s->sp - offset;
if (offset + s->sp < 0)
offset = -s->sp;
else if (offset + s->sp > s->len)
offset = s->len - s->sp;
Super_move(s, offset); Super_move(s, offset);
@ -871,7 +878,7 @@ Super_add_space(Super *s, int more_bytes)
newsize = (s->len + more_bytes) * 2; newsize = (s->len + more_bytes) * 2;
s->str = (char *)DohRealloc(s->str, newsize); s->str = (char *)DohRealloc(s->str, newsize);
assert(s->str); assert(s->str);
s->maxsize = newsize s->maxsize = newsize;
} }
} }
@ -964,11 +971,11 @@ Super_string_insert(Super *s, int pos, char *str, int len,
* ------------------------------------------------------------------------- */ * ------------------------------------------------------------------------- */
static void 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) int ignore1, DOH *ignore2, int ignore3)
{ /* this function's prototype matches Super_string_insert, so it can { /* this function's prototype matches Super_string_insert, so it can
be used as a callback */ be used as a callback */
Super_super_insert(s, pos, str); Super_super_insert(s, pos, (Super *)str);
} }
static void static void
@ -1076,12 +1083,78 @@ 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 static int
Super_raw_replace(Super *str, char *token, int flags, Super_raw_replace(Super *str, char *token, int flags,
callback insert, DOH *rep, int rep_len, callback insert, DOH *rep, int rep_len,
DOH *rep_fn, int rep_line) DOH *rep_fn, int rep_line)
{ {
char *s, *t; char *match, *lastmatch_end;
int tokenlen, state, i; int tokenlen, state, i;
int repcount = 0; int repcount = 0;
Super fake; /* HACK! :) */ Super fake; /* HACK! :) */
@ -1091,127 +1164,146 @@ Super_raw_replace(Super *str, char *token, int flags,
int old_len; int old_len;
str->hashkey = -1; str->hashkey = -1;
tokenlen = strlen(token); tokenlen = strlen(token);
/* first see if there is a match, using the speedy library /* first see if there is a match, using the speedy library
function */ function */
t = strstr(str->str, token); match = strstr(str->str, token);
if (!t) return 0; if (!match) return 0;
/* otherwise, keep the current text of the string and its tags. */ /* if there is a match, then fill in the global variables. Note
old_str = str->str; that we only copy the necessary fields. */
old_len = str->len; rr_dest = str;
old_tags = str->tags; rr_original = (Super *)CopySuper((DOH *)str);
old_numtags = str->numtags;
for (i = 0; i < old_numtags; i++)
Incref(old_tags[i].filename); /* we want to keep this! */
/* and obliterate this super, allocating new space for both tags /* Now obliterate our "destination". */
and data. */ Super_clear(rr_dest);
Super_clear(str);
str->str = (char *) DohMalloc(str->maxsize);
assert(str->str);
str->tags = (SSTag *) DohMalloc(str->maxtags * sizeof(SSTag));
/* 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 we can do this using library functions, get to work. */
if (!(flags & (DOH_REPLACE_ID | DOH_REPLACE_NOQUOTE))) if (!(flags & (DOH_REPLACE_ID | DOH_REPLACE_NOQUOTE)))
while (1)
{ {
int offset; lastmatch_end = rr_original->str;
while ((match = strstr(lastmatch_end, token)))
if (t > fake.str)
{ {
/* append a chunk from the old string */ /* copy the unchanged stuff from the original */
fake.len = t - fake.str; Super_rr_append_chunk(lastmatch_end - rr_original->str,
fake.numtags = Super_get_tag(&fake, fake.len, &offset) + 1; match - lastmatch_end);
if (offset == 0) fake.numtags--; /* avoid an empty last tag */
Super_super_insert(str, DOH_END, &fake);
/* now move 'fake' over that chunk */ /* and now insert the replacement */
fake.str += fake.len; (*insert)(rr_dest, DOH_END, (char *)rep,
fake.tags += numtags - 1; rep_len, rep_fn, rep_line);
/* OBIWAN! */ /*
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
}
}
while (1) /* now move our pointer up.. */
/* Depending on flags. We compare in different ways */ lastmatch_end = match + tokenlen;
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++; repcount++;
} }
} else if (isalpha(*c) || (*c == '_') || (*c == '$')) {
char temp = *c; /* copy the unchanged stuff from the end */
*c = 0; Super_rr_append_chunk(lastmatch_end - rr_original->str,
Super_add(str,t); rr_original->str + rr_original->len -
*c = temp; lastmatch_end);
t = c;
state = 10; Delete(rr_original);
return repcount;
} }
} else if (flags & DOH_REPLACE_NOQUOTE) {
if (*c == '\"') state = 20; /* otherwise we need to do our own kind of search, with Dave's
else if (*c == '\'') state = 30; special little state machine to tell us when we're in quotes or
} not at the beginning of an identifier. */
break; #define RR_BEGIN_MATCH 0
case 10: /* The start of an identifier */ #define RR_INSIDE_IDENTIFIER 1
if (isalnum(*c) || (*c == '_') || (*c == '$')) state = 10; #define RR_INSIDE_SINGLE_QUOTE 2
else { #define RR_INSIDE_DOUBLE_QUOTE 3
char temp = *c; #define RR_DONE -1
*c = 0;
if (strcmp(token,t) == 0) {
Super_add(str,rep);
count--;
repcount++;
} else {
Super_add(str,t);
}
*c = temp;
t = c;
state = 0; 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)
{
char after= *(match + tokenlen);
if (after == '_' || after == '$' || isalnum(after))
{
match += tokenlen;
state = RR_INSIDE_IDENTIFIER;
continue;
} }
}
/* 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; break;
case 20: /* A Super */
if (*c == '\"') state = 0; case RR_IN_IDENTIFIER:
else if (*c == '\\') c++; if (!(isalnum(*match) || (*match == '_') || (*match == '$')))
state = RR_BEGIN_MATCH;
break; break;
case 30: /* A Single quoted Super */
if (*c == '\'') state = 0; case RR_IN_DOUBLE_QUOTES:
else if (*c == '\\') c++; 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; break;
} }
c++;
} match++;
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);
} }
/* 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; return repcount;
} }
#endif