reverted to TCL version of regex library

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@25865 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Václav Slavík
2004-02-19 16:47:02 +00:00
parent bf25c88b6a
commit 3ca4086b22
14 changed files with 4958 additions and 4879 deletions

View File

@@ -28,7 +28,6 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Header$
*
*
* Note that there are some incestuous relationships between this code and
@@ -43,11 +42,13 @@
/*
* initcm - set up new colormap
- initcm - set up new colormap
^ static VOID initcm(struct vars *, struct colormap *);
*/
static void
initcm(struct vars * v,
struct colormap * cm)
static VOID
initcm(v, cm)
struct vars *v;
struct colormap *cm;
{
int i;
int j;
@@ -70,24 +71,25 @@ initcm(struct vars * v,
cd->nchrs = CHR_MAX - CHR_MIN + 1;
/* upper levels of tree */
for (t = &cm->tree[0], j = NBYTS - 1; j > 0; t = nextt, j--)
{
for (t = &cm->tree[0], j = NBYTS-1; j > 0; t = nextt, j--) {
nextt = t + 1;
for (i = BYTTAB - 1; i >= 0; i--)
for (i = BYTTAB-1; i >= 0; i--)
t->tptr[i] = nextt;
}
/* bottom level is solid white */
t = &cm->tree[NBYTS - 1];
for (i = BYTTAB - 1; i >= 0; i--)
t = &cm->tree[NBYTS-1];
for (i = BYTTAB-1; i >= 0; i--)
t->tcolor[i] = WHITE;
cd->block = t;
}
/*
* freecm - free dynamically-allocated things in a colormap
- freecm - free dynamically-allocated things in a colormap
^ static VOID freecm(struct colormap *);
*/
static void
freecm(struct colormap * cm)
static VOID
freecm(cm)
struct colormap *cm;
{
size_t i;
union tree *cb;
@@ -96,8 +98,7 @@ freecm(struct colormap * cm)
if (NBYTS > 1)
cmtreefree(cm, cm->tree, 0);
for (i = 1; i <= cm->max; i++) /* skip WHITE */
if (!UNUSEDCOLOR(&cm->cd[i]))
{
if (!UNUSEDCOLOR(&cm->cd[i])) {
cb = cm->cd[i].block;
if (cb != NULL)
FREE(cb);
@@ -107,32 +108,29 @@ freecm(struct colormap * cm)
}
/*
* cmtreefree - free a non-terminal part of a colormap tree
- cmtreefree - free a non-terminal part of a colormap tree
^ static VOID cmtreefree(struct colormap *, union tree *, int);
*/
static void
cmtreefree(struct colormap * cm,
union tree * tree,
int level) /* level number (top == 0) of this block */
static VOID
cmtreefree(cm, tree, level)
struct colormap *cm;
union tree *tree;
int level; /* level number (top == 0) of this block */
{
int i;
union tree *t;
union tree *fillt = &cm->tree[level + 1];
union tree *fillt = &cm->tree[level+1];
union tree *cb;
assert(level < NBYTS - 1); /* this level has pointers */
for (i = BYTTAB - 1; i >= 0; i--)
{
assert(level < NBYTS-1); /* this level has pointers */
for (i = BYTTAB-1; i >= 0; i--) {
t = tree->tptr[i];
assert(t != NULL);
if (t != fillt)
{
if (level < NBYTS - 2)
{ /* more pointer blocks below */
cmtreefree(cm, t, level + 1);
if (t != fillt) {
if (level < NBYTS-2) { /* more pointer blocks below */
cmtreefree(cm, t, level+1);
FREE(t);
}
else
{ /* color block below */
} else { /* color block below */
cb = cm->cd[t->tcolor[0]].block;
if (t != cb) /* not a solid block */
FREE(t);
@@ -142,12 +140,14 @@ cmtreefree(struct colormap * cm,
}
/*
* setcolor - set the color of a character in a colormap
- setcolor - set the color of a character in a colormap
^ static color setcolor(struct colormap *, pchr, pcolor);
*/
static color /* previous color */
setcolor(struct colormap * cm,
chr c,
pcolor co)
setcolor(cm, c, co)
struct colormap *cm;
pchr c;
pcolor co;
{
uchr uc = c;
int shift;
@@ -167,30 +167,27 @@ setcolor(struct colormap * cm,
t = cm->tree;
for (level = 0, shift = BYTBITS * (NBYTS - 1); shift > 0;
level++, shift -= BYTBITS)
{
level++, shift -= BYTBITS) {
b = (uc >> shift) & BYTMASK;
lastt = t;
t = lastt->tptr[b];
assert(t != NULL);
fillt = &cm->tree[level + 1];
fillt = &cm->tree[level+1];
bottom = (shift <= BYTBITS) ? 1 : 0;
cb = (bottom) ? cm->cd[t->tcolor[0]].block : fillt;
if (t == fillt || t == cb)
{ /* must allocate a new block */
newt = (union tree *) MALLOC((bottom) ?
if (t == fillt || t == cb) { /* must allocate a new block */
newt = (union tree *)MALLOC((bottom) ?
sizeof(struct colors) : sizeof(struct ptrs));
if (newt == NULL)
{
if (newt == NULL) {
CERR(REG_ESPACE);
return COLORLESS;
}
if (bottom)
memcpy(VS(newt->tcolor), VS(t->tcolor),
BYTTAB * sizeof(color));
BYTTAB*sizeof(color));
else
memcpy(VS(newt->tptr), VS(t->tptr),
BYTTAB * sizeof(union tree *));
BYTTAB*sizeof(union tree *));
t = newt;
lastt->tptr[b] = t;
}
@@ -198,28 +195,32 @@ setcolor(struct colormap * cm,
b = uc & BYTMASK;
prev = t->tcolor[b];
t->tcolor[b] = (color) co;
t->tcolor[b] = (color)co;
return prev;
}
/*
* maxcolor - report largest color number in use
- maxcolor - report largest color number in use
^ static color maxcolor(struct colormap *);
*/
static color
maxcolor(struct colormap * cm)
maxcolor(cm)
struct colormap *cm;
{
if (CISERR())
return COLORLESS;
return (color) cm->max;
return (color)cm->max;
}
/*
* newcolor - find a new color (must be subject of setcolor at once)
- newcolor - find a new color (must be subject of setcolor at once)
* Beware: may relocate the colordescs.
^ static color newcolor(struct colormap *);
*/
static color /* COLORLESS for error */
newcolor(struct colormap * cm)
newcolor(cm)
struct colormap *cm;
{
struct colordesc *cd;
struct colordesc *new;
@@ -228,37 +229,29 @@ newcolor(struct colormap * cm)
if (CISERR())
return COLORLESS;
if (cm->free != 0)
{
if (cm->free != 0) {
assert(cm->free > 0);
assert((size_t) cm->free < cm->ncds);
assert((size_t)cm->free < cm->ncds);
cd = &cm->cd[cm->free];
assert(UNUSEDCOLOR(cd));
assert(cd->arcs == NULL);
cm->free = cd->sub;
}
else if (cm->max < cm->ncds - 1)
{
} else if (cm->max < cm->ncds - 1) {
cm->max++;
cd = &cm->cd[cm->max];
}
else
{
} else {
/* oops, must allocate more */
n = cm->ncds * 2;
if (cm->cd == cm->cdspace)
{
new = (struct colordesc *) MALLOC(n *
if (cm->cd == cm->cdspace) {
new = (struct colordesc *)MALLOC(n *
sizeof(struct colordesc));
if (new != NULL)
memcpy(VS(new), VS(cm->cdspace), cm->ncds *
sizeof(struct colordesc));
}
else
new = (struct colordesc *) REALLOC(cm->cd,
} else
new = (struct colordesc *)REALLOC(cm->cd,
n * sizeof(struct colordesc));
if (new == NULL)
{
if (new == NULL) {
CERR(REG_ESPACE);
return COLORLESS;
}
@@ -275,19 +268,20 @@ newcolor(struct colormap * cm)
cd->flags = 0;
cd->block = NULL;
return (color) (cd - cm->cd);
return (color)(cd - cm->cd);
}
/*
* freecolor - free a color (must have no arcs or subcolor)
- freecolor - free a color (must have no arcs or subcolor)
^ static VOID freecolor(struct colormap *, pcolor);
*/
static void
freecolor(struct colormap * cm,
pcolor co)
static VOID
freecolor(cm, co)
struct colormap *cm;
pcolor co;
{
struct colordesc *cd = &cm->cd[co];
color pco,
nco; /* for freelist scan */
color pco, nco; /* for freelist scan */
assert(co >= 0);
if (co == WHITE)
@@ -297,51 +291,45 @@ freecolor(struct colormap * cm,
assert(cd->sub == NOSUB);
assert(cd->nchrs == 0);
cd->flags = FREECOL;
if (cd->block != NULL)
{
if (cd->block != NULL) {
FREE(cd->block);
cd->block = NULL; /* just paranoia */
}
if ((size_t) co == cm->max)
{
if ((size_t)co == cm->max) {
while (cm->max > WHITE && UNUSEDCOLOR(&cm->cd[cm->max]))
cm->max--;
assert(cm->free >= 0);
while ((size_t) cm->free > cm->max)
while ((size_t)cm->free > cm->max)
cm->free = cm->cd[cm->free].sub;
if (cm->free > 0)
{
if (cm->free > 0) {
assert(cm->free < cm->max);
pco = cm->free;
nco = cm->cd[pco].sub;
while (nco > 0)
if ((size_t) nco > cm->max)
{
if ((size_t)nco > cm->max) {
/* take this one out of freelist */
nco = cm->cd[nco].sub;
cm->cd[pco].sub = nco;
}
else
{
} else {
assert(nco < cm->max);
pco = nco;
nco = cm->cd[pco].sub;
}
}
}
else
{
} else {
cd->sub = cm->free;
cm->free = (color) (cd - cm->cd);
cm->free = (color)(cd - cm->cd);
}
}
/*
* pseudocolor - allocate a false color, to be managed by other means
- pseudocolor - allocate a false color, to be managed by other means
^ static color pseudocolor(struct colormap *);
*/
static color
pseudocolor(struct colormap * cm)
pseudocolor(cm)
struct colormap *cm;
{
color co;
@@ -354,10 +342,13 @@ pseudocolor(struct colormap * cm)
}
/*
* subcolor - allocate a new subcolor (if necessary) to this chr
- subcolor - allocate a new subcolor (if necessary) to this chr
^ static color subcolor(struct colormap *, pchr c);
*/
static color
subcolor(struct colormap * cm, chr c)
subcolor(cm, c)
struct colormap *cm;
pchr c;
{
color co; /* current color of c */
color sco; /* new subcolor */
@@ -377,22 +368,22 @@ subcolor(struct colormap * cm, chr c)
}
/*
* newsub - allocate a new subcolor (if necessary) for a color
- newsub - allocate a new subcolor (if necessary) for a color
^ static color newsub(struct colormap *, pcolor);
*/
static color
newsub(struct colormap * cm,
pcolor co)
newsub(cm, co)
struct colormap *cm;
pcolor co;
{
color sco; /* new subcolor */
sco = cm->cd[co].sub;
if (sco == NOSUB)
{ /* color has no open subcolor */
if (sco == NOSUB) { /* color has no open subcolor */
if (cm->cd[co].nchrs == 1) /* optimization */
return co;
sco = newcolor(cm); /* must create subcolor */
if (sco == COLORLESS)
{
if (sco == COLORLESS) {
assert(CISERR());
return COLORLESS;
}
@@ -405,14 +396,17 @@ newsub(struct colormap * cm,
}
/*
* subrange - allocate new subcolors to this range of chrs, fill in arcs
- subrange - allocate new subcolors to this range of chrs, fill in arcs
^ static VOID subrange(struct vars *, pchr, pchr, struct state *,
^ struct state *);
*/
static void
subrange(struct vars * v,
chr from,
chr to,
struct state * lp,
struct state * rp)
static VOID
subrange(v, from, to, lp, rp)
struct vars *v;
pchr from;
pchr to;
struct state *lp;
struct state *rp;
{
uchr uf;
int i;
@@ -420,8 +414,8 @@ subrange(struct vars * v,
assert(from <= to);
/* first, align "from" on a tree-block boundary */
uf = (uchr) from;
i = (int) (((uf + BYTTAB - 1) & (uchr) ~BYTMASK) - uf);
uf = (uchr)from;
i = (int)( ((uf + BYTTAB-1) & (uchr)~BYTMASK) - uf );
for (; from <= to && i > 0; i--, from++)
newarc(v->nfa, PLAIN, subcolor(v->cm, from), lp, rp);
if (from > to) /* didn't reach a boundary */
@@ -437,13 +431,15 @@ subrange(struct vars * v,
}
/*
* subblock - allocate new subcolors for one tree block of chrs, fill in arcs
- subblock - allocate new subcolors for one tree block of chrs, fill in arcs
^ static VOID subblock(struct vars *, pchr, struct state *, struct state *);
*/
static void
subblock(struct vars * v,
chr start, /* first of BYTTAB chrs */
struct state * lp,
struct state * rp)
static VOID
subblock(v, start, lp, rp)
struct vars *v;
pchr start; /* first of BYTTAB chrs */
struct state *lp;
struct state *rp;
{
uchr uc = start;
struct colormap *cm = v->cm;
@@ -466,23 +462,20 @@ subblock(struct vars * v,
t = cm->tree;
fillt = NULL;
for (level = 0, shift = BYTBITS * (NBYTS - 1); shift > 0;
level++, shift -= BYTBITS)
{
level++, shift -= BYTBITS) {
b = (uc >> shift) & BYTMASK;
lastt = t;
t = lastt->tptr[b];
assert(t != NULL);
fillt = &cm->tree[level + 1];
if (t == fillt && shift > BYTBITS)
{ /* need new ptr block */
t = (union tree *) MALLOC(sizeof(struct ptrs));
if (t == NULL)
{
fillt = &cm->tree[level+1];
if (t == fillt && shift > BYTBITS) { /* need new ptr block */
t = (union tree *)MALLOC(sizeof(struct ptrs));
if (t == NULL) {
CERR(REG_ESPACE);
return;
}
memcpy(VS(t->tptr), VS(fillt->tptr),
BYTTAB * sizeof(union tree *));
BYTTAB*sizeof(union tree *));
lastt->tptr[b] = t;
}
}
@@ -490,16 +483,13 @@ subblock(struct vars * v,
/* special cases: fill block or solid block */
co = t->tcolor[0];
cb = cm->cd[co].block;
if (t == fillt || t == cb)
{
if (t == fillt || t == cb) {
/* either way, we want a subcolor solid block */
sco = newsub(cm, co);
t = cm->cd[sco].block;
if (t == NULL)
{ /* must set it up */
t = (union tree *) MALLOC(sizeof(struct colors));
if (t == NULL)
{
if (t == NULL) { /* must set it up */
t = (union tree *)MALLOC(sizeof(struct colors));
if (t == NULL) {
CERR(REG_ESPACE);
return;
}
@@ -517,14 +507,12 @@ subblock(struct vars * v,
/* general case, a mixed block to be altered */
i = 0;
while (i < BYTTAB)
{
while (i < BYTTAB) {
co = t->tcolor[i];
sco = newsub(cm, co);
newarc(v->nfa, PLAIN, sco, lp, rp);
previ = i;
do
{
do {
t->tcolor[i++] = sco;
} while (i < BYTTAB && t->tcolor[i] == co);
ndone = i - previ;
@@ -534,11 +522,13 @@ subblock(struct vars * v,
}
/*
* okcolors - promote subcolors to full colors
- okcolors - promote subcolors to full colors
^ static VOID okcolors(struct nfa *, struct colormap *);
*/
static void
okcolors(struct nfa * nfa,
struct colormap * cm)
static VOID
okcolors(nfa, cm)
struct nfa *nfa;
struct colormap *cm;
{
struct colordesc *cd;
struct colordesc *end = CDEND(cm);
@@ -547,27 +537,20 @@ okcolors(struct nfa * nfa,
color co;
color sco;
for (cd = cm->cd, co = 0; cd < end; cd++, co++)
{
for (cd = cm->cd, co = 0; cd < end; cd++, co++) {
sco = cd->sub;
if (UNUSEDCOLOR(cd) || sco == NOSUB)
{
if (UNUSEDCOLOR(cd) || sco == NOSUB) {
/* has no subcolor, no further action */
}
else if (sco == co)
{
} else if (sco == co) {
/* is subcolor, let parent deal with it */
}
else if (cd->nchrs == 0)
{
} else if (cd->nchrs == 0) {
/* parent empty, its arcs change color to subcolor */
cd->sub = NOSUB;
scd = &cm->cd[sco];
assert(scd->nchrs > 0);
assert(scd->sub == sco);
scd->sub = NOSUB;
while ((a = cd->arcs) != NULL)
{
while ((a = cd->arcs) != NULL) {
assert(a->co == co);
/* uncolorchain(cm, a); */
cd->arcs = a->colorchain;
@@ -577,17 +560,14 @@ okcolors(struct nfa * nfa,
scd->arcs = a;
}
freecolor(cm, co);
}
else
{
} else {
/* parent's arcs must gain parallel subcolor arcs */
cd->sub = NOSUB;
scd = &cm->cd[sco];
assert(scd->nchrs > 0);
assert(scd->sub == sco);
scd->sub = NOSUB;
for (a = cd->arcs; a != NULL; a = a->colorchain)
{
for (a = cd->arcs; a != NULL; a = a->colorchain) {
assert(a->co == co);
newarc(nfa, a->type, sco, a->from, a->to);
}
@@ -596,11 +576,13 @@ okcolors(struct nfa * nfa,
}
/*
* colorchain - add this arc to the color chain of its color
- colorchain - add this arc to the color chain of its color
^ static VOID colorchain(struct colormap *, struct arc *);
*/
static void
colorchain(struct colormap * cm,
struct arc * a)
static VOID
colorchain(cm, a)
struct colormap *cm;
struct arc *a;
{
struct colordesc *cd = &cm->cd[a->co];
@@ -609,11 +591,13 @@ colorchain(struct colormap * cm,
}
/*
* uncolorchain - delete this arc from the color chain of its color
- uncolorchain - delete this arc from the color chain of its color
^ static VOID uncolorchain(struct colormap *, struct arc *);
*/
static void
uncolorchain(struct colormap * cm,
struct arc * a)
static VOID
uncolorchain(cm, a)
struct colormap *cm;
struct arc *a;
{
struct colordesc *cd = &cm->cd[a->co];
struct arc *aa;
@@ -621,8 +605,7 @@ uncolorchain(struct colormap * cm,
aa = cd->arcs;
if (aa == a) /* easy case */
cd->arcs = a->colorchain;
else
{
else {
for (; aa != NULL && aa->colorchain != a; aa = aa->colorchain)
continue;
assert(aa != NULL);
@@ -632,11 +615,13 @@ uncolorchain(struct colormap * cm,
}
/*
* singleton - is this character in its own color?
- singleton - is this character in its own color?
^ static int singleton(struct colormap *, pchr c);
*/
static int /* predicate */
singleton(struct colormap * cm,
chr c)
singleton(cm, c)
struct colormap *cm;
pchr c;
{
color co; /* color of c */
@@ -647,15 +632,18 @@ singleton(struct colormap * cm,
}
/*
* rainbow - add arcs of all full colors (but one) between specified states
- rainbow - add arcs of all full colors (but one) between specified states
^ static VOID rainbow(struct nfa *, struct colormap *, int, pcolor,
^ struct state *, struct state *);
*/
static void
rainbow(struct nfa * nfa,
struct colormap * cm,
int type,
pcolor but, /* COLORLESS if no exceptions */
struct state * from,
struct state * to)
static VOID
rainbow(nfa, cm, type, but, from, to)
struct nfa *nfa;
struct colormap *cm;
int type;
pcolor but; /* COLORLESS if no exceptions */
struct state *from;
struct state *to;
{
struct colordesc *cd;
struct colordesc *end = CDEND(cm);
@@ -663,23 +651,24 @@ rainbow(struct nfa * nfa,
for (cd = cm->cd, co = 0; cd < end && !CISERR(); cd++, co++)
if (!UNUSEDCOLOR(cd) && cd->sub != co && co != but &&
!(cd->flags & PSEUDO))
!(cd->flags&PSEUDO))
newarc(nfa, type, co, from, to);
}
/*
* colorcomplement - add arcs of complementary colors
*
- colorcomplement - add arcs of complementary colors
* The calling sequence ought to be reconciled with cloneouts().
^ static VOID colorcomplement(struct nfa *, struct colormap *, int,
^ struct state *, struct state *, struct state *);
*/
static void
colorcomplement(struct nfa * nfa,
struct colormap * cm,
int type,
struct state * of, /* complements of this guy's PLAIN
* outarcs */
struct state * from,
struct state * to)
static VOID
colorcomplement(nfa, cm, type, of, from, to)
struct nfa *nfa;
struct colormap *cm;
int type;
struct state *of; /* complements of this guy's PLAIN outarcs */
struct state *from;
struct state *to;
{
struct colordesc *cd;
struct colordesc *end = CDEND(cm);
@@ -687,20 +676,26 @@ colorcomplement(struct nfa * nfa,
assert(of != from);
for (cd = cm->cd, co = 0; cd < end && !CISERR(); cd++, co++)
if (!UNUSEDCOLOR(cd) && !(cd->flags & PSEUDO))
if (!UNUSEDCOLOR(cd) && !(cd->flags&PSEUDO))
if (findarc(of, PLAIN, co) == NULL)
newarc(nfa, type, co, from, to);
}
#ifdef REG_DEBUG
/*
^ #ifdef REG_DEBUG
*/
/*
* dumpcolors - debugging output
- dumpcolors - debugging output
^ static VOID dumpcolors(struct colormap *, FILE *);
*/
static void
dumpcolors(struct colormap * cm,
FILE *f)
static VOID
dumpcolors(cm, f)
struct colormap *cm;
FILE *f;
{
struct colordesc *cd;
struct colordesc *end;
@@ -708,19 +703,18 @@ dumpcolors(struct colormap * cm,
chr c;
char *has;
fprintf(f, "max %ld\n", (long) cm->max);
fprintf(f, "max %ld\n", (long)cm->max);
if (NBYTS > 1)
fillcheck(cm, cm->tree, 0, f);
end = CDEND(cm);
for (cd = cm->cd + 1, co = 1; cd < end; cd++, co++) /* skip 0 */
if (!UNUSEDCOLOR(cd))
{
if (!UNUSEDCOLOR(cd)) {
assert(cd->nchrs > 0);
has = (cd->block != NULL) ? "#" : "";
if (cd->flags & PSEUDO)
fprintf(f, "#%2ld%s(ps): ", (long) co, has);
if (cd->flags&PSEUDO)
fprintf(f, "#%2ld%s(ps): ", (long)co, has);
else
fprintf(f, "#%2ld%s(%2d): ", (long) co,
fprintf(f, "#%2ld%s(%2d): ", (long)co,
has, cd->nchrs);
/* it's hard to do this more efficiently */
for (c = CHR_MIN; c < CHR_MAX; c++)
@@ -734,51 +728,51 @@ dumpcolors(struct colormap * cm,
}
/*
* fillcheck - check proper filling of a tree
- fillcheck - check proper filling of a tree
^ static VOID fillcheck(struct colormap *, union tree *, int, FILE *);
*/
static void
fillcheck(struct colormap * cm,
union tree * tree,
int level, /* level number (top == 0) of this block */
FILE *f)
static VOID
fillcheck(cm, tree, level, f)
struct colormap *cm;
union tree *tree;
int level; /* level number (top == 0) of this block */
FILE *f;
{
int i;
union tree *t;
union tree *fillt = &cm->tree[level + 1];
union tree *fillt = &cm->tree[level+1];
assert(level < NBYTS - 1); /* this level has pointers */
for (i = BYTTAB - 1; i >= 0; i--)
{
assert(level < NBYTS-1); /* this level has pointers */
for (i = BYTTAB-1; i >= 0; i--) {
t = tree->tptr[i];
if (t == NULL)
fprintf(f, "NULL found in filled tree!\n");
else if (t == fillt)
{
}
else if (level < NBYTS - 2) /* more pointer blocks below */
fillcheck(cm, t, level + 1, f);
{}
else if (level < NBYTS-2) /* more pointer blocks below */
fillcheck(cm, t, level+1, f);
}
}
/*
* dumpchr - print a chr
*
- dumpchr - print a chr
* Kind of char-centric but works well enough for debug use.
^ static VOID dumpchr(pchr, FILE *);
*/
static void
dumpchr(chr c,
FILE *f)
static VOID
dumpchr(c, f)
pchr c;
FILE *f;
{
#if wxUSE_UNICODE
fprintf(f, "Debugging not implemented in unicode mode");
#else
if (c == '\\')
fprintf(f, "\\\\");
else if (c > ' ' && c <= '~')
putc((char) c, f);
putc((char)c, f);
else
fprintf(f, "\\u%04lx", (long) c);
#endif
fprintf(f, "\\u%04lx", (long)c);
}
#endif /* REG_DEBUG */
/*
^ #endif
*/
#endif /* ifdef REG_DEBUG */

View File

@@ -28,162 +28,181 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Header$
*
*/
/*
* newcvec - allocate a new cvec
- newcvec - allocate a new cvec
^ static struct cvec *newcvec(int, int, int);
*/
static struct cvec *
newcvec(int nchrs, /* to hold this many chrs... */
int nranges, /* ... and this many ranges... */
int nmcces) /* ... and this many MCCEs */
newcvec(nchrs, nranges, nmcces)
int nchrs; /* to hold this many chrs... */
int nranges; /* ... and this many ranges... */
int nmcces; /* ... and this many MCCEs */
{
size_t n;
size_t nc;
struct cvec *cv;
nc = (size_t) nchrs + (size_t) nmcces *(MAXMCCE + 1) + (size_t) nranges *2;
n = sizeof(struct cvec) + (size_t) (nmcces - 1) * sizeof(chr *)
+ nc * sizeof(chr);
cv = (struct cvec *) MALLOC(n);
if (cv == NULL)
nc = (size_t)nchrs + (size_t)nmcces*(MAXMCCE+1) + (size_t)nranges*2;
n = sizeof(struct cvec) + (size_t)(nmcces-1)*sizeof(chr *)
+ nc*sizeof(chr);
cv = (struct cvec *)MALLOC(n);
if (cv == NULL) {
return NULL;
}
cv->chrspace = nchrs;
cv->chrs = (chr *) &cv->mcces[nmcces]; /* chrs just after MCCE
* ptrs */
cv->chrs = (chr *)&cv->mcces[nmcces]; /* chrs just after MCCE ptrs */
cv->mccespace = nmcces;
cv->ranges = cv->chrs + nchrs + nmcces * (MAXMCCE + 1);
cv->ranges = cv->chrs + nchrs + nmcces*(MAXMCCE+1);
cv->rangespace = nranges;
return clearcvec(cv);
}
/*
* clearcvec - clear a possibly-new cvec
- clearcvec - clear a possibly-new cvec
* Returns pointer as convenience.
^ static struct cvec *clearcvec(struct cvec *);
*/
static struct cvec *
clearcvec(struct cvec * cv)
clearcvec(cv)
struct cvec *cv; /* character vector */
{
int i;
assert(cv != NULL);
cv->nchrs = 0;
assert(cv->chrs == (chr *) &cv->mcces[cv->mccespace]);
assert(cv->chrs == (chr *)&cv->mcces[cv->mccespace]);
cv->nmcces = 0;
cv->nmccechrs = 0;
cv->nranges = 0;
for (i = 0; i < cv->mccespace; i++)
for (i = 0; i < cv->mccespace; i++) {
cv->mcces[i] = NULL;
}
return cv;
}
/*
* addchr - add a chr to a cvec
- addchr - add a chr to a cvec
^ static VOID addchr(struct cvec *, pchr);
*/
static void
addchr(struct cvec * cv, /* character vector */
chr c) /* character to add */
static VOID
addchr(cv, c)
struct cvec *cv; /* character vector */
pchr c; /* character to add */
{
assert(cv->nchrs < cv->chrspace - cv->nmccechrs);
cv->chrs[cv->nchrs++] = (chr) c;
cv->chrs[cv->nchrs++] = (chr)c;
}
/*
* addrange - add a range to a cvec
- addrange - add a range to a cvec
^ static VOID addrange(struct cvec *, pchr, pchr);
*/
static void
addrange(struct cvec * cv, /* character vector */
chr from, /* first character of range */
chr to) /* last character of range */
static VOID
addrange(cv, from, to)
struct cvec *cv; /* character vector */
pchr from; /* first character of range */
pchr to; /* last character of range */
{
assert(cv->nranges < cv->rangespace);
cv->ranges[cv->nranges * 2] = (chr) from;
cv->ranges[cv->nranges * 2 + 1] = (chr) to;
cv->ranges[cv->nranges*2] = (chr)from;
cv->ranges[cv->nranges*2 + 1] = (chr)to;
cv->nranges++;
}
/*
* addmcce - add an MCCE to a cvec
- addmcce - add an MCCE to a cvec
^ static VOID addmcce(struct cvec *, chr *, chr *);
*/
static void
addmcce(struct cvec * cv, /* character vector */
chr *startp, /* beginning of text */
chr *endp) /* just past end of text */
static VOID
addmcce(cv, startp, endp)
struct cvec *cv; /* character vector */
chr *startp; /* beginning of text */
chr *endp; /* just past end of text */
{
int len;
int i;
chr *s;
chr *d;
if (startp == NULL && endp == NULL)
if (startp == NULL && endp == NULL) {
return;
}
len = endp - startp;
assert(len > 0);
assert(cv->nchrs + len < cv->chrspace - cv->nmccechrs);
assert(cv->nmcces < cv->mccespace);
d = &cv->chrs[cv->chrspace - cv->nmccechrs - len - 1];
cv->mcces[cv->nmcces++] = d;
for (s = startp, i = len; i > 0; s++, i--)
for (s = startp, i = len; i > 0; s++, i--) {
*d++ = *s;
}
*d++ = 0; /* endmarker */
assert(d == &cv->chrs[cv->chrspace - cv->nmccechrs]);
cv->nmccechrs += len + 1;
}
/*
* haschr - does a cvec contain this chr?
- haschr - does a cvec contain this chr?
^ static int haschr(struct cvec *, pchr);
*/
static int /* predicate */
haschr(struct cvec * cv, /* character vector */
chr c) /* character to test for */
haschr(cv, c)
struct cvec *cv; /* character vector */
pchr c; /* character to test for */
{
int i;
chr *p;
for (p = cv->chrs, i = cv->nchrs; i > 0; p++, i--)
{
if (*p == c)
for (p = cv->chrs, i = cv->nchrs; i > 0; p++, i--) {
if (*p == c) {
return 1;
}
for (p = cv->ranges, i = cv->nranges; i > 0; p += 2, i--)
{
if ((*p <= c) && (c <= *(p + 1)))
}
for (p = cv->ranges, i = cv->nranges; i > 0; p += 2, i--) {
if ((*p <= c) && (c <= *(p+1))) {
return 1;
}
}
return 0;
}
/*
* getcvec - get a cvec, remembering it as v->cv
- getcvec - get a cvec, remembering it as v->cv
^ static struct cvec *getcvec(struct vars *, int, int, int);
*/
static struct cvec *
getcvec(struct vars * v, /* context */
int nchrs, /* to hold this many chrs... */
int nranges, /* ... and this many ranges... */
int nmcces) /* ... and this many MCCEs */
getcvec(v, nchrs, nranges, nmcces)
struct vars *v; /* context */
int nchrs; /* to hold this many chrs... */
int nranges; /* ... and this many ranges... */
int nmcces; /* ... and this many MCCEs */
{
if (v->cv != NULL && nchrs <= v->cv->chrspace &&
nranges <= v->cv->rangespace && nmcces <= v->cv->mccespace)
nranges <= v->cv->rangespace && nmcces <= v->cv->mccespace) {
return clearcvec(v->cv);
}
if (v->cv != NULL)
if (v->cv != NULL) {
freecvec(v->cv);
}
v->cv = newcvec(nchrs, nranges, nmcces);
if (v->cv == NULL)
if (v->cv == NULL) {
ERR(REG_ESPACE);
}
return v->cv;
}
/*
* freecvec - free a cvec
- freecvec - free a cvec
^ static VOID freecvec(struct cvec *);
*/
static void
freecvec(struct cvec * cv)
static VOID
freecvec(cv)
struct cvec *cv; /* character vector */
{
FREE(cv);
}

View File

@@ -28,8 +28,6 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Header$
*
*/
/* scanning macros (know about v) */
@@ -64,27 +62,24 @@
#define ENDOF(array) ((array) + sizeof(array)/sizeof(chr))
/*
* lexstart - set up lexical stuff, scan leading options
- lexstart - set up lexical stuff, scan leading options
^ static VOID lexstart(struct vars *);
*/
static void
lexstart(struct vars * v)
static VOID
lexstart(v)
struct vars *v;
{
prefixes(v); /* may turn on new type bits etc. */
NOERR();
if (v->cflags & REG_QUOTE)
{
assert(!(v->cflags & (REG_ADVANCED | REG_EXPANDED | REG_NEWLINE)));
if (v->cflags&REG_QUOTE) {
assert(!(v->cflags&(REG_ADVANCED|REG_EXPANDED|REG_NEWLINE)));
INTOCON(L_Q);
}
else if (v->cflags & REG_EXTENDED)
{
assert(!(v->cflags & REG_QUOTE));
} else if (v->cflags&REG_EXTENDED) {
assert(!(v->cflags&REG_QUOTE));
INTOCON(L_ERE);
}
else
{
assert(!(v->cflags & (REG_QUOTE | REG_ADVF)));
} else {
assert(!(v->cflags&(REG_QUOTE|REG_ADVF)));
INTOCON(L_BRE);
}
@@ -93,19 +88,20 @@ lexstart(struct vars * v)
}
/*
* prefixes - implement various special prefixes
- prefixes - implement various special prefixes
^ static VOID prefixes(struct vars *);
*/
static void
prefixes(struct vars * v)
static VOID
prefixes(v)
struct vars *v;
{
/* literal string doesn't get any of this stuff */
if (v->cflags & REG_QUOTE)
if (v->cflags&REG_QUOTE)
return;
/* initial "***" gets special things */
if (HAVE(4) && NEXT3('*', '*', '*'))
switch (*(v->now + 3))
{
switch (*(v->now + 3)) {
case CHR('?'): /* "***?" error, msg shows version */
ERR(REG_BADPAT);
return; /* proceed no further */
@@ -113,7 +109,7 @@ prefixes(struct vars * v)
case CHR('='): /* "***=" shifts to literal string */
NOTE(REG_UNONPOSIX);
v->cflags |= REG_QUOTE;
v->cflags &= ~(REG_ADVANCED | REG_EXPANDED | REG_NEWLINE);
v->cflags &= ~(REG_ADVANCED|REG_EXPANDED|REG_NEWLINE);
v->now += 4;
return; /* and there can be no more prefixes */
break;
@@ -129,26 +125,24 @@ prefixes(struct vars * v)
}
/* BREs and EREs don't get embedded options */
if ((v->cflags & REG_ADVANCED) != REG_ADVANCED)
if ((v->cflags&REG_ADVANCED) != REG_ADVANCED)
return;
/* embedded options (AREs only) */
if (HAVE(3) && NEXT2('(', '?') && iscalpha(*(v->now + 2)))
{
if (HAVE(3) && NEXT2('(', '?') && iscalpha(*(v->now + 2))) {
NOTE(REG_UNONPOSIX);
v->now += 2;
for (; !ATEOS() && iscalpha(*v->now); v->now++)
switch (*v->now)
{
switch (*v->now) {
case CHR('b'): /* BREs (but why???) */
v->cflags &= ~(REG_ADVANCED | REG_QUOTE);
v->cflags &= ~(REG_ADVANCED|REG_QUOTE);
break;
case CHR('c'): /* case sensitive */
v->cflags &= ~REG_ICASE;
break;
case CHR('e'): /* plain EREs */
v->cflags |= REG_EXTENDED;
v->cflags &= ~(REG_ADVF | REG_QUOTE);
v->cflags &= ~(REG_ADVF|REG_QUOTE);
break;
case CHR('i'): /* case insensitive */
v->cflags |= REG_ICASE;
@@ -182,27 +176,27 @@ prefixes(struct vars * v)
ERR(REG_BADOPT);
return;
}
if (!NEXT1(')'))
{
if (!NEXT1(')')) {
ERR(REG_BADOPT);
return;
}
v->now++;
if (v->cflags & REG_QUOTE)
v->cflags &= ~(REG_EXPANDED | REG_NEWLINE);
if (v->cflags&REG_QUOTE)
v->cflags &= ~(REG_EXPANDED|REG_NEWLINE);
}
}
/*
* lexnest - "call a subroutine", interpolating string at the lexical level
*
- lexnest - "call a subroutine", interpolating string at the lexical level
* Note, this is not a very general facility. There are a number of
* implicit assumptions about what sorts of strings can be subroutines.
^ static VOID lexnest(struct vars *, chr *, chr *);
*/
static void
lexnest(struct vars * v,
chr *beginp, /* start of interpolation */
chr *endp) /* one past end of interpolation */
static VOID
lexnest(v, beginp, endp)
struct vars *v;
chr *beginp; /* start of interpolation */
chr *endp; /* one past end of interpolation */
{
assert(v->savenow == NULL); /* only one level of nesting */
v->savenow = v->now;
@@ -261,20 +255,24 @@ static chr brbackw[] = { /* \w within brackets */
};
/*
* lexword - interpolate a bracket expression for word characters
- lexword - interpolate a bracket expression for word characters
* Possibly ought to inquire whether there is a "word" character class.
^ static VOID lexword(struct vars *);
*/
static void
lexword(struct vars * v)
static VOID
lexword(v)
struct vars *v;
{
lexnest(v, backw, ENDOF(backw));
}
/*
* next - get next token
- next - get next token
^ static int next(struct vars *);
*/
static int /* 1 normal, 0 failure */
next(struct vars * v)
next(v)
struct vars *v;
{
chr c;
@@ -286,24 +284,21 @@ next(struct vars * v)
v->lasttype = v->nexttype;
/* REG_BOSONLY */
if (v->nexttype == EMPTY && (v->cflags & REG_BOSONLY))
{
if (v->nexttype == EMPTY && (v->cflags&REG_BOSONLY)) {
/* at start of a REG_BOSONLY RE */
RETV(SBEGIN, 0); /* same as \A */
}
/* if we're nested and we've hit end, return to outer level */
if (v->savenow != NULL && ATEOS())
{
if (v->savenow != NULL && ATEOS()) {
v->now = v->savenow;
v->stop = v->savestop;
v->savenow = v->savestop = NULL;
}
/* skip white space etc. if appropriate (not in literal or []) */
if (v->cflags & REG_EXPANDED)
switch (v->lexcon)
{
if (v->cflags&REG_EXPANDED)
switch (v->lexcon) {
case L_ERE:
case L_BRE:
case L_EBND:
@@ -313,10 +308,8 @@ next(struct vars * v)
}
/* handle EOS, depending on context */
if (ATEOS())
{
switch (v->lexcon)
{
if (ATEOS()) {
switch (v->lexcon) {
case L_ERE:
case L_BRE:
case L_Q:
@@ -340,8 +333,7 @@ next(struct vars * v)
c = *v->now++;
/* deal with the easy contexts, punt EREs to code below */
switch (v->lexcon)
{
switch (v->lexcon) {
case L_BRE: /* punt BREs to separate function */
return brenext(v, c);
break;
@@ -352,46 +344,33 @@ next(struct vars * v)
break;
case L_BBND: /* bounds are fairly simple */
case L_EBND:
switch (c)
{
case CHR('0'):
case CHR('1'):
case CHR('2'):
case CHR('3'):
case CHR('4'):
case CHR('5'):
case CHR('6'):
case CHR('7'):
case CHR('8'):
case CHR('9'):
RETV(DIGIT, (chr) DIGITVAL(c));
switch (c) {
case CHR('0'): case CHR('1'): case CHR('2'): case CHR('3'):
case CHR('4'): case CHR('5'): case CHR('6'): case CHR('7'):
case CHR('8'): case CHR('9'):
RETV(DIGIT, (chr)DIGITVAL(c));
break;
case CHR(','):
RET(',');
break;
case CHR('}'): /* ERE bound ends with } */
if (INCON(L_EBND))
{
if (INCON(L_EBND)) {
INTOCON(L_ERE);
if ((v->cflags & REG_ADVF) && NEXT1('?'))
{
if ((v->cflags&REG_ADVF) && NEXT1('?')) {
v->now++;
NOTE(REG_UNONPOSIX);
RETV('}', 0);
}
RETV('}', 1);
}
else
} else
FAILW(REG_BADBR);
break;
case CHR('\\'): /* BRE bound ends with \} */
if (INCON(L_BBND) && NEXT1('}'))
{
if (INCON(L_BBND) && NEXT1('}')) {
v->now++;
INTOCON(L_BRE);
RET('}');
}
else
} else
FAILW(REG_BADBR);
break;
default:
@@ -401,34 +380,30 @@ next(struct vars * v)
assert(NOTREACHED);
break;
case L_BRACK: /* brackets are not too hard */
switch (c)
{
switch (c) {
case CHR(']'):
if (LASTTYPE('['))
RETV(PLAIN, c);
else
{
INTOCON((v->cflags & REG_EXTENDED) ?
else {
INTOCON((v->cflags&REG_EXTENDED) ?
L_ERE : L_BRE);
RET(']');
}
break;
case CHR('\\'):
NOTE(REG_UBBS);
if (!(v->cflags & REG_ADVF))
if (!(v->cflags&REG_ADVF))
RETV(PLAIN, c);
NOTE(REG_UNONPOSIX);
if (ATEOS())
FAILW(REG_EESCAPE);
(DISCARD) lexescape(v);
switch (v->nexttype)
{ /* not all escapes okay here */
(DISCARD)lexescape(v);
switch (v->nexttype) { /* not all escapes okay here */
case PLAIN:
return 1;
break;
case CCLASS:
switch (v->nextvalue)
{
switch (v->nextvalue) {
case 'd':
lexnest(v, brbackd, ENDOF(brbackd));
break;
@@ -459,8 +434,7 @@ next(struct vars * v)
case CHR('['):
if (ATEOS())
FAILW(REG_EBRACK);
switch (*v->now++)
{
switch (*v->now++) {
case CHR('.'):
INTOCON(L_CEL);
/* might or might not be locale-specific */
@@ -490,33 +464,27 @@ next(struct vars * v)
assert(NOTREACHED);
break;
case L_CEL: /* collating elements are easy */
if (c == CHR('.') && NEXT1(']'))
{
if (c == CHR('.') && NEXT1(']')) {
v->now++;
INTOCON(L_BRACK);
RETV(END, '.');
}
else
} else
RETV(PLAIN, c);
break;
case L_ECL: /* ditto equivalence classes */
if (c == CHR('=') && NEXT1(']'))
{
if (c == CHR('=') && NEXT1(']')) {
v->now++;
INTOCON(L_BRACK);
RETV(END, '=');
}
else
} else
RETV(PLAIN, c);
break;
case L_CCL: /* ditto character classes */
if (c == CHR(':') && NEXT1(']'))
{
if (c == CHR(':') && NEXT1(']')) {
v->now++;
INTOCON(L_BRACK);
RETV(END, ':');
}
else
} else
RETV(PLAIN, c);
break;
default:
@@ -528,14 +496,12 @@ next(struct vars * v)
assert(INCON(L_ERE));
/* deal with EREs and AREs, except for backslashes */
switch (c)
{
switch (c) {
case CHR('|'):
RET('|');
break;
case CHR('*'):
if ((v->cflags & REG_ADVF) && NEXT1('?'))
{
if ((v->cflags&REG_ADVF) && NEXT1('?')) {
v->now++;
NOTE(REG_UNONPOSIX);
RETV('*', 0);
@@ -543,8 +509,7 @@ next(struct vars * v)
RETV('*', 1);
break;
case CHR('+'):
if ((v->cflags & REG_ADVF) && NEXT1('?'))
{
if ((v->cflags&REG_ADVF) && NEXT1('?')) {
v->now++;
NOTE(REG_UNONPOSIX);
RETV('+', 0);
@@ -552,8 +517,7 @@ next(struct vars * v)
RETV('+', 1);
break;
case CHR('?'):
if ((v->cflags & REG_ADVF) && NEXT1('?'))
{
if ((v->cflags&REG_ADVF) && NEXT1('?')) {
v->now++;
NOTE(REG_UNONPOSIX);
RETV('?', 0);
@@ -561,16 +525,13 @@ next(struct vars * v)
RETV('?', 1);
break;
case CHR('{'): /* bounds start or plain character */
if (v->cflags & REG_EXPANDED)
if (v->cflags&REG_EXPANDED)
skip(v);
if (ATEOS() || !iscdigit(*v->now))
{
if (ATEOS() || !iscdigit(*v->now)) {
NOTE(REG_UBRACES);
NOTE(REG_UUNSPEC);
RETV(PLAIN, c);
}
else
{
} else {
NOTE(REG_UBOUNDS);
INTOCON(L_EBND);
RET('{');
@@ -578,12 +539,10 @@ next(struct vars * v)
assert(NOTREACHED);
break;
case CHR('('): /* parenthesis, or advanced extension */
if ((v->cflags & REG_ADVF) && NEXT1('?'))
{
if ((v->cflags&REG_ADVF) && NEXT1('?')) {
NOTE(REG_UNONPOSIX);
v->now++;
switch (*v->now++)
{
switch (*v->now++) {
case CHR(':'): /* non-capturing paren */
RETV('(', 0);
break;
@@ -609,33 +568,32 @@ next(struct vars * v)
}
assert(NOTREACHED);
}
if (v->cflags & REG_NOSUB)
if (v->cflags&REG_NOSUB)
RETV('(', 0); /* all parens non-capturing */
else
RETV('(', 1);
break;
case CHR(')'):
if (LASTTYPE('('))
if (LASTTYPE('(')) {
NOTE(REG_UUNSPEC);
}
RETV(')', c);
break;
case CHR('['): /* easy except for [[:<:]] and [[:>:]] */
if (HAVE(6) && *(v->now + 0) == CHR('[') &&
*(v->now + 1) == CHR(':') &&
(*(v->now + 2) == CHR('<') ||
*(v->now + 2) == CHR('>')) &&
*(v->now + 3) == CHR(':') &&
*(v->now + 4) == CHR(']') &&
*(v->now + 5) == CHR(']'))
{
c = *(v->now + 2);
if (HAVE(6) && *(v->now+0) == CHR('[') &&
*(v->now+1) == CHR(':') &&
(*(v->now+2) == CHR('<') ||
*(v->now+2) == CHR('>')) &&
*(v->now+3) == CHR(':') &&
*(v->now+4) == CHR(']') &&
*(v->now+5) == CHR(']')) {
c = *(v->now+2);
v->now += 6;
NOTE(REG_UNONPOSIX);
RET((c == CHR('<')) ? '<' : '>');
}
INTOCON(L_BRACK);
if (NEXT1('^'))
{
if (NEXT1('^')) {
v->now++;
RETV('[', 0);
}
@@ -661,40 +619,24 @@ next(struct vars * v)
/* ERE/ARE backslash handling; backslash already eaten */
assert(!ATEOS());
if (!(v->cflags & REG_ADVF))
{ /* only AREs have non-trivial escapes */
if (iscalnum(*v->now))
{
if (!(v->cflags&REG_ADVF)) { /* only AREs have non-trivial escapes */
if (iscalnum(*v->now)) {
NOTE(REG_UBSALNUM);
NOTE(REG_UUNSPEC);
}
RETV(PLAIN, *v->now++);
}
(DISCARD) lexescape(v);
(DISCARD)lexescape(v);
if (ISERR())
FAILW(REG_EESCAPE);
if (v->nexttype == CCLASS)
{ /* fudge at lexical level */
switch (v->nextvalue)
{
case 'd':
lexnest(v, backd, ENDOF(backd));
break;
case 'D':
lexnest(v, backD, ENDOF(backD));
break;
case 's':
lexnest(v, backs, ENDOF(backs));
break;
case 'S':
lexnest(v, backS, ENDOF(backS));
break;
case 'w':
lexnest(v, backw, ENDOF(backw));
break;
case 'W':
lexnest(v, backW, ENDOF(backW));
break;
if (v->nexttype == CCLASS) { /* fudge at lexical level */
switch (v->nextvalue) {
case 'd': lexnest(v, backd, ENDOF(backd)); break;
case 'D': lexnest(v, backD, ENDOF(backD)); break;
case 's': lexnest(v, backs, ENDOF(backs)); break;
case 'S': lexnest(v, backS, ENDOF(backS)); break;
case 'w': lexnest(v, backw, ENDOF(backw)); break;
case 'W': lexnest(v, backW, ENDOF(backW)); break;
default:
assert(NOTREACHED);
FAILW(REG_ASSERT);
@@ -709,12 +651,13 @@ next(struct vars * v)
}
/*
* lexescape - parse an ARE backslash escape (backslash already eaten)
- lexescape - parse an ARE backslash escape (backslash already eaten)
* Note slightly nonstandard use of the CCLASS type code.
^ static int lexescape(struct vars *);
*/
static int /* not actually used, but convenient for
* RETV */
lexescape(struct vars * v)
static int /* not actually used, but convenient for RETV */
lexescape(v)
struct vars *v;
{
chr c;
static chr alert[] = {
@@ -725,7 +668,7 @@ lexescape(struct vars * v)
};
chr *save;
assert(v->cflags & REG_ADVF);
assert(v->cflags&REG_ADVF);
assert(!ATEOS());
c = *v->now++;
@@ -733,8 +676,7 @@ lexescape(struct vars * v)
RETV(PLAIN, c);
NOTE(REG_UNONPOSIX);
switch (c)
{
switch (c) {
case CHR('a'):
RETV(PLAIN, chrnamed(v, alert, ENDOF(alert), CHR('\007')));
break;
@@ -751,7 +693,7 @@ lexescape(struct vars * v)
NOTE(REG_UUNPORT);
if (ATEOS())
FAILW(REG_EESCAPE);
RETV(PLAIN, (chr) (*v->now++ & 037));
RETV(PLAIN, (chr)(*v->now++ & 037));
break;
case CHR('d'):
NOTE(REG_ULOCALE);
@@ -816,8 +758,7 @@ lexescape(struct vars * v)
break;
case CHR('x'):
NOTE(REG_UUNPORT);
c = lexdigits(v, 16, 1, 255); /* REs >255 long outside
* spec */
c = lexdigits(v, 16, 1, 255); /* REs >255 long outside spec */
if (ISERR())
FAILW(REG_EESCAPE);
RETV(PLAIN, c);
@@ -833,26 +774,18 @@ lexescape(struct vars * v)
case CHR('Z'):
RETV(SEND, 0);
break;
case CHR('1'):
case CHR('2'):
case CHR('3'):
case CHR('4'):
case CHR('5'):
case CHR('6'):
case CHR('7'):
case CHR('8'):
case CHR('1'): case CHR('2'): case CHR('3'): case CHR('4'):
case CHR('5'): case CHR('6'): case CHR('7'): case CHR('8'):
case CHR('9'):
save = v->now;
v->now--; /* put first digit back */
c = lexdigits(v, 10, 1, 255); /* REs >255 long outside
* spec */
c = lexdigits(v, 10, 1, 255); /* REs >255 long outside spec */
if (ISERR())
FAILW(REG_EESCAPE);
/* ugly heuristic (first test is "exactly 1 digit?") */
if (v->now - save == 0 || (int) c <= v->nsubexp)
{
if (v->now - save == 0 || (int)c <= v->nsubexp) {
NOTE(REG_UBACKREF);
RETV(BACKREF, (chr) c);
RETV(BACKREF, (chr)c);
}
/* oops, doesn't look like it's a backref after all... */
v->now = save;
@@ -874,119 +807,91 @@ lexescape(struct vars * v)
}
/*
* lexdigits - slurp up digits and return chr value
- lexdigits - slurp up digits and return chr value
^ static chr lexdigits(struct vars *, int, int, int);
*/
static chr /* chr value; errors signalled via ERR */
lexdigits(struct vars * v,
int base,
int minlen,
int maxlen)
lexdigits(v, base, minlen, maxlen)
struct vars *v;
int base;
int minlen;
int maxlen;
{
uchr n; /* unsigned to avoid overflow misbehavior */
int len;
chr c;
int d;
const uchr ub = (uchr) base;
CONST uchr ub = (uchr) base;
n = 0;
for (len = 0; len < maxlen && !ATEOS(); len++)
{
for (len = 0; len < maxlen && !ATEOS(); len++) {
c = *v->now++;
switch (c)
{
case CHR('0'):
case CHR('1'):
case CHR('2'):
case CHR('3'):
case CHR('4'):
case CHR('5'):
case CHR('6'):
case CHR('7'):
case CHR('8'):
case CHR('9'):
switch (c) {
case CHR('0'): case CHR('1'): case CHR('2'): case CHR('3'):
case CHR('4'): case CHR('5'): case CHR('6'): case CHR('7'):
case CHR('8'): case CHR('9'):
d = DIGITVAL(c);
break;
case CHR('a'):
case CHR('A'):
d = 10;
break;
case CHR('b'):
case CHR('B'):
d = 11;
break;
case CHR('c'):
case CHR('C'):
d = 12;
break;
case CHR('d'):
case CHR('D'):
d = 13;
break;
case CHR('e'):
case CHR('E'):
d = 14;
break;
case CHR('f'):
case CHR('F'):
d = 15;
break;
case CHR('a'): case CHR('A'): d = 10; break;
case CHR('b'): case CHR('B'): d = 11; break;
case CHR('c'): case CHR('C'): d = 12; break;
case CHR('d'): case CHR('D'): d = 13; break;
case CHR('e'): case CHR('E'): d = 14; break;
case CHR('f'): case CHR('F'): d = 15; break;
default:
v->now--; /* oops, not a digit at all */
d = -1;
break;
}
if (d >= base)
{ /* not a plausible digit */
if (d >= base) { /* not a plausible digit */
v->now--;
d = -1;
}
if (d < 0)
break; /* NOTE BREAK OUT */
n = n * ub + (uchr) d;
n = n*ub + (uchr)d;
}
if (len < minlen)
ERR(REG_EESCAPE);
return (chr) n;
return (chr)n;
}
/*
* brenext - get next BRE token
*
- brenext - get next BRE token
* This is much like EREs except for all the stupid backslashes and the
* context-dependency of some things.
^ static int brenext(struct vars *, pchr);
*/
static int /* 1 normal, 0 failure */
brenext(struct vars * v,
chr pc)
brenext(v, pc)
struct vars *v;
pchr pc;
{
chr c = (chr) pc;
chr c = (chr)pc;
switch (c)
{
switch (c) {
case CHR('*'):
if (LASTTYPE(EMPTY) || LASTTYPE('(') || LASTTYPE('^'))
RETV(PLAIN, c);
RET('*');
break;
case CHR('['):
if (HAVE(6) && *(v->now + 0) == CHR('[') &&
*(v->now + 1) == CHR(':') &&
(*(v->now + 2) == CHR('<') ||
*(v->now + 2) == CHR('>')) &&
*(v->now + 3) == CHR(':') &&
*(v->now + 4) == CHR(']') &&
*(v->now + 5) == CHR(']'))
{
c = *(v->now + 2);
if (HAVE(6) && *(v->now+0) == CHR('[') &&
*(v->now+1) == CHR(':') &&
(*(v->now+2) == CHR('<') ||
*(v->now+2) == CHR('>')) &&
*(v->now+3) == CHR(':') &&
*(v->now+4) == CHR(']') &&
*(v->now+5) == CHR(']')) {
c = *(v->now+2);
v->now += 6;
NOTE(REG_UNONPOSIX);
RET((c == CHR('<')) ? '<' : '>');
}
INTOCON(L_BRACK);
if (NEXT1('^'))
{
if (NEXT1('^')) {
v->now++;
RETV('[', 0);
}
@@ -998,20 +903,18 @@ brenext(struct vars * v,
case CHR('^'):
if (LASTTYPE(EMPTY))
RET('^');
if (LASTTYPE('('))
{
if (LASTTYPE('(')) {
NOTE(REG_UUNSPEC);
RET('^');
}
RETV(PLAIN, c);
break;
case CHR('$'):
if (v->cflags & REG_EXPANDED)
if (v->cflags&REG_EXPANDED)
skip(v);
if (ATEOS())
RET('$');
if (NEXT2('\\', ')'))
{
if (NEXT2('\\', ')')) {
NOTE(REG_UUNSPEC);
RET('$');
}
@@ -1030,8 +933,7 @@ brenext(struct vars * v,
FAILW(REG_EESCAPE);
c = *v->now++;
switch (c)
{
switch (c) {
case CHR('{'):
INTOCON(L_BBND);
NOTE(REG_UBOUNDS);
@@ -1051,21 +953,14 @@ brenext(struct vars * v,
NOTE(REG_UNONPOSIX);
RET('>');
break;
case CHR('1'):
case CHR('2'):
case CHR('3'):
case CHR('4'):
case CHR('5'):
case CHR('6'):
case CHR('7'):
case CHR('8'):
case CHR('1'): case CHR('2'): case CHR('3'): case CHR('4'):
case CHR('5'): case CHR('6'): case CHR('7'): case CHR('8'):
case CHR('9'):
NOTE(REG_UBACKREF);
RETV(BACKREF, (chr) DIGITVAL(c));
RETV(BACKREF, (chr)DIGITVAL(c));
break;
default:
if (iscalnum(c))
{
if (iscalnum(c)) {
NOTE(REG_UBSALNUM);
NOTE(REG_UUNSPEC);
}
@@ -1077,17 +972,18 @@ brenext(struct vars * v,
}
/*
* skip - skip white space and comments in expanded form
- skip - skip white space and comments in expanded form
^ static VOID skip(struct vars *);
*/
static void
skip(struct vars * v)
static VOID
skip(v)
struct vars *v;
{
chr *start = v->now;
assert(v->cflags & REG_EXPANDED);
assert(v->cflags&REG_EXPANDED);
for (;;)
{
for (;;) {
while (!ATEOS() && iscspace(*v->now))
v->now++;
if (ATEOS() || *v->now != CHR('#'))
@@ -1103,27 +999,46 @@ skip(struct vars * v)
}
/*
* newline - return the chr for a newline
*
- newline - return the chr for a newline
* This helps confine use of CHR to this source file.
^ static chr newline(NOPARMS);
*/
static chr
newline(void)
newline()
{
return CHR('\n');
}
/*
* chrnamed - return the chr known by a given (chr string) name
*
- ch - return the chr sequence for regc_locale.c's fake collating element ch
* This helps confine use of CHR to this source file. Beware that the caller
* knows how long the sequence is.
^ #ifdef REG_DEBUG
^ static chr *ch(NOPARMS);
^ #endif
*/
#ifdef REG_DEBUG
static chr *
ch()
{
static chr chstr[] = { CHR('c'), CHR('h'), CHR('\0') };
return chstr;
}
#endif
/*
- chrnamed - return the chr known by a given (chr string) name
* The code is a bit clumsy, but this routine gets only such specialized
* use that it hardly matters.
^ static chr chrnamed(struct vars *, chr *, chr *, pchr);
*/
static chr
chrnamed(struct vars * v,
chr *startp, /* start of name */
chr *endp, /* just past end of name */
chr lastresort) /* what to return if name lookup fails */
chrnamed(v, startp, endp, lastresort)
struct vars *v;
chr *startp; /* start of name */
chr *endp; /* just past end of name */
pchr lastresort; /* what to return if name lookup fails */
{
celt c;
int errsave;
@@ -1137,10 +1052,10 @@ chrnamed(struct vars * v,
v->err = errsave;
if (e != 0)
return (chr) lastresort;
return (chr)lastresort;
cv = range(v, c, c, 0);
if (cv->nchrs == 0)
return (chr) lastresort;
return (chr)lastresort;
return cv->chrs[0];
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,3 @@
#ifndef _REGEX_CUSTOM_H_
#define _REGEX_CUSTOM_H_
/*
* Copyright (c) 1998, 1999 Henry Spencer. All rights reserved.
*
@@ -27,72 +24,97 @@
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Id$
*/
/* headers if any */
/* FreeBSD, Watcom and DMars require this, CW doesn't have nor need it. */
/* Others also don't seem to need it. If you have an error related to */
/* (not) including <sys/types.h> please report details to */
/* wx-dev@lists.wxwindows.org */
#if defined(__UNIX__) || defined(__WATCOMC__) || defined(__DIGITALMARS__)
# include <sys/types.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <limits.h>
#include "wx/wxchar.h"
/**
*
* wx_wchar == wxChar
*
*/
#define wx_wchar wxChar
#include "tclInt.h"
/* overrides for regguts.h definitions, if any */
#define FUNCPTR(name, args) (*name) args
#define MALLOC(n) malloc(n)
#define FREE(p) free(VS(p))
#define REALLOC(p,n) realloc(VS(p),n)
#define FUNCPTR(name, args) (*name) _ANSI_ARGS_(args)
#define MALLOC(n) ckalloc(n)
#define FREE(p) ckfree(VS(p))
#define REALLOC(p,n) ckrealloc(VS(p),n)
/*
* Do not insert extras between the "begin" and "end" lines -- this
* chunk is automatically extracted to be fitted into regex.h.
*/
/* --- begin --- */
/* ensure certain things don't sneak in from system headers */
#ifdef __REG_WIDE_T
#undef __REG_WIDE_T
#endif
#ifdef __REG_WIDE_COMPILE
#undef __REG_WIDE_COMPILE
#endif
#ifdef __REG_WIDE_EXEC
#undef __REG_WIDE_EXEC
#endif
#ifdef __REG_REGOFF_T
#undef __REG_REGOFF_T
#endif
#ifdef __REG_VOID_T
#undef __REG_VOID_T
#endif
#ifdef __REG_CONST
#undef __REG_CONST
#endif
#ifdef __REG_NOFRONT
#undef __REG_NOFRONT
#endif
#ifdef __REG_NOCHAR
#undef __REG_NOCHAR
#endif
/* interface types */
#define __REG_WIDE_T Tcl_UniChar
#define __REG_REGOFF_T long /* not really right, but good enough... */
#define __REG_VOID_T VOID
#define __REG_CONST CONST
/* names and declarations */
#define __REG_WIDE_COMPILE TclReComp
#define __REG_WIDE_EXEC TclReExec
#define __REG_NOFRONT /* don't want regcomp() and regexec() */
#define __REG_NOCHAR /* or the char versions */
#define regfree TclReFree
#define regerror TclReError
/* --- end --- */
/* internal character type and related */
typedef wx_wchar chr; /* the type itself */
typedef unsigned long uchr; /* unsigned type that will hold a chr */
typedef long celt; /* type to hold chr, MCCE number, or
* NOCELT */
#define NOCELT (-1) /* celt value which is not valid chr or
* MCCE */
#define CHR(c) ((unsigned char) (c)) /* turn char literal into chr
* literal */
typedef Tcl_UniChar chr; /* the type itself */
typedef int pchr; /* what it promotes to */
typedef unsigned uchr; /* unsigned type that will hold a chr */
typedef int celt; /* type to hold chr, MCCE number, or NOCELT */
#define NOCELT (-1) /* celt value which is not valid chr or MCCE */
#define CHR(c) (UCHAR(c)) /* turn char literal into chr literal */
#define DIGITVAL(c) ((c)-'0') /* turn chr digit into its value */
#if wxUSE_WCHAR_T
# define CHRBITS (SIZEOF_WCHAR_T << 3) /* bits in a chr; must not use sizeof */
# define CHR_MAX ((1 << CHRBITS) - 1)
# define CHR_MIN 0x00000000 /* smallest and largest chr; the value */
#else /*ANSI*/
# define CHRBITS 8
# define CHR_MAX 0xFF
# define CHR_MIN 0x00
#endif /*wxUSE_WCHAR_T*/
#if TCL_UTF_MAX > 3
#define CHRBITS 32 /* bits in a chr; must not use sizeof */
#define CHR_MIN 0x00000000 /* smallest and largest chr; the value */
#define CHR_MAX 0xffffffff /* CHR_MAX-CHR_MIN+1 should fit in uchr */
#else
#define CHRBITS 16 /* bits in a chr; must not use sizeof */
#define CHR_MIN 0x0000 /* smallest and largest chr; the value */
#define CHR_MAX 0xffff /* CHR_MAX-CHR_MIN+1 should fit in uchr */
#endif
/* functions operating on chr */
#define iscalnum(x) wx_isalnum(x)
#define iscalpha(x) wx_isalpha(x)
#define iscdigit(x) wx_isdigit(x)
#define iscspace(x) wx_isspace(x)
#define iscalnum(x) Tcl_UniCharIsAlnum(x)
#define iscalpha(x) Tcl_UniCharIsAlpha(x)
#define iscdigit(x) Tcl_UniCharIsDigit(x)
#define iscspace(x) Tcl_UniCharIsSpace(x)
extern int wx_strlen(const wx_wchar* szString);
/* name the external functions */
#define compile TclReComp
#define exec TclReExec
/* enable/disable debugging code (by whether REG_DEBUG is defined or not) */
#if 0 /* no debug unless requested by makefile */
#define REG_DEBUG /* */
#endif
/* and pick up the standard header */
#include "regex.h"
#endif /* _REGEX_CUSTOM_H_ */

View File

@@ -28,19 +28,19 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Header$
*
*/
/*
* longest - longest-preferred matching engine
- longest - longest-preferred matching engine
^ static chr *longest(struct vars *, struct dfa *, chr *, chr *, int *);
*/
static chr * /* endpoint, or NULL */
longest(struct vars * v, /* used only for debug and exec flags */
struct dfa * d,
chr *start, /* where the match should start */
chr *stop, /* match must end at or before here */
int *hitstopp) /* record whether hit v->stop, if non-NULL */
longest(v, d, start, stop, hitstopp)
struct vars *v; /* used only for debug and exec flags */
struct dfa *d;
chr *start; /* where the match should start */
chr *stop; /* match must end at or before here */
int *hitstopp; /* record whether hit v->stop, if non-NULL */
{
chr *cp;
chr *realstop = (stop == v->stop) ? stop : stop + 1;
@@ -59,15 +59,12 @@ longest(struct vars * v, /* used only for debug and exec flags */
/* startup */
FDEBUG(("+++ startup +++\n"));
if (cp == v->start)
{
co = d->cnfa->bos[(v->eflags & REG_NOTBOL) ? 0 : 1];
FDEBUG(("color %ld\n", (long) co));
}
else
{
if (cp == v->start) {
co = d->cnfa->bos[(v->eflags&REG_NOTBOL) ? 0 : 1];
FDEBUG(("color %ld\n", (long)co));
} else {
co = GETCOLOR(cm, *(cp - 1));
FDEBUG(("char %c, color %ld\n", (char) *(cp - 1), (long) co));
FDEBUG(("char %c, color %ld\n", (char)*(cp-1), (long)co));
}
css = miss(v, d, css, co, cp, start);
if (css == NULL)
@@ -75,16 +72,14 @@ longest(struct vars * v, /* used only for debug and exec flags */
css->lastseen = cp;
/* main loop */
if (v->eflags & REG_FTRACE)
while (cp < realstop)
{
if (v->eflags&REG_FTRACE)
while (cp < realstop) {
FDEBUG(("+++ at c%d +++\n", css - d->ssets));
co = GETCOLOR(cm, *cp);
FDEBUG(("char %c, color %ld\n", (char) *cp, (long) co));
FDEBUG(("char %c, color %ld\n", (char)*cp, (long)co));
ss = css->outs[co];
if (ss == NULL)
{
ss = miss(v, d, css, co, cp + 1, start);
if (ss == NULL) {
ss = miss(v, d, css, co, cp+1, start);
if (ss == NULL)
break; /* NOTE BREAK OUT */
}
@@ -93,13 +88,11 @@ longest(struct vars * v, /* used only for debug and exec flags */
css = ss;
}
else
while (cp < realstop)
{
while (cp < realstop) {
co = GETCOLOR(cm, *cp);
ss = css->outs[co];
if (ss == NULL)
{
ss = miss(v, d, css, co, cp + 1, start);
if (ss == NULL) {
ss = miss(v, d, css, co, cp+1, start);
if (ss == NULL)
break; /* NOTE BREAK OUT */
}
@@ -110,15 +103,14 @@ longest(struct vars * v, /* used only for debug and exec flags */
/* shutdown */
FDEBUG(("+++ shutdown at c%d +++\n", css - d->ssets));
if (cp == v->stop && stop == v->stop)
{
if (cp == v->stop && stop == v->stop) {
if (hitstopp != NULL)
*hitstopp = 1;
co = d->cnfa->eos[(v->eflags & REG_NOTEOL) ? 0 : 1];
FDEBUG(("color %ld\n", (long) co));
co = d->cnfa->eos[(v->eflags&REG_NOTEOL) ? 0 : 1];
FDEBUG(("color %ld\n", (long)co));
ss = miss(v, d, css, co, cp, start);
/* special case: match ended at eol? */
if (ss != NULL && (ss->flags & POSTSTATE))
if (ss != NULL && (ss->flags&POSTSTATE))
return cp;
else if (ss != NULL)
ss->lastseen = cp; /* to be tidy */
@@ -127,7 +119,7 @@ longest(struct vars * v, /* used only for debug and exec flags */
/* find last match, if any */
post = d->lastpost;
for (ss = d->ssets, i = d->nssused; i > 0; ss++, i--)
if ((ss->flags & POSTSTATE) && post != ss->lastseen &&
if ((ss->flags&POSTSTATE) && post != ss->lastseen &&
(post == NULL || post < ss->lastseen))
post = ss->lastseen;
if (post != NULL) /* found one */
@@ -137,17 +129,19 @@ longest(struct vars * v, /* used only for debug and exec flags */
}
/*
* shortest - shortest-preferred matching engine
- shortest - shortest-preferred matching engine
^ static chr *shortest(struct vars *, struct dfa *, chr *, chr *, chr *,
^ chr **, int *);
*/
static chr * /* endpoint, or NULL */
shortest(struct vars * v,
struct dfa * d,
chr *start, /* where the match should start */
chr *min, /* match must end at or after here */
chr *max, /* match must end at or before here */
chr **coldp, /* store coldstart pointer here, if
* nonNULL */
int *hitstopp) /* record whether hit v->stop, if non-NULL */
shortest(v, d, start, min, max, coldp, hitstopp)
struct vars *v;
struct dfa *d;
chr *start; /* where the match should start */
chr *min; /* match must end at or after here */
chr *max; /* match must end at or before here */
chr **coldp; /* store coldstart pointer here, if nonNULL */
int *hitstopp; /* record whether hit v->stop, if non-NULL */
{
chr *cp;
chr *realmin = (min == v->stop) ? min : min + 1;
@@ -165,15 +159,12 @@ shortest(struct vars * v,
/* startup */
FDEBUG(("--- startup ---\n"));
if (cp == v->start)
{
co = d->cnfa->bos[(v->eflags & REG_NOTBOL) ? 0 : 1];
FDEBUG(("color %ld\n", (long) co));
}
else
{
if (cp == v->start) {
co = d->cnfa->bos[(v->eflags&REG_NOTBOL) ? 0 : 1];
FDEBUG(("color %ld\n", (long)co));
} else {
co = GETCOLOR(cm, *(cp - 1));
FDEBUG(("char %c, color %ld\n", (char) *(cp - 1), (long) co));
FDEBUG(("char %c, color %ld\n", (char)*(cp-1), (long)co));
}
css = miss(v, d, css, co, cp, start);
if (css == NULL)
@@ -182,77 +173,71 @@ shortest(struct vars * v,
ss = css;
/* main loop */
if (v->eflags & REG_FTRACE)
while (cp < realmax)
{
if (v->eflags&REG_FTRACE)
while (cp < realmax) {
FDEBUG(("--- at c%d ---\n", css - d->ssets));
co = GETCOLOR(cm, *cp);
FDEBUG(("char %c, color %ld\n", (char) *cp, (long) co));
FDEBUG(("char %c, color %ld\n", (char)*cp, (long)co));
ss = css->outs[co];
if (ss == NULL)
{
ss = miss(v, d, css, co, cp + 1, start);
if (ss == NULL) {
ss = miss(v, d, css, co, cp+1, start);
if (ss == NULL)
break; /* NOTE BREAK OUT */
}
cp++;
ss->lastseen = cp;
css = ss;
if ((ss->flags & POSTSTATE) && cp >= realmin)
if ((ss->flags&POSTSTATE) && cp >= realmin)
break; /* NOTE BREAK OUT */
}
else
while (cp < realmax)
{
while (cp < realmax) {
co = GETCOLOR(cm, *cp);
ss = css->outs[co];
if (ss == NULL)
{
ss = miss(v, d, css, co, cp + 1, start);
if (ss == NULL) {
ss = miss(v, d, css, co, cp+1, start);
if (ss == NULL)
break; /* NOTE BREAK OUT */
}
cp++;
ss->lastseen = cp;
css = ss;
if ((ss->flags & POSTSTATE) && cp >= realmin)
if ((ss->flags&POSTSTATE) && cp >= realmin)
break; /* NOTE BREAK OUT */
}
if (ss == NULL)
return NULL;
if (coldp != NULL) /* report last no-progress state set, if
* any */
if (coldp != NULL) /* report last no-progress state set, if any */
*coldp = lastcold(v, d);
if ((ss->flags & POSTSTATE) && cp > min)
{
if ((ss->flags&POSTSTATE) && cp > min) {
assert(cp >= realmin);
cp--;
}
else if (cp == v->stop && max == v->stop)
{
co = d->cnfa->eos[(v->eflags & REG_NOTEOL) ? 0 : 1];
FDEBUG(("color %ld\n", (long) co));
} else if (cp == v->stop && max == v->stop) {
co = d->cnfa->eos[(v->eflags&REG_NOTEOL) ? 0 : 1];
FDEBUG(("color %ld\n", (long)co));
ss = miss(v, d, css, co, cp, start);
/* match might have ended at eol */
if ((ss == NULL || !(ss->flags & POSTSTATE)) && hitstopp != NULL)
if ((ss == NULL || !(ss->flags&POSTSTATE)) && hitstopp != NULL)
*hitstopp = 1;
}
if (ss == NULL || !(ss->flags & POSTSTATE))
if (ss == NULL || !(ss->flags&POSTSTATE))
return NULL;
return cp;
}
/*
* lastcold - determine last point at which no progress had been made
- lastcold - determine last point at which no progress had been made
^ static chr *lastcold(struct vars *, struct dfa *);
*/
static chr * /* endpoint, or NULL */
lastcold(struct vars * v,
struct dfa * d)
lastcold(v, d)
struct vars *v;
struct dfa *d;
{
struct sset *ss;
chr *nopr;
@@ -262,19 +247,22 @@ lastcold(struct vars * v,
if (nopr == NULL)
nopr = v->start;
for (ss = d->ssets, i = d->nssused; i > 0; ss++, i--)
if ((ss->flags & NOPROGRESS) && nopr < ss->lastseen)
if ((ss->flags&NOPROGRESS) && nopr < ss->lastseen)
nopr = ss->lastseen;
return nopr;
}
/*
* newdfa - set up a fresh DFA
- newdfa - set up a fresh DFA
^ static struct dfa *newdfa(struct vars *, struct cnfa *,
^ struct colormap *, struct smalldfa *);
*/
static struct dfa *
newdfa(struct vars * v,
struct cnfa * cnfa,
struct colormap * cm,
struct smalldfa * small) /* preallocated space, may be NULL */
newdfa(v, cnfa, cm, small)
struct vars *v;
struct cnfa *cnfa;
struct colormap *cm;
struct smalldfa *small; /* preallocated space, may be NULL */
{
struct dfa *d;
size_t nss = cnfa->nstates * 2;
@@ -283,15 +271,12 @@ newdfa(struct vars * v,
assert(cnfa != NULL && cnfa->nstates != 0);
if (nss <= FEWSTATES && cnfa->ncolors <= FEWCOLORS)
{
if (nss <= FEWSTATES && cnfa->ncolors <= FEWCOLORS) {
assert(wordsper == 1);
if (small == NULL)
{
small = (struct smalldfa *) MALLOC(
if (small == NULL) {
small = (struct smalldfa *)MALLOC(
sizeof(struct smalldfa));
if (small == NULL)
{
if (small == NULL) {
ERR(REG_ESPACE);
return NULL;
}
@@ -303,36 +288,32 @@ newdfa(struct vars * v,
d->outsarea = small->outsarea;
d->incarea = small->incarea;
d->cptsmalloced = 0;
d->mallocarea = (smallwas == NULL) ? (char *) small : NULL;
}
else
{
d = (struct dfa *) MALLOC(sizeof(struct dfa));
if (d == NULL)
{
d->mallocarea = (smallwas == NULL) ? (char *)small : NULL;
} else {
d = (struct dfa *)MALLOC(sizeof(struct dfa));
if (d == NULL) {
ERR(REG_ESPACE);
return NULL;
}
d->ssets = (struct sset *) MALLOC(nss * sizeof(struct sset));
d->statesarea = (unsigned *) MALLOC((nss + WORK) * wordsper *
d->ssets = (struct sset *)MALLOC(nss * sizeof(struct sset));
d->statesarea = (unsigned *)MALLOC((nss+WORK) * wordsper *
sizeof(unsigned));
d->work = &d->statesarea[nss * wordsper];
d->outsarea = (struct sset **) MALLOC(nss * cnfa->ncolors *
d->outsarea = (struct sset **)MALLOC(nss * cnfa->ncolors *
sizeof(struct sset *));
d->incarea = (struct arcp *) MALLOC(nss * cnfa->ncolors *
d->incarea = (struct arcp *)MALLOC(nss * cnfa->ncolors *
sizeof(struct arcp));
d->cptsmalloced = 1;
d->mallocarea = (char *) d;
d->mallocarea = (char *)d;
if (d->ssets == NULL || d->statesarea == NULL ||
d->outsarea == NULL || d->incarea == NULL)
{
d->outsarea == NULL || d->incarea == NULL) {
freedfa(d);
ERR(REG_ESPACE);
return NULL;
}
}
d->nssets = (v->eflags & REG_SMALL) ? 7 : nss;
d->nssets = (v->eflags&REG_SMALL) ? 7 : nss;
d->nssused = 0;
d->nstates = cnfa->nstates;
d->ncolors = cnfa->ncolors;
@@ -349,13 +330,14 @@ newdfa(struct vars * v,
}
/*
* freedfa - free a DFA
- freedfa - free a DFA
^ static VOID freedfa(struct dfa *);
*/
static void
freedfa(struct dfa * d)
static VOID
freedfa(d)
struct dfa *d;
{
if (d->cptsmalloced)
{
if (d->cptsmalloced) {
if (d->ssets != NULL)
FREE(d->ssets);
if (d->statesarea != NULL)
@@ -371,13 +353,14 @@ freedfa(struct dfa * d)
}
/*
* hash - construct a hash code for a bitvector
*
- hash - construct a hash code for a bitvector
* There are probably better ways, but they're more expensive.
^ static unsigned hash(unsigned *, int);
*/
static unsigned
hash(unsigned *uv,
int n)
hash(uv, n)
unsigned *uv;
int n;
{
int i;
unsigned h;
@@ -389,28 +372,29 @@ hash(unsigned *uv,
}
/*
* initialize - hand-craft a cache entry for startup, otherwise get ready
- initialize - hand-craft a cache entry for startup, otherwise get ready
^ static struct sset *initialize(struct vars *, struct dfa *, chr *);
*/
static struct sset *
initialize(struct vars * v, /* used only for debug flags */
struct dfa * d,
chr *start)
initialize(v, d, start)
struct vars *v; /* used only for debug flags */
struct dfa *d;
chr *start;
{
struct sset *ss;
int i;
/* is previous one still there? */
if (d->nssused > 0 && (d->ssets[0].flags & STARTER))
if (d->nssused > 0 && (d->ssets[0].flags&STARTER))
ss = &d->ssets[0];
else
{ /* no, must (re)build it */
else { /* no, must (re)build it */
ss = getvacant(v, d, start, start);
for (i = 0; i < d->wordsper; i++)
ss->states[i] = 0;
BSET(ss->states, d->cnfa->pre);
ss->hash = HASH(ss->states, d->wordsper);
assert(d->cnfa->pre != d->cnfa->post);
ss->flags = STARTER | LOCKED | NOPROGRESS;
ss->flags = STARTER|LOCKED|NOPROGRESS;
/* lastseen dealt with below */
}
@@ -423,15 +407,18 @@ initialize(struct vars * v, /* used only for debug flags */
}
/*
* miss - handle a cache miss
- miss - handle a cache miss
^ static struct sset *miss(struct vars *, struct dfa *, struct sset *,
^ pcolor, chr *, chr *);
*/
static struct sset * /* NULL if goes to empty set */
miss(struct vars * v, /* used only for debug flags */
struct dfa * d,
struct sset * css,
pcolor co,
chr *cp, /* next chr */
chr *start) /* where the attempt got started */
miss(v, d, css, co, cp, start)
struct vars *v; /* used only for debug flags */
struct dfa *d;
struct sset *css;
pcolor co;
chr *cp; /* next chr */
chr *start; /* where the attempt got started */
{
struct cnfa *cnfa = d->cnfa;
int i;
@@ -445,8 +432,7 @@ miss(struct vars * v, /* used only for debug flags */
int sawlacons;
/* for convenience, we can be called even if it might not be a miss */
if (css->outs[co] != NULL)
{
if (css->outs[co] != NULL) {
FDEBUG(("hit\n"));
return css->outs[co];
}
@@ -460,9 +446,8 @@ miss(struct vars * v, /* used only for debug flags */
gotstate = 0;
for (i = 0; i < d->nstates; i++)
if (ISBSET(css->states, i))
for (ca = cnfa->states[i] + 1; ca->co != COLORLESS; ca++)
if (ca->co == co)
{
for (ca = cnfa->states[i]+1; ca->co != COLORLESS; ca++)
if (ca->co == co) {
BSET(d->work, ca->to);
gotstate = 1;
if (ca->to == cnfa->post)
@@ -471,16 +456,14 @@ miss(struct vars * v, /* used only for debug flags */
noprogress = 0;
FDEBUG(("%d -> %d\n", i, ca->to));
}
dolacons = (gotstate) ? (cnfa->flags & HASLACONS) : 0;
dolacons = (gotstate) ? (cnfa->flags&HASLACONS) : 0;
sawlacons = 0;
while (dolacons)
{ /* transitive closure */
while (dolacons) { /* transitive closure */
dolacons = 0;
for (i = 0; i < d->nstates; i++)
if (ISBSET(d->work, i))
for (ca = cnfa->states[i] + 1; ca->co != COLORLESS;
ca++)
{
for (ca = cnfa->states[i]+1; ca->co != COLORLESS;
ca++) {
if (ca->co <= cnfa->ncolors)
continue; /* NOTE CONTINUE */
sawlacons = 1;
@@ -503,13 +486,11 @@ miss(struct vars * v, /* used only for debug flags */
/* next, is that in the cache? */
for (p = d->ssets, i = d->nssused; i > 0; p++, i--)
if (HIT(h, d->work, p, d->wordsper))
{
if (HIT(h, d->work, p, d->wordsper)) {
FDEBUG(("cached c%d\n", p - d->ssets));
break; /* NOTE BREAK OUT */
}
if (i == 0)
{ /* nope, need a new cache entry */
if (i == 0) { /* nope, need a new cache entry */
p = getvacant(v, d, cp, start);
assert(p != css);
for (i = 0; i < d->wordsper; i++)
@@ -521,25 +502,26 @@ miss(struct vars * v, /* used only for debug flags */
/* lastseen to be dealt with by caller */
}
if (!sawlacons)
{ /* lookahead conds. always cache miss */
if (!sawlacons) { /* lookahead conds. always cache miss */
FDEBUG(("c%d[%d]->c%d\n", css - d->ssets, co, p - d->ssets));
css->outs[co] = p;
css->inchain[co] = p->ins;
p->ins.ss = css;
p->ins.co = (color) co;
p->ins.co = (color)co;
}
return p;
}
/*
* lacon - lookahead-constraint checker for miss()
- lacon - lookahead-constraint checker for miss()
^ static int lacon(struct vars *, struct cnfa *, chr *, pcolor);
*/
static int /* predicate: constraint satisfied? */
lacon(struct vars * v,
struct cnfa * pcnfa, /* parent cnfa */
chr *cp,
pcolor co) /* "color" of the lookahead constraint */
lacon(v, pcnfa, cp, co)
struct vars *v;
struct cnfa *pcnfa; /* parent cnfa */
chr *cp;
pcolor co; /* "color" of the lookahead constraint */
{
int n;
struct subre *sub;
@@ -552,27 +534,28 @@ lacon(struct vars * v,
FDEBUG(("=== testing lacon %d\n", n));
sub = &v->g->lacons[n];
d = newdfa(v, &sub->cnfa, &v->g->cmap, &sd);
if (d == NULL)
{
if (d == NULL) {
ERR(REG_ESPACE);
return 0;
}
end = longest(v, d, cp, v->stop, (int *) NULL);
end = longest(v, d, cp, v->stop, (int *)NULL);
freedfa(d);
FDEBUG(("=== lacon %d match %d\n", n, (end != NULL)));
return (sub->subno) ? (end != NULL) : (end == NULL);
}
/*
* getvacant - get a vacant state set
- getvacant - get a vacant state set
* This routine clears out the inarcs and outarcs, but does not otherwise
* clear the innards of the state set -- that's up to the caller.
^ static struct sset *getvacant(struct vars *, struct dfa *, chr *, chr *);
*/
static struct sset *
getvacant(struct vars * v, /* used only for debug flags */
struct dfa * d,
chr *cp,
chr *start)
getvacant(v, d, cp, start)
struct vars *v; /* used only for debug flags */
struct dfa *d;
chr *cp;
chr *start;
{
int i;
struct sset *ss;
@@ -582,14 +565,13 @@ getvacant(struct vars * v, /* used only for debug flags */
color co;
ss = pickss(v, d, cp, start);
assert(!(ss->flags & LOCKED));
assert(!(ss->flags&LOCKED));
/* clear out its inarcs, including self-referential ones */
ap = ss->ins;
while ((p = ap.ss) != NULL)
{
while ((p = ap.ss) != NULL) {
co = ap.co;
FDEBUG(("zapping c%d's %ld outarc\n", p - d->ssets, (long) co));
FDEBUG(("zapping c%d's %ld outarc\n", p - d->ssets, (long)co));
p->outs[co] = NULL;
ap = p->inchain[co];
p->inchain[co].ss = NULL; /* paranoia */
@@ -597,8 +579,7 @@ getvacant(struct vars * v, /* used only for debug flags */
ss->ins.ss = NULL;
/* take it off the inarc chains of the ssets reached by its outarcs */
for (i = 0; i < d->ncolors; i++)
{
for (i = 0; i < d->ncolors; i++) {
p = ss->outs[i];
assert(p != ss); /* not self-referential */
if (p == NULL)
@@ -606,8 +587,7 @@ getvacant(struct vars * v, /* used only for debug flags */
FDEBUG(("del outarc %d from c%d's in chn\n", i, p - d->ssets));
if (p->ins.ss == ss && p->ins.co == i)
p->ins = ss->inchain[i];
else
{
else {
assert(p->ins.ss != NULL);
for (ap = p->ins; ap.ss != NULL &&
!(ap.ss == ss && ap.co == i);
@@ -621,12 +601,12 @@ getvacant(struct vars * v, /* used only for debug flags */
}
/* if ss was a success state, may need to remember location */
if ((ss->flags & POSTSTATE) && ss->lastseen != d->lastpost &&
if ((ss->flags&POSTSTATE) && ss->lastseen != d->lastpost &&
(d->lastpost == NULL || d->lastpost < ss->lastseen))
d->lastpost = ss->lastseen;
/* likewise for a no-progress state */
if ((ss->flags & NOPROGRESS) && ss->lastseen != d->lastnopr &&
if ((ss->flags&NOPROGRESS) && ss->lastseen != d->lastnopr &&
(d->lastnopr == NULL || d->lastnopr < ss->lastseen))
d->lastnopr = ss->lastseen;
@@ -634,13 +614,15 @@ getvacant(struct vars * v, /* used only for debug flags */
}
/*
* pickss - pick the next stateset to be used
- pickss - pick the next stateset to be used
^ static struct sset *pickss(struct vars *, struct dfa *, chr *, chr *);
*/
static struct sset *
pickss(struct vars * v, /* used only for debug flags */
struct dfa * d,
chr *cp,
chr *start)
pickss(v, d, cp, start)
struct vars *v; /* used only for debug flags */
struct dfa *d;
chr *cp;
chr *start;
{
int i;
struct sset *ss;
@@ -648,8 +630,7 @@ pickss(struct vars * v, /* used only for debug flags */
chr *ancient;
/* shortcut for cases where cache isn't full */
if (d->nssused < d->nssets)
{
if (d->nssused < d->nssets) {
i = d->nssused;
d->nssused++;
ss = &d->ssets[i];
@@ -661,8 +642,7 @@ pickss(struct vars * v, /* used only for debug flags */
ss->ins.co = WHITE; /* give it some value */
ss->outs = &d->outsarea[i * d->ncolors];
ss->inchain = &d->incarea[i * d->ncolors];
for (i = 0; i < d->ncolors; i++)
{
for (i = 0; i < d->ncolors; i++) {
ss->outs[i] = NULL;
ss->inchain[i].ss = NULL;
}
@@ -670,22 +650,20 @@ pickss(struct vars * v, /* used only for debug flags */
}
/* look for oldest, or old enough anyway */
if (cp - start > d->nssets * 2 / 3) /* oldest 33% are expendable */
ancient = cp - d->nssets * 2 / 3;
if (cp - start > d->nssets*2/3) /* oldest 33% are expendable */
ancient = cp - d->nssets*2/3;
else
ancient = start;
for (ss = d->search, end = &d->ssets[d->nssets]; ss < end; ss++)
if ((ss->lastseen == NULL || ss->lastseen < ancient) &&
!(ss->flags & LOCKED))
{
!(ss->flags&LOCKED)) {
d->search = ss + 1;
FDEBUG(("replacing c%d\n", ss - d->ssets));
return ss;
}
for (ss = d->ssets, end = d->search; ss < end; ss++)
if ((ss->lastseen == NULL || ss->lastseen < ancient) &&
!(ss->flags & LOCKED))
{
!(ss->flags&LOCKED)) {
d->search = ss + 1;
FDEBUG(("replacing c%d\n", ss - d->ssets));
return ss;

View File

@@ -27,8 +27,6 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Header: /projects/cvsroot/pgsql-server/src/backend/regex/regerror.c,v 1.26 2003/08/04 00:43:21 momjian Exp $
*
*/
#include "regguts.h"
@@ -37,45 +35,34 @@
static char unk[] = "*** unknown regex error code 0x%x ***";
/* struct to map among codes, code names, and explanations */
static struct rerr
{
static struct rerr {
int code;
char *name;
char *explain;
} rerrs[] =
{
} rerrs[] = {
/* the actual table is built from regex.h */
#include "regerrs.h"
{
-1, "", "oops"
}, /* explanation special-cased in code */
# include "regerrs.h"
{ -1, "", "oops" }, /* explanation special-cased in code */
};
size_t
regerror(int errcode, /* error code, or REG_ATOI or REG_ITOA */
const regex_t *preg, /* associated regex_t (unused at present) */
char *errbuf, /* result buffer (unless errbuf_size==0) */
size_t errbuf_size) /* available space in errbuf, can be 0 */
{ return wx_regerror(errcode, preg, errbuf, errbuf_size); }
/*
* pg_regerror - the interface to error numbers
- regerror - the interface to error numbers
*/
/* ARGSUSED */
size_t /* actual space needed (including NUL) */
wx_regerror(int errcode, /* error code, or REG_ATOI or REG_ITOA */
const regex_t *preg, /* associated regex_t (unused at present) */
char *errbuf, /* result buffer (unless errbuf_size==0) */
size_t errbuf_size) /* available space in errbuf, can be 0 */
regerror(errcode, preg, errbuf, errbuf_size)
int errcode; /* error code, or REG_ATOI or REG_ITOA */
CONST regex_t *preg; /* associated regex_t (unused at present) */
char *errbuf; /* result buffer (unless errbuf_size==0) */
size_t errbuf_size; /* available space in errbuf, can be 0 */
{
struct rerr *r;
char *msg;
char convbuf[sizeof(unk) + 50]; /* 50 = plenty for int */
char convbuf[sizeof(unk)+50]; /* 50 = plenty for int */
size_t len;
int icode;
switch (errcode)
{
switch (errcode) {
case REG_ATOI: /* convert name to number */
for (r = rerrs; r->code >= 0; r++)
if (strcmp(r->name, errbuf) == 0)
@@ -90,9 +77,8 @@ wx_regerror(int errcode, /* error code, or REG_ATOI or REG_ITOA */
break;
if (r->code >= 0)
msg = r->name;
else
{ /* unknown; tell him the number */
sprintf(convbuf, "REG_%u", (unsigned) icode);
else { /* unknown; tell him the number */
sprintf(convbuf, "REG_%u", (unsigned)icode);
msg = convbuf;
}
break;
@@ -102,8 +88,7 @@ wx_regerror(int errcode, /* error code, or REG_ATOI or REG_ITOA */
break;
if (r->code >= 0)
msg = r->explain;
else
{ /* unknown; say so */
else { /* unknown; say so */
sprintf(convbuf, unk, errcode);
msg = convbuf;
}
@@ -111,14 +96,12 @@ wx_regerror(int errcode, /* error code, or REG_ATOI or REG_ITOA */
}
len = strlen(msg) + 1; /* space needed, including NUL */
if (errbuf_size > 0)
{
if (errbuf_size > 0) {
if (errbuf_size > len)
strcpy(errbuf, msg);
else
{ /* truncate to fit */
memcpy(errbuf, msg, errbuf_size - 1); /*RN - was strncpy*/
errbuf[errbuf_size - 1] = '\0';
else { /* truncate to fit */
strncpy(errbuf, msg, errbuf_size-1);
errbuf[errbuf_size-1] = '\0';
}
}

View File

@@ -1,75 +1,18 @@
/*
* $Id$
*/
{
REG_OKAY, "REG_OKAY", "no errors detected"
},
{
REG_NOMATCH, "REG_NOMATCH", "failed to match"
},
{
REG_BADPAT, "REG_BADPAT", "invalid regexp (reg version 0.8)"
},
{
REG_ECOLLATE, "REG_ECOLLATE", "invalid collating element"
},
{
REG_ECTYPE, "REG_ECTYPE", "invalid character class"
},
{
REG_EESCAPE, "REG_EESCAPE", "invalid escape \\ sequence"
},
{
REG_ESUBREG, "REG_ESUBREG", "invalid backreference number"
},
{
REG_EBRACK, "REG_EBRACK", "brackets [] not balanced"
},
{
REG_EPAREN, "REG_EPAREN", "parentheses () not balanced"
},
{
REG_EBRACE, "REG_EBRACE", "braces {} not balanced"
},
{
REG_BADBR, "REG_BADBR", "invalid repetition count(s)"
},
{
REG_ERANGE, "REG_ERANGE", "invalid character range"
},
{
REG_ESPACE, "REG_ESPACE", "out of memory"
},
{
REG_BADRPT, "REG_BADRPT", "quantifier operand invalid"
},
{
REG_ASSERT, "REG_ASSERT", "\"can't happen\" -- you found a bug"
},
{
REG_INVARG, "REG_INVARG", "invalid argument to regex function"
},
{
REG_MIXED, "REG_MIXED", "character widths of regex and string differ"
},
{
REG_BADOPT, "REG_BADOPT", "invalid embedded option"
},
{ REG_OKAY, "REG_OKAY", "no errors detected" },
{ REG_NOMATCH, "REG_NOMATCH", "failed to match" },
{ REG_BADPAT, "REG_BADPAT", "invalid regexp (reg version 0.8)" },
{ REG_ECOLLATE, "REG_ECOLLATE", "invalid collating element" },
{ REG_ECTYPE, "REG_ECTYPE", "invalid character class" },
{ REG_EESCAPE, "REG_EESCAPE", "invalid escape \\ sequence" },
{ REG_ESUBREG, "REG_ESUBREG", "invalid backreference number" },
{ REG_EBRACK, "REG_EBRACK", "brackets [] not balanced" },
{ REG_EPAREN, "REG_EPAREN", "parentheses () not balanced" },
{ REG_EBRACE, "REG_EBRACE", "braces {} not balanced" },
{ REG_BADBR, "REG_BADBR", "invalid repetition count(s)" },
{ REG_ERANGE, "REG_ERANGE", "invalid character range" },
{ REG_ESPACE, "REG_ESPACE", "out of memory" },
{ REG_BADRPT, "REG_BADRPT", "quantifier operand invalid" },
{ REG_ASSERT, "REG_ASSERT", "\"can't happen\" -- you found a bug" },
{ REG_INVARG, "REG_INVARG", "invalid argument to regex function" },
{ REG_MIXED, "REG_MIXED", "character widths of regex and string differ" },
{ REG_BADOPT, "REG_BADOPT", "invalid embedded option" },

View File

@@ -1,6 +1,5 @@
#ifndef _REGEX_H_
#define _REGEX_H_ /* never again */
/*
* regular expressions
*
@@ -30,35 +29,98 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Id$
*
*
* Prototypes etc. marked with "^" within comments get gathered up (and
* possibly edited) by the regfwd program and inserted near the bottom of
* this file.
*
* We offer the option of declaring one wide-character version of the
* RE functions as well as the char versions. To do that, define
* __REG_WIDE_T to the type of wide characters (unfortunately, there
* is no consensus that wchar_t is suitable) and __REG_WIDE_COMPILE and
* __REG_WIDE_EXEC to the names to be used for the compile and execute
* functions (suggestion: re_Xcomp and re_Xexec, where X is a letter
* suggestive of the wide type, e.g. re_ucomp and re_uexec for Unicode).
* For cranky old compilers, it may be necessary to do something like:
* #define __REG_WIDE_COMPILE(a,b,c,d) re_Xcomp(a,b,c,d)
* #define __REG_WIDE_EXEC(a,b,c,d,e,f,g) re_Xexec(a,b,c,d,e,f,g)
* rather than just #defining the names as parameterless macros.
*
* For some specialized purposes, it may be desirable to suppress the
* declarations of the "front end" functions, regcomp() and regexec(),
* or of the char versions of the compile and execute functions. To
* suppress the front-end functions, define __REG_NOFRONT. To suppress
* the char versions, define __REG_NOCHAR.
*
* The right place to do those defines (and some others you may want, see
* below) would be <sys/types.h>. If you don't have control of that file,
* the right place to add your own defines to this file is marked below.
* This is normally done automatically, by the makefile and regmkhdr, based
* on the contents of regcustom.h.
*/
/*
* Add your own defines, if needed, here.
* voodoo for C++
*/
#ifdef __cplusplus
extern "C" {
#endif
/*****************************
WXWINDOWS CUSTOM
*****************************/
#ifndef _REGEX_CUSTOM_H_
# define wx_wchar wxChar
/* FreeBSD, Watcom and DMars require this, CW doesn't have nor need it. */
/* Others also don't seem to need it. If you have an error related to */
/* (not) including <sys/types.h> please report details to */
/* wx-dev@lists.wxwindows.org */
# if defined(__UNIX__) || defined(__WATCOMC__) || defined(__DIGITALMARS__)
# include <sys/types.h>
# endif
#endif /* ndef _REGEX_CUSTOM_H_ */
/*****************************
END WXWINDOWS CUSTOM
*****************************/
#include <stdio.h>
#include <stdlib.h>
/*
* Add your own defines, if needed, here.
*/
/*
* Location where a chunk of regcustom.h is automatically spliced into
* this file (working from its prototype, regproto.h).
*/
/* --- begin --- */
/* ensure certain things don't sneak in from system headers */
#ifdef __REG_WIDE_T
#undef __REG_WIDE_T
#endif
#ifdef __REG_WIDE_COMPILE
#undef __REG_WIDE_COMPILE
#endif
#ifdef __REG_WIDE_EXEC
#undef __REG_WIDE_EXEC
#endif
#ifdef __REG_REGOFF_T
#undef __REG_REGOFF_T
#endif
#ifdef __REG_VOID_T
#undef __REG_VOID_T
#endif
#ifdef __REG_CONST
#undef __REG_CONST
#endif
#ifdef __REG_NOFRONT
#undef __REG_NOFRONT
#endif
#ifdef __REG_NOCHAR
#undef __REG_NOCHAR
#endif
/* interface types */
#define __REG_WIDE_T Tcl_UniChar
#define __REG_REGOFF_T long /* not really right, but good enough... */
#define __REG_VOID_T VOID
#define __REG_CONST CONST
/* names and declarations */
#define __REG_WIDE_COMPILE TclReComp
#define __REG_WIDE_EXEC TclReExec
#define __REG_NOFRONT /* don't want regcomp() and regexec() */
#define __REG_NOCHAR /* or the char versions */
#define regfree TclReFree
#define regerror TclReError
/* --- end --- */
/*
* interface types etc.
@@ -66,34 +128,58 @@ extern "C" {
/*
* regoff_t has to be large enough to hold either off_t or ssize_t,
* and must be signed; it's only a guess that long is suitable.
* and must be signed; it's only a guess that long is suitable, so we
* offer <sys/types.h> an override.
*/
#ifdef __REG_REGOFF_T
typedef __REG_REGOFF_T regoff_t;
#else
typedef long regoff_t;
#endif
/*
* For benefit of old compilers, we offer <sys/types.h> the option of
* overriding the `void' type used to declare nonexistent return types.
*/
#ifdef __REG_VOID_T
typedef __REG_VOID_T re_void;
#else
typedef void re_void;
#endif
/*
* Also for benefit of old compilers, <sys/types.h> can supply a macro
* which expands to a substitute for `const'.
*/
#ifndef __REG_CONST
#define __REG_CONST const
#endif
/*
* other interface types
*/
/* the biggie, a compiled RE (or rather, a front end to same) */
typedef struct
{
typedef struct {
int re_magic; /* magic number */
size_t re_nsub; /* number of subexpressions */
long re_info; /* information about RE */
#define REG_UBACKREF 000001
#define REG_ULOOKAHEAD 000002
#define REG_UBOUNDS 000004
#define REG_UBRACES 000010
#define REG_UBSALNUM 000020
#define REG_UPBOTCH 000040
#define REG_UBBS 000100
#define REG_UNONPOSIX 000200
#define REG_UUNSPEC 000400
#define REG_UUNPORT 001000
#define REG_ULOCALE 002000
#define REG_UEMPTYMATCH 004000
#define REG_UIMPOSSIBLE 010000
#define REG_USHORTEST 020000
# define REG_UBACKREF 000001
# define REG_ULOOKAHEAD 000002
# define REG_UBOUNDS 000004
# define REG_UBRACES 000010
# define REG_UBSALNUM 000020
# define REG_UPBOTCH 000040
# define REG_UBBS 000100
# define REG_UNONPOSIX 000200
# define REG_UUNSPEC 000400
# define REG_UUNPORT 001000
# define REG_ULOCALE 002000
# define REG_UEMPTYMATCH 004000
# define REG_UIMPOSSIBLE 010000
# define REG_USHORTEST 020000
int re_csize; /* sizeof(character) */
char *re_endp; /* backward compatibility kludge */
/* the rest is opaque pointers to hidden innards */
@@ -102,22 +188,29 @@ typedef struct
} regex_t;
/* result reporting (may acquire more fields later) */
typedef struct
{
typedef struct {
regoff_t rm_so; /* start of substring */
regoff_t rm_eo; /* end of substring */
} regmatch_t;
/* supplementary control and reporting */
typedef struct
{
typedef struct {
regmatch_t rm_extend; /* see REG_EXPECT */
} rm_detail_t;
/*
* regex compilation flags
* compilation
^ #ifndef __REG_NOCHAR
^ int re_comp(regex_t *, __REG_CONST char *, size_t, int);
^ #endif
^ #ifndef __REG_NOFRONT
^ int regcomp(regex_t *, __REG_CONST char *, int);
^ #endif
^ #ifdef __REG_WIDE_T
^ int __REG_WIDE_COMPILE(regex_t *, __REG_CONST __REG_WIDE_T *, size_t, int);
^ #endif
*/
#define REG_BASIC 000000 /* BREs (convenience) */
#define REG_EXTENDED 000001 /* EREs */
@@ -132,8 +225,7 @@ typedef struct
#define REG_NLANCH 000200 /* ^ matches after \n, $ before */
#define REG_NEWLINE 000300 /* newlines are line terminators */
#define REG_PEND 000400 /* ugh -- backward-compatibility hack */
#define REG_EXPECT 001000 /* report details on partial/limited
* matches */
#define REG_EXPECT 001000 /* report details on partial/limited matches */
#define REG_BOSONLY 002000 /* temporary kludge for BOS-only matches */
#define REG_DUMP 004000 /* none of your business :-) */
#define REG_FAKE 010000 /* none of your business :-) */
@@ -142,7 +234,18 @@ typedef struct
/*
* regex execution flags
* execution
^ #ifndef __REG_NOCHAR
^ int re_exec(regex_t *, __REG_CONST char *, size_t,
^ rm_detail_t *, size_t, regmatch_t [], int);
^ #endif
^ #ifndef __REG_NOFRONT
^ int regexec(regex_t *, __REG_CONST char *, size_t, regmatch_t [], int);
^ #endif
^ #ifdef __REG_WIDE_T
^ int __REG_WIDE_EXEC(regex_t *, __REG_CONST __REG_WIDE_T *, size_t,
^ rm_detail_t *, size_t, regmatch_t [], int);
^ #endif
*/
#define REG_NOTBOL 0001 /* BOS is not BOL */
#define REG_NOTEOL 0002 /* EOS is not EOL */
@@ -152,10 +255,24 @@ typedef struct
#define REG_SMALL 0040 /* none of your business */
/*
* misc generics (may be more functions here eventually)
^ re_void regfree(regex_t *);
*/
/*
* error reporting
* Be careful if modifying the list of error codes -- the table used by
* regerror() is generated automatically from this file!
*
* Note that there is no wide-char variant of regerror at this time; what
* kind of character is used for error reports is independent of what kind
* is used in matching.
*
^ extern size_t regerror(int, __REG_CONST regex_t *, char *, size_t);
*/
#define REG_OKAY 0 /* no errors detected */
#define REG_NOMATCH 1 /* failed to match */
@@ -173,8 +290,7 @@ typedef struct
#define REG_BADRPT 13 /* quantifier operand invalid */
#define REG_ASSERT 15 /* "can't happen" -- you found a bug */
#define REG_INVARG 16 /* invalid argument to regex function */
#define REG_MIXED 17 /* character widths of regex and string
* differ */
#define REG_MIXED 17 /* character widths of regex and string differ */
#define REG_BADOPT 18 /* invalid embedded option */
/* two specials for debugging and testing */
#define REG_ATOI 101 /* convert error-code name to number */
@@ -183,19 +299,43 @@ typedef struct
/*
* the prototypes for exported functions
* the prototypes, as possibly munched by regfwd
*/
extern int wx_regcomp(regex_t *, const wx_wchar *, size_t, int);
extern int regcomp(regex_t *, const wx_wchar *, int);
extern int wx_regexec(regex_t *, const wx_wchar *, size_t, rm_detail_t *, size_t, regmatch_t[], int);
extern int regexec(regex_t *, const wx_wchar *, size_t, regmatch_t[], int);
extern void regfree(regex_t *);
extern size_t regerror(int, const regex_t *, char *, size_t);
extern void wx_regfree(regex_t *);
extern size_t wx_regerror(int, const regex_t *, char *, size_t);
/* =====^!^===== begin forwards =====^!^===== */
/* automatically gathered by fwd; do not hand-edit */
/* === regproto.h === */
#ifndef __REG_NOCHAR
int re_comp _ANSI_ARGS_((regex_t *, __REG_CONST char *, size_t, int));
#endif
#ifndef __REG_NOFRONT
int regcomp _ANSI_ARGS_((regex_t *, __REG_CONST char *, int));
#endif
#ifdef __REG_WIDE_T
int __REG_WIDE_COMPILE _ANSI_ARGS_((regex_t *, __REG_CONST __REG_WIDE_T *, size_t, int));
#endif
#ifndef __REG_NOCHAR
int re_exec _ANSI_ARGS_((regex_t *, __REG_CONST char *, size_t, rm_detail_t *, size_t, regmatch_t [], int));
#endif
#ifndef __REG_NOFRONT
int regexec _ANSI_ARGS_((regex_t *, __REG_CONST char *, size_t, regmatch_t [], int));
#endif
#ifdef __REG_WIDE_T
int __REG_WIDE_EXEC _ANSI_ARGS_((regex_t *, __REG_CONST __REG_WIDE_T *, size_t, rm_detail_t *, size_t, regmatch_t [], int));
#endif
re_void regfree _ANSI_ARGS_((regex_t *));
extern size_t regerror _ANSI_ARGS_((int, __REG_CONST regex_t *, char *, size_t));
/* automatically gathered by fwd; do not hand-edit */
/* =====^!^===== end forwards =====^!^===== */
/*
* more C++ voodoo
*/
#ifdef __cplusplus
}
#endif
#endif /* _REGEX_H_ */
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -27,7 +27,6 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Header: /projects/cvsroot/pgsql-server/src/backend/regex/regfree.c,v 1.17 2003/08/04 00:43:21 momjian Exp $
*
*
* You might think that this could be incorporated into regcomp.c, and
@@ -39,19 +38,16 @@
#include "regguts.h"
/*
* pg_regfree - free an RE (generic function, punts to RE-specific function)
- regfree - free an RE (generic function, punts to RE-specific function)
*
* Ignoring invocation with NULL is a convenience.
*/
void
regfree(regex_t *re)
{ wx_regfree(re); }
void
wx_regfree(regex_t *re)
VOID
regfree(re)
regex_t *re;
{
if (re == NULL)
return;
(*((struct fns *) re->re_fns)->free) (re);
(*((struct fns *)re->re_fns)->free)(re);
}

View File

@@ -26,8 +26,6 @@
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Id$
*/
@@ -45,32 +43,52 @@
* Things that regcustom.h might override.
*/
/* standard header files (NULL is a reasonable indicator for them) */
#ifndef NULL
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <limits.h>
#include <string.h>
#endif
/* assertions */
#ifndef __WXWINCE__
#ifndef assert
#ifndef REG_DEBUG
# ifndef NDEBUG
# ifndef REG_DEBUG
# define NDEBUG /* no assertions */
# endif
#endif
#include <assert.h>
#endif
#else
// To do: assertion on WinCE
#define assert(x)
#endif
/* voids */
#ifndef VOID
#define VOID void /* for function return values */
#endif
#ifndef DISCARD
#define DISCARD void /* for throwing values away */
#define DISCARD VOID /* for throwing values away */
#endif
#ifndef PVOID
#define PVOID VOID * /* generic pointer */
#endif
#ifndef VS
#define VS(x) ((void *)(x)) /* cast something to generic ptr */
#define VS(x) ((PVOID)(x)) /* cast something to generic ptr */
#endif
#ifndef NOPARMS
#define NOPARMS VOID /* for empty parm lists */
#endif
/* const */
#ifndef CONST
#define CONST const /* for old compilers, might be empty */
#endif
/* function-pointer declarator */
#ifndef FUNCPTR
#define FUNCPTR(name, args) (*name) args
#if __STDC__ >= 1
#define FUNCPTR(name, args) (*name)args
#else
#define FUNCPTR(name, args) (*name)()
#endif
#endif
/* memory allocation */
@@ -141,8 +159,7 @@
#ifndef BYTBITS
#define BYTBITS 8 /* bits in a byt */
#endif
#define BYTTAB (1<<BYTBITS) /* size of table with one entry per byt
* value */
#define BYTTAB (1<<BYTBITS) /* size of table with one entry per byt value */
#define BYTMASK (BYTTAB-1) /* bit mask for byt */
#define NBYTS ((CHRBITS+BYTBITS-1)/BYTBITS)
/* the definition of GETCOLOR(), below, assumes NBYTS <= 4 */
@@ -155,7 +172,6 @@
*/
typedef short color; /* colors of characters */
typedef int pcolor; /* what color promotes to */
#define COLORLESS (-1) /* impossible color */
#define WHITE 0 /* default color, parent of all others */
@@ -172,49 +188,43 @@ typedef int pcolor; /* what color promotes to */
*/
/* the tree itself */
struct colors
{
struct colors {
color ccolor[BYTTAB];
};
struct ptrs
{
struct ptrs {
union tree *pptr[BYTTAB];
};
union tree
{
union tree {
struct colors colors;
struct ptrs ptrs;
};
#define tcolor colors.ccolor
#define tptr ptrs.pptr
/* internal per-color structure for the color machinery */
struct colordesc
{
struct colordesc {
uchr nchrs; /* number of chars of this color */
color sub; /* open subcolor (if any); free chain ptr */
#define NOSUB COLORLESS
# define NOSUB COLORLESS
struct arc *arcs; /* color chain */
int flags;
#define FREECOL 01 /* currently free */
#define PSEUDO 02 /* pseudocolor, no real chars */
#define UNUSEDCOLOR(cd) ((cd)->flags&FREECOL)
# define FREECOL 01 /* currently free */
# define PSEUDO 02 /* pseudocolor, no real chars */
# define UNUSEDCOLOR(cd) ((cd)->flags&FREECOL)
union tree *block; /* block of solid color, if any */
};
/* the color map itself */
struct colormap
{
struct colormap {
int magic;
#define CMMAGIC 0x876
# define CMMAGIC 0x876
struct vars *v; /* for compile error reporting */
size_t ncds; /* number of colordescs */
size_t max; /* highest in use */
color free; /* beginning of free chain (if non-0) */
struct colordesc *cd;
#define CDEND(cm) (&(cm)->cd[(cm)->max + 1])
#define NINLINECDS ((size_t)10)
# define CDEND(cm) (&(cm)->cd[(cm)->max + 1])
# define NINLINECDS ((size_t)10)
struct colordesc cdspace[NINLINECDS];
union tree tree[NBYTS]; /* tree top, plus fill blocks */
};
@@ -241,8 +251,7 @@ struct colormap
* Interface definitions for locale-interface functions in locale.c.
* Multi-character collating elements (MCCEs) cause most of the trouble.
*/
struct cvec
{
struct cvec {
int nchrs; /* number of chrs */
int chrspace; /* number of chrs possible */
chr *chrs; /* pointer to vector of chrs */
@@ -269,30 +278,27 @@ struct cvec
*/
struct state;
struct arc
{
struct arc {
int type;
#define ARCFREE '\0'
# define ARCFREE '\0'
color co;
struct state *from; /* where it's from (and contained within) */
struct state *to; /* where it's to */
struct arc *outchain; /* *from's outs chain or free chain */
#define freechain outchain
# define freechain outchain
struct arc *inchain; /* *to's ins chain */
struct arc *colorchain; /* color's arc chain */
};
struct arcbatch
{ /* for bulk allocation of arcs */
struct arcbatch { /* for bulk allocation of arcs */
struct arcbatch *next;
#define ABSIZE 10
# define ABSIZE 10
struct arc a[ABSIZE];
};
struct state
{
struct state {
int no;
#define FREESTATE (-1)
# define FREESTATE (-1)
char flag; /* marks special states */
int nins; /* number of inarcs */
struct arc *ins; /* chain of inarcs */
@@ -302,13 +308,11 @@ struct state
struct state *tmp; /* temporary for traversal algorithms */
struct state *next; /* chain for traversing all */
struct state *prev; /* back chain */
struct arcbatch oas; /* first arcbatch, avoid malloc in easy
* case */
struct arcbatch oas; /* first arcbatch, avoid malloc in easy case */
int noas; /* number of arcs used in first arcbatch */
};
struct nfa
{
struct nfa {
struct state *pre; /* pre-initial state */
struct state *init; /* initial state */
struct state *final; /* final state */
@@ -329,18 +333,16 @@ struct nfa
/*
* definitions for compacted NFA
*/
struct carc
{
struct carc {
color co; /* COLORLESS is list terminator */
int to; /* state number */
};
struct cnfa
{
struct cnfa {
int nstates; /* number of states */
int ncolors; /* number of colors */
int flags;
#define HASLACONS 01 /* uses lookahead constraints */
# define HASLACONS 01 /* uses lookahead constraints */
int pre; /* setup state number */
int post; /* teardown state number */
color bos[2]; /* colors, if any, assigned to BOS and BOL */
@@ -348,7 +350,6 @@ struct cnfa
struct carc **states; /* vector of pointers to outarc lists */
struct carc *arcs; /* the area for the lists */
};
#define ZAPCNFA(cnfa) ((cnfa).nstates = 0)
#define NULLCNFA(cnfa) ((cnfa).nstates == 0)
@@ -357,31 +358,28 @@ struct cnfa
/*
* subexpression tree
*/
struct subre
{
char op; /* '|', '.' (concat), 'b' (backref), '(',
* '=' */
struct subre {
char op; /* '|', '.' (concat), 'b' (backref), '(', '=' */
char flags;
#define LONGER 01 /* prefers longer match */
#define SHORTER 02 /* prefers shorter match */
#define MIXED 04 /* mixed preference below */
#define CAP 010 /* capturing parens below */
#define BACKR 020 /* back reference below */
#define INUSE 0100 /* in use in final tree */
#define LOCAL 03 /* bits which may not propagate up */
#define LMIX(f) ((f)<<2) /* LONGER -> MIXED */
#define SMIX(f) ((f)<<1) /* SHORTER -> MIXED */
#define UP(f) (((f)&~LOCAL) | (LMIX(f) & SMIX(f) & MIXED))
#define MESSY(f) ((f)&(MIXED|CAP|BACKR))
#define PREF(f) ((f)&LOCAL)
#define PREF2(f1, f2) ((PREF(f1) != 0) ? PREF(f1) : PREF(f2))
#define COMBINE(f1, f2) (UP((f1)|(f2)) | PREF2(f1, f2))
# define LONGER 01 /* prefers longer match */
# define SHORTER 02 /* prefers shorter match */
# define MIXED 04 /* mixed preference below */
# define CAP 010 /* capturing parens below */
# define BACKR 020 /* back reference below */
# define INUSE 0100 /* in use in final tree */
# define LOCAL 03 /* bits which may not propagate up */
# define LMIX(f) ((f)<<2) /* LONGER -> MIXED */
# define SMIX(f) ((f)<<1) /* SHORTER -> MIXED */
# define UP(f) (((f)&~LOCAL) | (LMIX(f) & SMIX(f) & MIXED))
# define MESSY(f) ((f)&(MIXED|CAP|BACKR))
# define PREF(f) ((f)&LOCAL)
# define PREF2(f1, f2) ((PREF(f1) != 0) ? PREF(f1) : PREF(f2))
# define COMBINE(f1, f2) (UP((f1)|(f2)) | PREF2(f1, f2))
short retry; /* index into retry memory */
int subno; /* subexpression number (for 'b' and '(') */
short min; /* min repetitions, for backref only */
short max; /* max repetitions, for backref only */
struct subre *left; /* left child, if any (also freelist
* chain) */
struct subre *left; /* left child, if any (also freelist chain) */
struct subre *right; /* right child, if any */
struct state *begin; /* outarcs from here... */
struct state *end; /* ...ending in inarcs here */
@@ -395,9 +393,8 @@ struct subre
* table of function pointers for generic manipulation functions
* A regex_t's re_fns points to one of these.
*/
struct fns
{
void FUNCPTR(free, (regex_t *));
struct fns {
VOID FUNCPTR(free, (regex_t *));
};
@@ -405,10 +402,9 @@ struct fns
/*
* the insides of a regex_t, hidden behind a void *
*/
struct guts
{
struct guts {
int magic;
#define GUTSMAGIC 0xfed9
# define GUTSMAGIC 0xfed9
int cflags; /* copy of compile flags */
long info; /* copy of re_info */
size_t nsub; /* copy of re_nsub */
@@ -416,7 +412,7 @@ struct guts
struct cnfa search; /* for fast preliminary search */
int ntree;
struct colormap cmap;
int FUNCPTR(compare, (const chr *, const chr *, size_t));
int FUNCPTR(compare, (CONST chr *, CONST chr *, size_t));
struct subre *lacons; /* lookahead-constraint vector */
int nlacons; /* size of lacons */
};