Finished writing the thing -- I think
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk/SWIG@104 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
parent
67940725e8
commit
e24104982b
1 changed files with 700 additions and 608 deletions
|
|
@ -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
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue