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

@@ -2,21 +2,21 @@
* colorings of characters * colorings of characters
* This file is #included by regcomp.c. * This file is #included by regcomp.c.
* *
* Copyright (c) 1998, 1999 Henry Spencer. All rights reserved. * Copyright (c) 1998, 1999 Henry Spencer. All rights reserved.
* *
* Development of this software was funded, in part, by Cray Research Inc., * Development of this software was funded, in part, by Cray Research Inc.,
* UUNET Communications Services Inc., Sun Microsystems Inc., and Scriptics * UUNET Communications Services Inc., Sun Microsystems Inc., and Scriptics
* Corporation, none of whom are responsible for the results. The author * Corporation, none of whom are responsible for the results. The author
* thanks all of them. * thanks all of them.
* *
* Redistribution and use in source and binary forms -- with or without * Redistribution and use in source and binary forms -- with or without
* modification -- are permitted for any purpose, provided that * modification -- are permitted for any purpose, provided that
* redistributions in source form retain this entire copyright notice and * redistributions in source form retain this entire copyright notice and
* indicate the origin and nature of any modifications. * indicate the origin and nature of any modifications.
* *
* I'd appreciate being given credit for this package in the documentation * I'd appreciate being given credit for this package in the documentation
* of software which uses it, but that is not a requirement. * of software which uses it, but that is not a requirement.
* *
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
@@ -28,7 +28,6 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
* $Header$
* *
* *
* Note that there are some incestuous relationships between this code and * Note that there are some incestuous relationships between this code and
@@ -37,20 +36,22 @@
#define CISERR() VISERR(cm->v) #define CISERR() VISERR(cm->v)
#define CERR(e) VERR(cm->v, (e)) #define CERR(e) VERR(cm->v, (e))
/* /*
* initcm - set up new colormap - initcm - set up new colormap
^ static VOID initcm(struct vars *, struct colormap *);
*/ */
static void static VOID
initcm(struct vars * v, initcm(v, cm)
struct colormap * cm) struct vars *v;
struct colormap *cm;
{ {
int i; int i;
int j; int j;
union tree *t; union tree *t;
union tree *nextt; union tree *nextt;
struct colordesc *cd; struct colordesc *cd;
@@ -63,41 +64,41 @@ initcm(struct vars * v,
cm->max = 0; cm->max = 0;
cm->free = 0; cm->free = 0;
cd = cm->cd; /* cm->cd[WHITE] */ cd = cm->cd; /* cm->cd[WHITE] */
cd->sub = NOSUB; cd->sub = NOSUB;
cd->arcs = NULL; cd->arcs = NULL;
cd->flags = 0; cd->flags = 0;
cd->nchrs = CHR_MAX - CHR_MIN + 1; cd->nchrs = CHR_MAX - CHR_MIN + 1;
/* upper levels of tree */ /* 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; nextt = t + 1;
for (i = BYTTAB - 1; i >= 0; i--) for (i = BYTTAB-1; i >= 0; i--)
t->tptr[i] = nextt; t->tptr[i] = nextt;
} }
/* bottom level is solid white */ /* bottom level is solid white */
t = &cm->tree[NBYTS - 1]; t = &cm->tree[NBYTS-1];
for (i = BYTTAB - 1; i >= 0; i--) for (i = BYTTAB-1; i >= 0; i--)
t->tcolor[i] = WHITE; t->tcolor[i] = WHITE;
cd->block = t; 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 static VOID
freecm(struct colormap * cm) freecm(cm)
struct colormap *cm;
{ {
size_t i; size_t i;
union tree *cb; union tree *cb;
cm->magic = 0; cm->magic = 0;
if (NBYTS > 1) if (NBYTS > 1)
cmtreefree(cm, cm->tree, 0); cmtreefree(cm, cm->tree, 0);
for (i = 1; i <= cm->max; i++) /* skip WHITE */ for (i = 1; i <= cm->max; i++) /* skip WHITE */
if (!UNUSEDCOLOR(&cm->cd[i])) if (!UNUSEDCOLOR(&cm->cd[i])) {
{
cb = cm->cd[i].block; cb = cm->cd[i].block;
if (cb != NULL) if (cb != NULL)
FREE(cb); 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 static VOID
cmtreefree(struct colormap * cm, cmtreefree(cm, tree, level)
union tree * tree, struct colormap *cm;
int level) /* level number (top == 0) of this block */ union tree *tree;
int level; /* level number (top == 0) of this block */
{ {
int i; int i;
union tree *t; union tree *t;
union tree *fillt = &cm->tree[level + 1]; union tree *fillt = &cm->tree[level+1];
union tree *cb; union tree *cb;
assert(level < NBYTS - 1); /* this level has pointers */ assert(level < NBYTS-1); /* this level has pointers */
for (i = BYTTAB - 1; i >= 0; i--) for (i = BYTTAB-1; i >= 0; i--) {
{
t = tree->tptr[i]; t = tree->tptr[i];
assert(t != NULL); assert(t != NULL);
if (t != fillt) if (t != fillt) {
{ if (level < NBYTS-2) { /* more pointer blocks below */
if (level < NBYTS - 2) cmtreefree(cm, t, level+1);
{ /* more pointer blocks below */
cmtreefree(cm, t, level + 1);
FREE(t); FREE(t);
} } else { /* color block below */
else
{ /* color block below */
cb = cm->cd[t->tcolor[0]].block; cb = cm->cd[t->tcolor[0]].block;
if (t != cb) /* not a solid block */ if (t != cb) /* not a solid block */
FREE(t); FREE(t);
@@ -142,24 +140,26 @@ 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 */ static color /* previous color */
setcolor(struct colormap * cm, setcolor(cm, c, co)
chr c, struct colormap *cm;
pcolor co) pchr c;
pcolor co;
{ {
uchr uc = c; uchr uc = c;
int shift; int shift;
int level; int level;
int b; int b;
int bottom; int bottom;
union tree *t; union tree *t;
union tree *newt; union tree *newt;
union tree *fillt; union tree *fillt;
union tree *lastt; union tree *lastt;
union tree *cb; union tree *cb;
color prev; color prev;
assert(cm->magic == CMMAGIC); assert(cm->magic == CMMAGIC);
if (CISERR() || co == COLORLESS) if (CISERR() || co == COLORLESS)
@@ -167,30 +167,27 @@ setcolor(struct colormap * cm,
t = cm->tree; t = cm->tree;
for (level = 0, shift = BYTBITS * (NBYTS - 1); shift > 0; for (level = 0, shift = BYTBITS * (NBYTS - 1); shift > 0;
level++, shift -= BYTBITS) level++, shift -= BYTBITS) {
{
b = (uc >> shift) & BYTMASK; b = (uc >> shift) & BYTMASK;
lastt = t; lastt = t;
t = lastt->tptr[b]; t = lastt->tptr[b];
assert(t != NULL); assert(t != NULL);
fillt = &cm->tree[level + 1]; fillt = &cm->tree[level+1];
bottom = (shift <= BYTBITS) ? 1 : 0; bottom = (shift <= BYTBITS) ? 1 : 0;
cb = (bottom) ? cm->cd[t->tcolor[0]].block : fillt; cb = (bottom) ? cm->cd[t->tcolor[0]].block : fillt;
if (t == fillt || t == cb) if (t == fillt || t == cb) { /* must allocate a new block */
{ /* must allocate a new block */ newt = (union tree *)MALLOC((bottom) ?
newt = (union tree *) MALLOC((bottom) ? sizeof(struct colors) : sizeof(struct ptrs));
sizeof(struct colors) : sizeof(struct ptrs)); if (newt == NULL) {
if (newt == NULL)
{
CERR(REG_ESPACE); CERR(REG_ESPACE);
return COLORLESS; return COLORLESS;
} }
if (bottom) if (bottom)
memcpy(VS(newt->tcolor), VS(t->tcolor), memcpy(VS(newt->tcolor), VS(t->tcolor),
BYTTAB * sizeof(color)); BYTTAB*sizeof(color));
else else
memcpy(VS(newt->tptr), VS(t->tptr), memcpy(VS(newt->tptr), VS(t->tptr),
BYTTAB * sizeof(union tree *)); BYTTAB*sizeof(union tree *));
t = newt; t = newt;
lastt->tptr[b] = t; lastt->tptr[b] = t;
} }
@@ -198,67 +195,63 @@ setcolor(struct colormap * cm,
b = uc & BYTMASK; b = uc & BYTMASK;
prev = t->tcolor[b]; prev = t->tcolor[b];
t->tcolor[b] = (color) co; t->tcolor[b] = (color)co;
return prev; return prev;
} }
/* /*
* maxcolor - report largest color number in use - maxcolor - report largest color number in use
^ static color maxcolor(struct colormap *);
*/ */
static color static color
maxcolor(struct colormap * cm) maxcolor(cm)
struct colormap *cm;
{ {
if (CISERR()) if (CISERR())
return COLORLESS; 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. * Beware: may relocate the colordescs.
^ static color newcolor(struct colormap *);
*/ */
static color /* COLORLESS for error */ static color /* COLORLESS for error */
newcolor(struct colormap * cm) newcolor(cm)
struct colormap *cm;
{ {
struct colordesc *cd; struct colordesc *cd;
struct colordesc *new; struct colordesc *new;
size_t n; size_t n;
if (CISERR()) if (CISERR())
return COLORLESS; return COLORLESS;
if (cm->free != 0) if (cm->free != 0) {
{
assert(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]; cd = &cm->cd[cm->free];
assert(UNUSEDCOLOR(cd)); assert(UNUSEDCOLOR(cd));
assert(cd->arcs == NULL); assert(cd->arcs == NULL);
cm->free = cd->sub; cm->free = cd->sub;
} } else if (cm->max < cm->ncds - 1) {
else if (cm->max < cm->ncds - 1)
{
cm->max++; cm->max++;
cd = &cm->cd[cm->max]; cd = &cm->cd[cm->max];
} } else {
else
{
/* oops, must allocate more */ /* oops, must allocate more */
n = cm->ncds * 2; n = cm->ncds * 2;
if (cm->cd == cm->cdspace) if (cm->cd == cm->cdspace) {
{ new = (struct colordesc *)MALLOC(n *
new = (struct colordesc *) MALLOC(n * sizeof(struct colordesc));
sizeof(struct colordesc));
if (new != NULL) if (new != NULL)
memcpy(VS(new), VS(cm->cdspace), cm->ncds * memcpy(VS(new), VS(cm->cdspace), cm->ncds *
sizeof(struct colordesc)); sizeof(struct colordesc));
} } else
else new = (struct colordesc *)REALLOC(cm->cd,
new = (struct colordesc *) REALLOC(cm->cd, n * sizeof(struct colordesc));
n * sizeof(struct colordesc)); if (new == NULL) {
if (new == NULL)
{
CERR(REG_ESPACE); CERR(REG_ESPACE);
return COLORLESS; return COLORLESS;
} }
@@ -275,19 +268,20 @@ newcolor(struct colormap * cm)
cd->flags = 0; cd->flags = 0;
cd->block = NULL; 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 static VOID
freecolor(struct colormap * cm, freecolor(cm, co)
pcolor co) struct colormap *cm;
pcolor co;
{ {
struct colordesc *cd = &cm->cd[co]; struct colordesc *cd = &cm->cd[co];
color pco, color pco, nco; /* for freelist scan */
nco; /* for freelist scan */
assert(co >= 0); assert(co >= 0);
if (co == WHITE) if (co == WHITE)
@@ -297,53 +291,47 @@ freecolor(struct colormap * cm,
assert(cd->sub == NOSUB); assert(cd->sub == NOSUB);
assert(cd->nchrs == 0); assert(cd->nchrs == 0);
cd->flags = FREECOL; cd->flags = FREECOL;
if (cd->block != NULL) if (cd->block != NULL) {
{
FREE(cd->block); FREE(cd->block);
cd->block = NULL; /* just paranoia */ 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])) while (cm->max > WHITE && UNUSEDCOLOR(&cm->cd[cm->max]))
cm->max--; cm->max--;
assert(cm->free >= 0); 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; cm->free = cm->cd[cm->free].sub;
if (cm->free > 0) if (cm->free > 0) {
{
assert(cm->free < cm->max); assert(cm->free < cm->max);
pco = cm->free; pco = cm->free;
nco = cm->cd[pco].sub; nco = cm->cd[pco].sub;
while (nco > 0) while (nco > 0)
if ((size_t) nco > cm->max) if ((size_t)nco > cm->max) {
{
/* take this one out of freelist */ /* take this one out of freelist */
nco = cm->cd[nco].sub; nco = cm->cd[nco].sub;
cm->cd[pco].sub = nco; cm->cd[pco].sub = nco;
} } else {
else
{
assert(nco < cm->max); assert(nco < cm->max);
pco = nco; pco = nco;
nco = cm->cd[pco].sub; nco = cm->cd[pco].sub;
} }
} }
} } else {
else
{
cd->sub = cm->free; 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 static color
pseudocolor(struct colormap * cm) pseudocolor(cm)
struct colormap *cm;
{ {
color co; color co;
co = newcolor(cm); co = newcolor(cm);
if (CISERR()) if (CISERR())
@@ -354,13 +342,16 @@ 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 static color
subcolor(struct colormap * cm, chr c) subcolor(cm, c)
struct colormap *cm;
pchr c;
{ {
color co; /* current color of c */ color co; /* current color of c */
color sco; /* new subcolor */ color sco; /* new subcolor */
co = GETCOLOR(cm, c); co = GETCOLOR(cm, c);
sco = newsub(cm, co); sco = newsub(cm, co);
@@ -368,8 +359,8 @@ subcolor(struct colormap * cm, chr c)
return COLORLESS; return COLORLESS;
assert(sco != COLORLESS); assert(sco != COLORLESS);
if (co == sco) /* already in an open subcolor */ if (co == sco) /* already in an open subcolor */
return co; /* rest is redundant */ return co; /* rest is redundant */
cm->cd[co].nchrs--; cm->cd[co].nchrs--;
cm->cd[sco].nchrs++; cm->cd[sco].nchrs++;
setcolor(cm, c, sco); setcolor(cm, c, sco);
@@ -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 static color
newsub(struct colormap * cm, newsub(cm, co)
pcolor co) struct colormap *cm;
pcolor co;
{ {
color sco; /* new subcolor */ color sco; /* new subcolor */
sco = cm->cd[co].sub; sco = cm->cd[co].sub;
if (sco == NOSUB) if (sco == NOSUB) { /* color has no open subcolor */
{ /* color has no open subcolor */ if (cm->cd[co].nchrs == 1) /* optimization */
if (cm->cd[co].nchrs == 1) /* optimization */
return co; return co;
sco = newcolor(cm); /* must create subcolor */ sco = newcolor(cm); /* must create subcolor */
if (sco == COLORLESS) if (sco == COLORLESS) {
{
assert(CISERR()); assert(CISERR());
return COLORLESS; return COLORLESS;
} }
@@ -405,26 +396,29 @@ 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 static VOID
subrange(struct vars * v, subrange(v, from, to, lp, rp)
chr from, struct vars *v;
chr to, pchr from;
struct state * lp, pchr to;
struct state * rp) struct state *lp;
struct state *rp;
{ {
uchr uf; uchr uf;
int i; int i;
assert(from <= to); assert(from <= to);
/* first, align "from" on a tree-block boundary */ /* first, align "from" on a tree-block boundary */
uf = (uchr) from; uf = (uchr)from;
i = (int) (((uf + BYTTAB - 1) & (uchr) ~BYTMASK) - uf); i = (int)( ((uf + BYTTAB-1) & (uchr)~BYTMASK) - uf );
for (; from <= to && i > 0; i--, from++) for (; from <= to && i > 0; i--, from++)
newarc(v->nfa, PLAIN, subcolor(v->cm, from), lp, rp); newarc(v->nfa, PLAIN, subcolor(v->cm, from), lp, rp);
if (from > to) /* didn't reach a boundary */ if (from > to) /* didn't reach a boundary */
return; return;
/* deal with whole blocks */ /* deal with whole blocks */
@@ -437,28 +431,30 @@ 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 static VOID
subblock(struct vars * v, subblock(v, start, lp, rp)
chr start, /* first of BYTTAB chrs */ struct vars *v;
struct state * lp, pchr start; /* first of BYTTAB chrs */
struct state * rp) struct state *lp;
struct state *rp;
{ {
uchr uc = start; uchr uc = start;
struct colormap *cm = v->cm; struct colormap *cm = v->cm;
int shift; int shift;
int level; int level;
int i; int i;
int b; int b;
union tree *t; union tree *t;
union tree *cb; union tree *cb;
union tree *fillt; union tree *fillt;
union tree *lastt; union tree *lastt;
int previ; int previ;
int ndone; int ndone;
color co; color co;
color sco; color sco;
assert((uc % BYTTAB) == 0); assert((uc % BYTTAB) == 0);
@@ -466,23 +462,20 @@ subblock(struct vars * v,
t = cm->tree; t = cm->tree;
fillt = NULL; fillt = NULL;
for (level = 0, shift = BYTBITS * (NBYTS - 1); shift > 0; for (level = 0, shift = BYTBITS * (NBYTS - 1); shift > 0;
level++, shift -= BYTBITS) level++, shift -= BYTBITS) {
{
b = (uc >> shift) & BYTMASK; b = (uc >> shift) & BYTMASK;
lastt = t; lastt = t;
t = lastt->tptr[b]; t = lastt->tptr[b];
assert(t != NULL); assert(t != NULL);
fillt = &cm->tree[level + 1]; fillt = &cm->tree[level+1];
if (t == fillt && shift > BYTBITS) if (t == fillt && shift > BYTBITS) { /* need new ptr block */
{ /* need new ptr block */ t = (union tree *)MALLOC(sizeof(struct ptrs));
t = (union tree *) MALLOC(sizeof(struct ptrs)); if (t == NULL) {
if (t == NULL)
{
CERR(REG_ESPACE); CERR(REG_ESPACE);
return; return;
} }
memcpy(VS(t->tptr), VS(fillt->tptr), memcpy(VS(t->tptr), VS(fillt->tptr),
BYTTAB * sizeof(union tree *)); BYTTAB*sizeof(union tree *));
lastt->tptr[b] = t; lastt->tptr[b] = t;
} }
} }
@@ -490,16 +483,13 @@ subblock(struct vars * v,
/* special cases: fill block or solid block */ /* special cases: fill block or solid block */
co = t->tcolor[0]; co = t->tcolor[0];
cb = cm->cd[co].block; cb = cm->cd[co].block;
if (t == fillt || t == cb) if (t == fillt || t == cb) {
{
/* either way, we want a subcolor solid block */ /* either way, we want a subcolor solid block */
sco = newsub(cm, co); sco = newsub(cm, co);
t = cm->cd[sco].block; t = cm->cd[sco].block;
if (t == NULL) if (t == NULL) { /* must set it up */
{ /* must set it up */ t = (union tree *)MALLOC(sizeof(struct colors));
t = (union tree *) MALLOC(sizeof(struct colors)); if (t == NULL) {
if (t == NULL)
{
CERR(REG_ESPACE); CERR(REG_ESPACE);
return; return;
} }
@@ -517,14 +507,12 @@ subblock(struct vars * v,
/* general case, a mixed block to be altered */ /* general case, a mixed block to be altered */
i = 0; i = 0;
while (i < BYTTAB) while (i < BYTTAB) {
{
co = t->tcolor[i]; co = t->tcolor[i];
sco = newsub(cm, co); sco = newsub(cm, co);
newarc(v->nfa, PLAIN, sco, lp, rp); newarc(v->nfa, PLAIN, sco, lp, rp);
previ = i; previ = i;
do do {
{
t->tcolor[i++] = sco; t->tcolor[i++] = sco;
} while (i < BYTTAB && t->tcolor[i] == co); } while (i < BYTTAB && t->tcolor[i] == co);
ndone = i - previ; ndone = i - previ;
@@ -534,40 +522,35 @@ 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 static VOID
okcolors(struct nfa * nfa, okcolors(nfa, cm)
struct colormap * cm) struct nfa *nfa;
struct colormap *cm;
{ {
struct colordesc *cd; struct colordesc *cd;
struct colordesc *end = CDEND(cm); struct colordesc *end = CDEND(cm);
struct colordesc *scd; struct colordesc *scd;
struct arc *a; struct arc *a;
color co; color co;
color sco; 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; sco = cd->sub;
if (UNUSEDCOLOR(cd) || sco == NOSUB) if (UNUSEDCOLOR(cd) || sco == NOSUB) {
{
/* has no subcolor, no further action */ /* has no subcolor, no further action */
} } else if (sco == co) {
else if (sco == co)
{
/* is subcolor, let parent deal with it */ /* 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 */ /* parent empty, its arcs change color to subcolor */
cd->sub = NOSUB; cd->sub = NOSUB;
scd = &cm->cd[sco]; scd = &cm->cd[sco];
assert(scd->nchrs > 0); assert(scd->nchrs > 0);
assert(scd->sub == sco); assert(scd->sub == sco);
scd->sub = NOSUB; scd->sub = NOSUB;
while ((a = cd->arcs) != NULL) while ((a = cd->arcs) != NULL) {
{
assert(a->co == co); assert(a->co == co);
/* uncolorchain(cm, a); */ /* uncolorchain(cm, a); */
cd->arcs = a->colorchain; cd->arcs = a->colorchain;
@@ -577,17 +560,14 @@ okcolors(struct nfa * nfa,
scd->arcs = a; scd->arcs = a;
} }
freecolor(cm, co); freecolor(cm, co);
} } else {
else
{
/* parent's arcs must gain parallel subcolor arcs */ /* parent's arcs must gain parallel subcolor arcs */
cd->sub = NOSUB; cd->sub = NOSUB;
scd = &cm->cd[sco]; scd = &cm->cd[sco];
assert(scd->nchrs > 0); assert(scd->nchrs > 0);
assert(scd->sub == sco); assert(scd->sub == sco);
scd->sub = NOSUB; 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); assert(a->co == co);
newarc(nfa, a->type, sco, a->from, a->to); 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 static VOID
colorchain(struct colormap * cm, colorchain(cm, a)
struct arc * a) struct colormap *cm;
struct arc *a;
{ {
struct colordesc *cd = &cm->cd[a->co]; struct colordesc *cd = &cm->cd[a->co];
@@ -609,36 +591,39 @@ 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 static VOID
uncolorchain(struct colormap * cm, uncolorchain(cm, a)
struct arc * a) struct colormap *cm;
struct arc *a;
{ {
struct colordesc *cd = &cm->cd[a->co]; struct colordesc *cd = &cm->cd[a->co];
struct arc *aa; struct arc *aa;
aa = cd->arcs; aa = cd->arcs;
if (aa == a) /* easy case */ if (aa == a) /* easy case */
cd->arcs = a->colorchain; cd->arcs = a->colorchain;
else else {
{
for (; aa != NULL && aa->colorchain != a; aa = aa->colorchain) for (; aa != NULL && aa->colorchain != a; aa = aa->colorchain)
continue; continue;
assert(aa != NULL); assert(aa != NULL);
aa->colorchain = a->colorchain; aa->colorchain = a->colorchain;
} }
a->colorchain = NULL; /* paranoia */ a->colorchain = NULL; /* paranoia */
} }
/* /*
* 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 */ static int /* predicate */
singleton(struct colormap * cm, singleton(cm, c)
chr c) struct colormap *cm;
pchr c;
{ {
color co; /* color of c */ color co; /* color of c */
co = GETCOLOR(cm, c); co = GETCOLOR(cm, c);
if (cm->cd[co].nchrs == 1 && cm->cd[co].sub == NOSUB) if (cm->cd[co].nchrs == 1 && cm->cd[co].sub == NOSUB)
@@ -647,81 +632,90 @@ 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 static VOID
rainbow(struct nfa * nfa, rainbow(nfa, cm, type, but, from, to)
struct colormap * cm, struct nfa *nfa;
int type, struct colormap *cm;
pcolor but, /* COLORLESS if no exceptions */ int type;
struct state * from, pcolor but; /* COLORLESS if no exceptions */
struct state * to) struct state *from;
struct state *to;
{ {
struct colordesc *cd; struct colordesc *cd;
struct colordesc *end = CDEND(cm); struct colordesc *end = CDEND(cm);
color co; color co;
for (cd = cm->cd, co = 0; cd < end && !CISERR(); cd++, co++) for (cd = cm->cd, co = 0; cd < end && !CISERR(); cd++, co++)
if (!UNUSEDCOLOR(cd) && cd->sub != co && co != but && if (!UNUSEDCOLOR(cd) && cd->sub != co && co != but &&
!(cd->flags & PSEUDO)) !(cd->flags&PSEUDO))
newarc(nfa, type, co, from, to); 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(). * 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 static VOID
colorcomplement(struct nfa * nfa, colorcomplement(nfa, cm, type, of, from, to)
struct colormap * cm, struct nfa *nfa;
int type, struct colormap *cm;
struct state * of, /* complements of this guy's PLAIN int type;
* outarcs */ struct state *of; /* complements of this guy's PLAIN outarcs */
struct state * from, struct state *from;
struct state * to) struct state *to;
{ {
struct colordesc *cd; struct colordesc *cd;
struct colordesc *end = CDEND(cm); struct colordesc *end = CDEND(cm);
color co; color co;
assert(of != from); assert(of != from);
for (cd = cm->cd, co = 0; cd < end && !CISERR(); cd++, co++) 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) if (findarc(of, PLAIN, co) == NULL)
newarc(nfa, type, co, from, to); newarc(nfa, type, co, from, to);
} }
#ifdef REG_DEBUG #ifdef REG_DEBUG
/*
^ #ifdef REG_DEBUG
*/
/* /*
* dumpcolors - debugging output - dumpcolors - debugging output
^ static VOID dumpcolors(struct colormap *, FILE *);
*/ */
static void static VOID
dumpcolors(struct colormap * cm, dumpcolors(cm, f)
FILE *f) struct colormap *cm;
FILE *f;
{ {
struct colordesc *cd; struct colordesc *cd;
struct colordesc *end; struct colordesc *end;
color co; color co;
chr c; chr c;
char *has; char *has;
fprintf(f, "max %ld\n", (long) cm->max); fprintf(f, "max %ld\n", (long)cm->max);
if (NBYTS > 1) if (NBYTS > 1)
fillcheck(cm, cm->tree, 0, f); fillcheck(cm, cm->tree, 0, f);
end = CDEND(cm); end = CDEND(cm);
for (cd = cm->cd + 1, co = 1; cd < end; cd++, co++) /* skip 0 */ for (cd = cm->cd + 1, co = 1; cd < end; cd++, co++) /* skip 0 */
if (!UNUSEDCOLOR(cd)) if (!UNUSEDCOLOR(cd)) {
{
assert(cd->nchrs > 0); assert(cd->nchrs > 0);
has = (cd->block != NULL) ? "#" : ""; has = (cd->block != NULL) ? "#" : "";
if (cd->flags & PSEUDO) if (cd->flags&PSEUDO)
fprintf(f, "#%2ld%s(ps): ", (long) co, has); fprintf(f, "#%2ld%s(ps): ", (long)co, has);
else else
fprintf(f, "#%2ld%s(%2d): ", (long) co, fprintf(f, "#%2ld%s(%2d): ", (long)co,
has, cd->nchrs); has, cd->nchrs);
/* it's hard to do this more efficiently */ /* it's hard to do this more efficiently */
for (c = CHR_MIN; c < CHR_MAX; c++) for (c = CHR_MIN; c < CHR_MAX; c++)
if (GETCOLOR(cm, c) == co) if (GETCOLOR(cm, c) == co)
@@ -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 static VOID
fillcheck(struct colormap * cm, fillcheck(cm, tree, level, f)
union tree * tree, struct colormap *cm;
int level, /* level number (top == 0) of this block */ union tree *tree;
FILE *f) int level; /* level number (top == 0) of this block */
FILE *f;
{ {
int i; int i;
union tree *t; 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 */ assert(level < NBYTS-1); /* this level has pointers */
for (i = BYTTAB - 1; i >= 0; i--) for (i = BYTTAB-1; i >= 0; i--) {
{
t = tree->tptr[i]; t = tree->tptr[i];
if (t == NULL) if (t == NULL)
fprintf(f, "NULL found in filled tree!\n"); fprintf(f, "NULL found in filled tree!\n");
else if (t == fillt) else if (t == fillt)
{ {}
} else if (level < NBYTS-2) /* more pointer blocks below */
else if (level < NBYTS - 2) /* more pointer blocks below */ fillcheck(cm, t, level+1, f);
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. * Kind of char-centric but works well enough for debug use.
^ static VOID dumpchr(pchr, FILE *);
*/ */
static void static VOID
dumpchr(chr c, dumpchr(c, f)
FILE *f) pchr c;
FILE *f;
{ {
#if wxUSE_UNICODE
fprintf(f, "Debugging not implemented in unicode mode");
#else
if (c == '\\') if (c == '\\')
fprintf(f, "\\\\"); fprintf(f, "\\\\");
else if (c > ' ' && c <= '~') else if (c > ' ' && c <= '~')
putc((char) c, f); putc((char)c, f);
else else
fprintf(f, "\\u%04lx", (long) c); fprintf(f, "\\u%04lx", (long)c);
#endif
} }
#endif /* REG_DEBUG */ /*
^ #endif
*/
#endif /* ifdef REG_DEBUG */

View File

@@ -2,21 +2,21 @@
* Utility functions for handling cvecs * Utility functions for handling cvecs
* This file is #included by regcomp.c. * This file is #included by regcomp.c.
* *
* Copyright (c) 1998, 1999 Henry Spencer. All rights reserved. * Copyright (c) 1998, 1999 Henry Spencer. All rights reserved.
* *
* Development of this software was funded, in part, by Cray Research Inc., * Development of this software was funded, in part, by Cray Research Inc.,
* UUNET Communications Services Inc., Sun Microsystems Inc., and Scriptics * UUNET Communications Services Inc., Sun Microsystems Inc., and Scriptics
* Corporation, none of whom are responsible for the results. The author * Corporation, none of whom are responsible for the results. The author
* thanks all of them. * thanks all of them.
* *
* Redistribution and use in source and binary forms -- with or without * Redistribution and use in source and binary forms -- with or without
* modification -- are permitted for any purpose, provided that * modification -- are permitted for any purpose, provided that
* redistributions in source form retain this entire copyright notice and * redistributions in source form retain this entire copyright notice and
* indicate the origin and nature of any modifications. * indicate the origin and nature of any modifications.
* *
* I'd appreciate being given credit for this package in the documentation * I'd appreciate being given credit for this package in the documentation
* of software which uses it, but that is not a requirement. * of software which uses it, but that is not a requirement.
* *
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
@@ -28,162 +28,181 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * 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 * static struct cvec *
newcvec(int nchrs, /* to hold this many chrs... */ newcvec(nchrs, nranges, nmcces)
int nranges, /* ... and this many ranges... */ int nchrs; /* to hold this many chrs... */
int nmcces) /* ... and this many MCCEs */ int nranges; /* ... and this many ranges... */
int nmcces; /* ... and this many MCCEs */
{ {
size_t n; size_t n;
size_t nc; size_t nc;
struct cvec *cv; struct cvec *cv;
nc = (size_t) nchrs + (size_t) nmcces *(MAXMCCE + 1) + (size_t) nranges *2; nc = (size_t)nchrs + (size_t)nmcces*(MAXMCCE+1) + (size_t)nranges*2;
n = sizeof(struct cvec) + (size_t)(nmcces-1)*sizeof(chr *)
n = sizeof(struct cvec) + (size_t) (nmcces - 1) * sizeof(chr *) + nc*sizeof(chr);
+ nc * sizeof(chr); cv = (struct cvec *)MALLOC(n);
cv = (struct cvec *) MALLOC(n); if (cv == NULL) {
if (cv == NULL) return NULL;
return NULL; }
cv->chrspace = nchrs; cv->chrspace = nchrs;
cv->chrs = (chr *) &cv->mcces[nmcces]; /* chrs just after MCCE cv->chrs = (chr *)&cv->mcces[nmcces]; /* chrs just after MCCE ptrs */
* ptrs */ cv->mccespace = nmcces;
cv->mccespace = nmcces; cv->ranges = cv->chrs + nchrs + nmcces*(MAXMCCE+1);
cv->ranges = cv->chrs + nchrs + nmcces * (MAXMCCE + 1); cv->rangespace = nranges;
cv->rangespace = nranges; return clearcvec(cv);
return clearcvec(cv);
} }
/* /*
* clearcvec - clear a possibly-new cvec - clearcvec - clear a possibly-new cvec
* Returns pointer as convenience. * Returns pointer as convenience.
^ static struct cvec *clearcvec(struct cvec *);
*/ */
static struct cvec * static struct cvec *
clearcvec(struct cvec * cv) clearcvec(cv)
struct cvec *cv; /* character vector */
{ {
int i; int i;
assert(cv != NULL); assert(cv != NULL);
cv->nchrs = 0; cv->nchrs = 0;
assert(cv->chrs == (chr *) &cv->mcces[cv->mccespace]); assert(cv->chrs == (chr *)&cv->mcces[cv->mccespace]);
cv->nmcces = 0; cv->nmcces = 0;
cv->nmccechrs = 0; cv->nmccechrs = 0;
cv->nranges = 0; cv->nranges = 0;
for (i = 0; i < cv->mccespace; i++) for (i = 0; i < cv->mccespace; i++) {
cv->mcces[i] = NULL; cv->mcces[i] = NULL;
}
return cv; return cv;
} }
/* /*
* addchr - add a chr to a cvec - addchr - add a chr to a cvec
^ static VOID addchr(struct cvec *, pchr);
*/ */
static void static VOID
addchr(struct cvec * cv, /* character vector */ addchr(cv, c)
chr c) /* character to add */ struct cvec *cv; /* character vector */
pchr c; /* character to add */
{ {
assert(cv->nchrs < cv->chrspace - cv->nmccechrs); 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 static VOID
addrange(struct cvec * cv, /* character vector */ addrange(cv, from, to)
chr from, /* first character of range */ struct cvec *cv; /* character vector */
chr to) /* last character of range */ pchr from; /* first character of range */
pchr to; /* last character of range */
{ {
assert(cv->nranges < cv->rangespace); assert(cv->nranges < cv->rangespace);
cv->ranges[cv->nranges * 2] = (chr) from; cv->ranges[cv->nranges*2] = (chr)from;
cv->ranges[cv->nranges * 2 + 1] = (chr) to; cv->ranges[cv->nranges*2 + 1] = (chr)to;
cv->nranges++; 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 static VOID
addmcce(struct cvec * cv, /* character vector */ addmcce(cv, startp, endp)
chr *startp, /* beginning of text */ struct cvec *cv; /* character vector */
chr *endp) /* just past end of text */ chr *startp; /* beginning of text */
chr *endp; /* just past end of text */
{ {
int len; int len;
int i; int i;
chr *s; chr *s;
chr *d; chr *d;
if (startp == NULL && endp == NULL) if (startp == NULL && endp == NULL) {
return; return;
len = endp - startp; }
assert(len > 0); len = endp - startp;
assert(cv->nchrs + len < cv->chrspace - cv->nmccechrs); assert(len > 0);
assert(cv->nmcces < cv->mccespace); assert(cv->nchrs + len < cv->chrspace - cv->nmccechrs);
d = &cv->chrs[cv->chrspace - cv->nmccechrs - len - 1]; assert(cv->nmcces < cv->mccespace);
cv->mcces[cv->nmcces++] = d; d = &cv->chrs[cv->chrspace - cv->nmccechrs - len - 1];
for (s = startp, i = len; i > 0; s++, i--) cv->mcces[cv->nmcces++] = d;
*d++ = *s; for (s = startp, i = len; i > 0; s++, i--) {
*d++ = 0; /* endmarker */ *d++ = *s;
assert(d == &cv->chrs[cv->chrspace - cv->nmccechrs]); }
cv->nmccechrs += len + 1; *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 */ static int /* predicate */
haschr(struct cvec * cv, /* character vector */ haschr(cv, c)
chr c) /* character to test for */ struct cvec *cv; /* character vector */
pchr c; /* character to test for */
{ {
int i; int i;
chr *p; chr *p;
for (p = cv->chrs, i = cv->nchrs; i > 0; p++, i--) for (p = cv->chrs, i = cv->nchrs; i > 0; p++, i--) {
{ if (*p == c) {
if (*p == c) return 1;
return 1;
} }
for (p = cv->ranges, i = cv->nranges; i > 0; p += 2, i--) }
{ for (p = cv->ranges, i = cv->nranges; i > 0; p += 2, i--) {
if ((*p <= c) && (c <= *(p + 1))) if ((*p <= c) && (c <= *(p+1))) {
return 1; return 1;
} }
return 0; }
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 * static struct cvec *
getcvec(struct vars * v, /* context */ getcvec(v, nchrs, nranges, nmcces)
int nchrs, /* to hold this many chrs... */ struct vars *v; /* context */
int nranges, /* ... and this many ranges... */ int nchrs; /* to hold this many chrs... */
int nmcces) /* ... and this many MCCEs */ int nranges; /* ... and this many ranges... */
int nmcces; /* ... and this many MCCEs */
{ {
if (v->cv != NULL && nchrs <= v->cv->chrspace && 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); return clearcvec(v->cv);
}
if (v->cv != NULL) if (v->cv != NULL) {
freecvec(v->cv); freecvec(v->cv);
v->cv = newcvec(nchrs, nranges, nmcces); }
if (v->cv == NULL) v->cv = newcvec(nchrs, nranges, nmcces);
ERR(REG_ESPACE); if (v->cv == NULL) {
ERR(REG_ESPACE);
}
return v->cv; return v->cv;
} }
/* /*
* freecvec - free a cvec - freecvec - free a cvec
^ static VOID freecvec(struct cvec *);
*/ */
static void static VOID
freecvec(struct cvec * cv) freecvec(cv)
struct cvec *cv; /* character vector */
{ {
FREE(cv); FREE(cv);
} }

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

File diff suppressed because it is too large Load Diff

View File

@@ -1,22 +1,19 @@
#ifndef _REGEX_CUSTOM_H_
#define _REGEX_CUSTOM_H_
/* /*
* Copyright (c) 1998, 1999 Henry Spencer. All rights reserved. * Copyright (c) 1998, 1999 Henry Spencer. All rights reserved.
* *
* Development of this software was funded, in part, by Cray Research Inc., * Development of this software was funded, in part, by Cray Research Inc.,
* UUNET Communications Services Inc., Sun Microsystems Inc., and Scriptics * UUNET Communications Services Inc., Sun Microsystems Inc., and Scriptics
* Corporation, none of whom are responsible for the results. The author * Corporation, none of whom are responsible for the results. The author
* thanks all of them. * thanks all of them.
* *
* Redistribution and use in source and binary forms -- with or without * Redistribution and use in source and binary forms -- with or without
* modification -- are permitted for any purpose, provided that * modification -- are permitted for any purpose, provided that
* redistributions in source form retain this entire copyright notice and * redistributions in source form retain this entire copyright notice and
* indicate the origin and nature of any modifications. * indicate the origin and nature of any modifications.
* *
* I'd appreciate being given credit for this package in the documentation * I'd appreciate being given credit for this package in the documentation
* of software which uses it, but that is not a requirement. * of software which uses it, but that is not a requirement.
* *
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
@@ -27,72 +24,97 @@
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Id$
*/ */
/* headers if any */ /* headers if any */
#include "tclInt.h"
/* 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
/* overrides for regguts.h definitions, if any */ /* overrides for regguts.h definitions, if any */
#define FUNCPTR(name, args) (*name) args #define FUNCPTR(name, args) (*name) _ANSI_ARGS_(args)
#define MALLOC(n) malloc(n) #define MALLOC(n) ckalloc(n)
#define FREE(p) free(VS(p)) #define FREE(p) ckfree(VS(p))
#define REALLOC(p,n) realloc(VS(p),n) #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 */ /* internal character type and related */
typedef wx_wchar chr; /* the type itself */ typedef Tcl_UniChar chr; /* the type itself */
typedef unsigned long uchr; /* unsigned type that will hold a chr */ typedef int pchr; /* what it promotes to */
typedef long celt; /* type to hold chr, MCCE number, or typedef unsigned uchr; /* unsigned type that will hold a chr */
* NOCELT */ typedef int celt; /* type to hold chr, MCCE number, or NOCELT */
#define NOCELT (-1) /* celt value which is not valid chr or MCCE */
#define NOCELT (-1) /* celt value which is not valid chr or #define CHR(c) (UCHAR(c)) /* turn char literal into chr literal */
* MCCE */ #define DIGITVAL(c) ((c)-'0') /* turn chr digit into its value */
#define CHR(c) ((unsigned char) (c)) /* turn char literal into chr #if TCL_UTF_MAX > 3
* literal */ #define CHRBITS 32 /* bits in a chr; must not use sizeof */
#define DIGITVAL(c) ((c)-'0') /* turn chr digit into its value */ #define CHR_MIN 0x00000000 /* smallest and largest chr; the value */
#define CHR_MAX 0xffffffff /* CHR_MAX-CHR_MIN+1 should fit in uchr */
#if wxUSE_WCHAR_T #else
# define CHRBITS (SIZEOF_WCHAR_T << 3) /* bits in a chr; must not use sizeof */ #define CHRBITS 16 /* bits in a chr; must not use sizeof */
# define CHR_MAX ((1 << CHRBITS) - 1) #define CHR_MIN 0x0000 /* smallest and largest chr; the value */
# define CHR_MIN 0x00000000 /* smallest and largest chr; the value */ #define CHR_MAX 0xffff /* CHR_MAX-CHR_MIN+1 should fit in uchr */
#else /*ANSI*/ #endif
# define CHRBITS 8
# define CHR_MAX 0xFF
# define CHR_MIN 0x00
#endif /*wxUSE_WCHAR_T*/
/* functions operating on chr */ /* functions operating on chr */
#define iscalnum(x) wx_isalnum(x) #define iscalnum(x) Tcl_UniCharIsAlnum(x)
#define iscalpha(x) wx_isalpha(x) #define iscalpha(x) Tcl_UniCharIsAlpha(x)
#define iscdigit(x) wx_isdigit(x) #define iscdigit(x) Tcl_UniCharIsDigit(x)
#define iscspace(x) wx_isspace(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 */ /* and pick up the standard header */
#include "regex.h" #include "regex.h"
#endif /* _REGEX_CUSTOM_H_ */

View File

@@ -2,21 +2,21 @@
* DFA routines * DFA routines
* This file is #included by regexec.c. * This file is #included by regexec.c.
* *
* Copyright (c) 1998, 1999 Henry Spencer. All rights reserved. * Copyright (c) 1998, 1999 Henry Spencer. All rights reserved.
* *
* Development of this software was funded, in part, by Cray Research Inc., * Development of this software was funded, in part, by Cray Research Inc.,
* UUNET Communications Services Inc., Sun Microsystems Inc., and Scriptics * UUNET Communications Services Inc., Sun Microsystems Inc., and Scriptics
* Corporation, none of whom are responsible for the results. The author * Corporation, none of whom are responsible for the results. The author
* thanks all of them. * thanks all of them.
* *
* Redistribution and use in source and binary forms -- with or without * Redistribution and use in source and binary forms -- with or without
* modification -- are permitted for any purpose, provided that * modification -- are permitted for any purpose, provided that
* redistributions in source form retain this entire copyright notice and * redistributions in source form retain this entire copyright notice and
* indicate the origin and nature of any modifications. * indicate the origin and nature of any modifications.
* *
* I'd appreciate being given credit for this package in the documentation * I'd appreciate being given credit for this package in the documentation
* of software which uses it, but that is not a requirement. * of software which uses it, but that is not a requirement.
* *
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
@@ -28,27 +28,27 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * 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 */ static chr * /* endpoint, or NULL */
longest(struct vars * v, /* used only for debug and exec flags */ longest(v, d, start, stop, hitstopp)
struct dfa * d, struct vars *v; /* used only for debug and exec flags */
chr *start, /* where the match should start */ struct dfa *d;
chr *stop, /* match must end at or before here */ chr *start; /* where the match should start */
int *hitstopp) /* record whether hit v->stop, if non-NULL */ chr *stop; /* match must end at or before here */
int *hitstopp; /* record whether hit v->stop, if non-NULL */
{ {
chr *cp; chr *cp;
chr *realstop = (stop == v->stop) ? stop : stop + 1; chr *realstop = (stop == v->stop) ? stop : stop + 1;
color co; color co;
struct sset *css; struct sset *css;
struct sset *ss; struct sset *ss;
chr *post; chr *post;
int i; int i;
struct colormap *cm = d->cm; struct colormap *cm = d->cm;
/* initialize */ /* initialize */
@@ -59,15 +59,12 @@ longest(struct vars * v, /* used only for debug and exec flags */
/* startup */ /* startup */
FDEBUG(("+++ startup +++\n")); FDEBUG(("+++ startup +++\n"));
if (cp == v->start) if (cp == v->start) {
{ co = d->cnfa->bos[(v->eflags&REG_NOTBOL) ? 0 : 1];
co = d->cnfa->bos[(v->eflags & REG_NOTBOL) ? 0 : 1]; FDEBUG(("color %ld\n", (long)co));
FDEBUG(("color %ld\n", (long) co)); } else {
}
else
{
co = GETCOLOR(cm, *(cp - 1)); 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); css = miss(v, d, css, co, cp, start);
if (css == NULL) if (css == NULL)
@@ -75,33 +72,29 @@ longest(struct vars * v, /* used only for debug and exec flags */
css->lastseen = cp; css->lastseen = cp;
/* main loop */ /* main loop */
if (v->eflags & REG_FTRACE) if (v->eflags&REG_FTRACE)
while (cp < realstop) while (cp < realstop) {
{
FDEBUG(("+++ at c%d +++\n", css - d->ssets)); FDEBUG(("+++ at c%d +++\n", css - d->ssets));
co = GETCOLOR(cm, *cp); 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]; ss = css->outs[co];
if (ss == NULL) if (ss == NULL) {
{ ss = miss(v, d, css, co, cp+1, start);
ss = miss(v, d, css, co, cp + 1, start);
if (ss == NULL) if (ss == NULL)
break; /* NOTE BREAK OUT */ break; /* NOTE BREAK OUT */
} }
cp++; cp++;
ss->lastseen = cp; ss->lastseen = cp;
css = ss; css = ss;
} }
else else
while (cp < realstop) while (cp < realstop) {
{
co = GETCOLOR(cm, *cp); co = GETCOLOR(cm, *cp);
ss = css->outs[co]; ss = css->outs[co];
if (ss == NULL) if (ss == NULL) {
{ ss = miss(v, d, css, co, cp+1, start);
ss = miss(v, d, css, co, cp + 1, start);
if (ss == NULL) if (ss == NULL)
break; /* NOTE BREAK OUT */ break; /* NOTE BREAK OUT */
} }
cp++; cp++;
ss->lastseen = cp; ss->lastseen = cp;
@@ -110,15 +103,14 @@ longest(struct vars * v, /* used only for debug and exec flags */
/* shutdown */ /* shutdown */
FDEBUG(("+++ shutdown at c%d +++\n", css - d->ssets)); 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) if (hitstopp != NULL)
*hitstopp = 1; *hitstopp = 1;
co = d->cnfa->eos[(v->eflags & REG_NOTEOL) ? 0 : 1]; co = d->cnfa->eos[(v->eflags&REG_NOTEOL) ? 0 : 1];
FDEBUG(("color %ld\n", (long) co)); FDEBUG(("color %ld\n", (long)co));
ss = miss(v, d, css, co, cp, start); ss = miss(v, d, css, co, cp, start);
/* special case: match ended at eol? */ /* special case: match ended at eol? */
if (ss != NULL && (ss->flags & POSTSTATE)) if (ss != NULL && (ss->flags&POSTSTATE))
return cp; return cp;
else if (ss != NULL) else if (ss != NULL)
ss->lastseen = cp; /* to be tidy */ ss->lastseen = cp; /* to be tidy */
@@ -127,32 +119,34 @@ longest(struct vars * v, /* used only for debug and exec flags */
/* find last match, if any */ /* find last match, if any */
post = d->lastpost; post = d->lastpost;
for (ss = d->ssets, i = d->nssused; i > 0; ss++, i--) 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 == NULL || post < ss->lastseen))
post = ss->lastseen; post = ss->lastseen;
if (post != NULL) /* found one */ if (post != NULL) /* found one */
return post - 1; return post - 1;
return NULL; return NULL;
} }
/* /*
* 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 */ static chr * /* endpoint, or NULL */
shortest(struct vars * v, shortest(v, d, start, min, max, coldp, hitstopp)
struct dfa * d, struct vars *v;
chr *start, /* where the match should start */ struct dfa *d;
chr *min, /* match must end at or after here */ chr *start; /* where the match should start */
chr *max, /* match must end at or before here */ chr *min; /* match must end at or after here */
chr **coldp, /* store coldstart pointer here, if chr *max; /* match must end at or before here */
* nonNULL */ chr **coldp; /* store coldstart pointer here, if nonNULL */
int *hitstopp) /* record whether hit v->stop, if non-NULL */ int *hitstopp; /* record whether hit v->stop, if non-NULL */
{ {
chr *cp; chr *cp;
chr *realmin = (min == v->stop) ? min : min + 1; chr *realmin = (min == v->stop) ? min : min + 1;
chr *realmax = (max == v->stop) ? max : max + 1; chr *realmax = (max == v->stop) ? max : max + 1;
color co; color co;
struct sset *css; struct sset *css;
struct sset *ss; struct sset *ss;
struct colormap *cm = d->cm; struct colormap *cm = d->cm;
@@ -165,15 +159,12 @@ shortest(struct vars * v,
/* startup */ /* startup */
FDEBUG(("--- startup ---\n")); FDEBUG(("--- startup ---\n"));
if (cp == v->start) if (cp == v->start) {
{ co = d->cnfa->bos[(v->eflags&REG_NOTBOL) ? 0 : 1];
co = d->cnfa->bos[(v->eflags & REG_NOTBOL) ? 0 : 1]; FDEBUG(("color %ld\n", (long)co));
FDEBUG(("color %ld\n", (long) co)); } else {
}
else
{
co = GETCOLOR(cm, *(cp - 1)); 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); css = miss(v, d, css, co, cp, start);
if (css == NULL) if (css == NULL)
@@ -182,116 +173,110 @@ shortest(struct vars * v,
ss = css; ss = css;
/* main loop */ /* main loop */
if (v->eflags & REG_FTRACE) if (v->eflags&REG_FTRACE)
while (cp < realmax) while (cp < realmax) {
{
FDEBUG(("--- at c%d ---\n", css - d->ssets)); FDEBUG(("--- at c%d ---\n", css - d->ssets));
co = GETCOLOR(cm, *cp); 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]; ss = css->outs[co];
if (ss == NULL) if (ss == NULL) {
{ ss = miss(v, d, css, co, cp+1, start);
ss = miss(v, d, css, co, cp + 1, start);
if (ss == NULL) if (ss == NULL)
break; /* NOTE BREAK OUT */ break; /* NOTE BREAK OUT */
} }
cp++; cp++;
ss->lastseen = cp; ss->lastseen = cp;
css = ss; css = ss;
if ((ss->flags & POSTSTATE) && cp >= realmin) if ((ss->flags&POSTSTATE) && cp >= realmin)
break; /* NOTE BREAK OUT */ break; /* NOTE BREAK OUT */
} }
else else
while (cp < realmax) while (cp < realmax) {
{
co = GETCOLOR(cm, *cp); co = GETCOLOR(cm, *cp);
ss = css->outs[co]; ss = css->outs[co];
if (ss == NULL) if (ss == NULL) {
{ ss = miss(v, d, css, co, cp+1, start);
ss = miss(v, d, css, co, cp + 1, start);
if (ss == NULL) if (ss == NULL)
break; /* NOTE BREAK OUT */ break; /* NOTE BREAK OUT */
} }
cp++; cp++;
ss->lastseen = cp; ss->lastseen = cp;
css = ss; css = ss;
if ((ss->flags & POSTSTATE) && cp >= realmin) if ((ss->flags&POSTSTATE) && cp >= realmin)
break; /* NOTE BREAK OUT */ break; /* NOTE BREAK OUT */
} }
if (ss == NULL) if (ss == NULL)
return NULL; return NULL;
if (coldp != NULL) /* report last no-progress state set, if if (coldp != NULL) /* report last no-progress state set, if any */
* any */
*coldp = lastcold(v, d); *coldp = lastcold(v, d);
if ((ss->flags & POSTSTATE) && cp > min) if ((ss->flags&POSTSTATE) && cp > min) {
{
assert(cp >= realmin); assert(cp >= realmin);
cp--; cp--;
} } else if (cp == v->stop && max == v->stop) {
else if (cp == v->stop && max == v->stop) 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); ss = miss(v, d, css, co, cp, start);
/* match might have ended at eol */ /* match might have ended at eol */
if ((ss == NULL || !(ss->flags & POSTSTATE)) && hitstopp != NULL) if ((ss == NULL || !(ss->flags&POSTSTATE)) && hitstopp != NULL)
*hitstopp = 1; *hitstopp = 1;
} }
if (ss == NULL || !(ss->flags & POSTSTATE)) if (ss == NULL || !(ss->flags&POSTSTATE))
return NULL; return NULL;
return cp; 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 */ static chr * /* endpoint, or NULL */
lastcold(struct vars * v, lastcold(v, d)
struct dfa * d) struct vars *v;
struct dfa *d;
{ {
struct sset *ss; struct sset *ss;
chr *nopr; chr *nopr;
int i; int i;
nopr = d->lastnopr; nopr = d->lastnopr;
if (nopr == NULL) if (nopr == NULL)
nopr = v->start; nopr = v->start;
for (ss = d->ssets, i = d->nssused; i > 0; ss++, i--) 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; nopr = ss->lastseen;
return nopr; 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 * static struct dfa *
newdfa(struct vars * v, newdfa(v, cnfa, cm, small)
struct cnfa * cnfa, struct vars *v;
struct colormap * cm, struct cnfa *cnfa;
struct smalldfa * small) /* preallocated space, may be NULL */ struct colormap *cm;
struct smalldfa *small; /* preallocated space, may be NULL */
{ {
struct dfa *d; struct dfa *d;
size_t nss = cnfa->nstates * 2; size_t nss = cnfa->nstates * 2;
int wordsper = (cnfa->nstates + UBITS - 1) / UBITS; int wordsper = (cnfa->nstates + UBITS - 1) / UBITS;
struct smalldfa *smallwas = small; struct smalldfa *smallwas = small;
assert(cnfa != NULL && cnfa->nstates != 0); assert(cnfa != NULL && cnfa->nstates != 0);
if (nss <= FEWSTATES && cnfa->ncolors <= FEWCOLORS) if (nss <= FEWSTATES && cnfa->ncolors <= FEWCOLORS) {
{
assert(wordsper == 1); assert(wordsper == 1);
if (small == NULL) if (small == NULL) {
{ small = (struct smalldfa *)MALLOC(
small = (struct smalldfa *) MALLOC( sizeof(struct smalldfa));
sizeof(struct smalldfa)); if (small == NULL) {
if (small == NULL)
{
ERR(REG_ESPACE); ERR(REG_ESPACE);
return NULL; return NULL;
} }
@@ -303,36 +288,32 @@ newdfa(struct vars * v,
d->outsarea = small->outsarea; d->outsarea = small->outsarea;
d->incarea = small->incarea; d->incarea = small->incarea;
d->cptsmalloced = 0; d->cptsmalloced = 0;
d->mallocarea = (smallwas == NULL) ? (char *) small : NULL; d->mallocarea = (smallwas == NULL) ? (char *)small : NULL;
} } else {
else d = (struct dfa *)MALLOC(sizeof(struct dfa));
{ if (d == NULL) {
d = (struct dfa *) MALLOC(sizeof(struct dfa));
if (d == NULL)
{
ERR(REG_ESPACE); ERR(REG_ESPACE);
return NULL; return NULL;
} }
d->ssets = (struct sset *) MALLOC(nss * sizeof(struct sset)); d->ssets = (struct sset *)MALLOC(nss * sizeof(struct sset));
d->statesarea = (unsigned *) MALLOC((nss + WORK) * wordsper * d->statesarea = (unsigned *)MALLOC((nss+WORK) * wordsper *
sizeof(unsigned)); sizeof(unsigned));
d->work = &d->statesarea[nss * wordsper]; 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 *)); sizeof(struct sset *));
d->incarea = (struct arcp *) MALLOC(nss * cnfa->ncolors * d->incarea = (struct arcp *)MALLOC(nss * cnfa->ncolors *
sizeof(struct arcp)); sizeof(struct arcp));
d->cptsmalloced = 1; d->cptsmalloced = 1;
d->mallocarea = (char *) d; d->mallocarea = (char *)d;
if (d->ssets == NULL || d->statesarea == NULL || if (d->ssets == NULL || d->statesarea == NULL ||
d->outsarea == NULL || d->incarea == NULL) d->outsarea == NULL || d->incarea == NULL) {
{
freedfa(d); freedfa(d);
ERR(REG_ESPACE); ERR(REG_ESPACE);
return NULL; return NULL;
} }
} }
d->nssets = (v->eflags & REG_SMALL) ? 7 : nss; d->nssets = (v->eflags&REG_SMALL) ? 7 : nss;
d->nssused = 0; d->nssused = 0;
d->nstates = cnfa->nstates; d->nstates = cnfa->nstates;
d->ncolors = cnfa->ncolors; 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 static VOID
freedfa(struct dfa * d) freedfa(d)
struct dfa *d;
{ {
if (d->cptsmalloced) if (d->cptsmalloced) {
{
if (d->ssets != NULL) if (d->ssets != NULL)
FREE(d->ssets); FREE(d->ssets);
if (d->statesarea != NULL) if (d->statesarea != NULL)
@@ -371,16 +353,17 @@ 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. * There are probably better ways, but they're more expensive.
^ static unsigned hash(unsigned *, int);
*/ */
static unsigned static unsigned
hash(unsigned *uv, hash(uv, n)
int n) unsigned *uv;
int n;
{ {
int i; int i;
unsigned h; unsigned h;
h = 0; h = 0;
for (i = 0; i < n; i++) for (i = 0; i < n; i++)
@@ -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 * static struct sset *
initialize(struct vars * v, /* used only for debug flags */ initialize(v, d, start)
struct dfa * d, struct vars *v; /* used only for debug flags */
chr *start) struct dfa *d;
chr *start;
{ {
struct sset *ss; struct sset *ss;
int i; int i;
/* is previous one still there? */ /* 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]; ss = &d->ssets[0];
else else { /* no, must (re)build it */
{ /* no, must (re)build it */
ss = getvacant(v, d, start, start); ss = getvacant(v, d, start, start);
for (i = 0; i < d->wordsper; i++) for (i = 0; i < d->wordsper; i++)
ss->states[i] = 0; ss->states[i] = 0;
BSET(ss->states, d->cnfa->pre); BSET(ss->states, d->cnfa->pre);
ss->hash = HASH(ss->states, d->wordsper); ss->hash = HASH(ss->states, d->wordsper);
assert(d->cnfa->pre != d->cnfa->post); assert(d->cnfa->pre != d->cnfa->post);
ss->flags = STARTER | LOCKED | NOPROGRESS; ss->flags = STARTER|LOCKED|NOPROGRESS;
/* lastseen dealt with below */ /* lastseen dealt with below */
} }
@@ -423,30 +407,32 @@ 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 */ static struct sset * /* NULL if goes to empty set */
miss(struct vars * v, /* used only for debug flags */ miss(v, d, css, co, cp, start)
struct dfa * d, struct vars *v; /* used only for debug flags */
struct sset * css, struct dfa *d;
pcolor co, struct sset *css;
chr *cp, /* next chr */ pcolor co;
chr *start) /* where the attempt got started */ chr *cp; /* next chr */
chr *start; /* where the attempt got started */
{ {
struct cnfa *cnfa = d->cnfa; struct cnfa *cnfa = d->cnfa;
int i; int i;
unsigned h; unsigned h;
struct carc *ca; struct carc *ca;
struct sset *p; struct sset *p;
int ispost; int ispost;
int noprogress; int noprogress;
int gotstate; int gotstate;
int dolacons; int dolacons;
int sawlacons; int sawlacons;
/* for convenience, we can be called even if it might not be a miss */ /* 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")); FDEBUG(("hit\n"));
return css->outs[co]; return css->outs[co];
} }
@@ -460,9 +446,8 @@ miss(struct vars * v, /* used only for debug flags */
gotstate = 0; gotstate = 0;
for (i = 0; i < d->nstates; i++) for (i = 0; i < d->nstates; i++)
if (ISBSET(css->states, i)) if (ISBSET(css->states, i))
for (ca = cnfa->states[i] + 1; ca->co != COLORLESS; ca++) for (ca = cnfa->states[i]+1; ca->co != COLORLESS; ca++)
if (ca->co == co) if (ca->co == co) {
{
BSET(d->work, ca->to); BSET(d->work, ca->to);
gotstate = 1; gotstate = 1;
if (ca->to == cnfa->post) if (ca->to == cnfa->post)
@@ -471,23 +456,21 @@ miss(struct vars * v, /* used only for debug flags */
noprogress = 0; noprogress = 0;
FDEBUG(("%d -> %d\n", i, ca->to)); FDEBUG(("%d -> %d\n", i, ca->to));
} }
dolacons = (gotstate) ? (cnfa->flags & HASLACONS) : 0; dolacons = (gotstate) ? (cnfa->flags&HASLACONS) : 0;
sawlacons = 0; sawlacons = 0;
while (dolacons) while (dolacons) { /* transitive closure */
{ /* transitive closure */
dolacons = 0; dolacons = 0;
for (i = 0; i < d->nstates; i++) for (i = 0; i < d->nstates; i++)
if (ISBSET(d->work, i)) if (ISBSET(d->work, i))
for (ca = cnfa->states[i] + 1; ca->co != COLORLESS; for (ca = cnfa->states[i]+1; ca->co != COLORLESS;
ca++) ca++) {
{
if (ca->co <= cnfa->ncolors) if (ca->co <= cnfa->ncolors)
continue; /* NOTE CONTINUE */ continue; /* NOTE CONTINUE */
sawlacons = 1; sawlacons = 1;
if (ISBSET(d->work, ca->to)) if (ISBSET(d->work, ca->to))
continue; /* NOTE CONTINUE */ continue; /* NOTE CONTINUE */
if (!lacon(v, cnfa, cp, ca->co)) if (!lacon(v, cnfa, cp, ca->co))
continue; /* NOTE CONTINUE */ continue; /* NOTE CONTINUE */
BSET(d->work, ca->to); BSET(d->work, ca->to);
dolacons = 1; dolacons = 1;
if (ca->to == cnfa->post) if (ca->to == cnfa->post)
@@ -503,13 +486,11 @@ miss(struct vars * v, /* used only for debug flags */
/* next, is that in the cache? */ /* next, is that in the cache? */
for (p = d->ssets, i = d->nssused; i > 0; p++, i--) 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)); FDEBUG(("cached c%d\n", p - d->ssets));
break; /* NOTE BREAK OUT */ break; /* NOTE BREAK OUT */
} }
if (i == 0) if (i == 0) { /* nope, need a new cache entry */
{ /* nope, need a new cache entry */
p = getvacant(v, d, cp, start); p = getvacant(v, d, cp, start);
assert(p != css); assert(p != css);
for (i = 0; i < d->wordsper; i++) for (i = 0; i < d->wordsper; i++)
@@ -521,97 +502,96 @@ miss(struct vars * v, /* used only for debug flags */
/* lastseen to be dealt with by caller */ /* lastseen to be dealt with by caller */
} }
if (!sawlacons) if (!sawlacons) { /* lookahead conds. always cache miss */
{ /* lookahead conds. always cache miss */
FDEBUG(("c%d[%d]->c%d\n", css - d->ssets, co, p - d->ssets)); FDEBUG(("c%d[%d]->c%d\n", css - d->ssets, co, p - d->ssets));
css->outs[co] = p; css->outs[co] = p;
css->inchain[co] = p->ins; css->inchain[co] = p->ins;
p->ins.ss = css; p->ins.ss = css;
p->ins.co = (color) co; p->ins.co = (color)co;
} }
return p; 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? */ static int /* predicate: constraint satisfied? */
lacon(struct vars * v, lacon(v, pcnfa, cp, co)
struct cnfa * pcnfa, /* parent cnfa */ struct vars *v;
chr *cp, struct cnfa *pcnfa; /* parent cnfa */
pcolor co) /* "color" of the lookahead constraint */ chr *cp;
pcolor co; /* "color" of the lookahead constraint */
{ {
int n; int n;
struct subre *sub; struct subre *sub;
struct dfa *d; struct dfa *d;
struct smalldfa sd; struct smalldfa sd;
chr *end; chr *end;
n = co - pcnfa->ncolors; n = co - pcnfa->ncolors;
assert(n < v->g->nlacons && v->g->lacons != NULL); assert(n < v->g->nlacons && v->g->lacons != NULL);
FDEBUG(("=== testing lacon %d\n", n)); FDEBUG(("=== testing lacon %d\n", n));
sub = &v->g->lacons[n]; sub = &v->g->lacons[n];
d = newdfa(v, &sub->cnfa, &v->g->cmap, &sd); d = newdfa(v, &sub->cnfa, &v->g->cmap, &sd);
if (d == NULL) if (d == NULL) {
{
ERR(REG_ESPACE); ERR(REG_ESPACE);
return 0; return 0;
} }
end = longest(v, d, cp, v->stop, (int *) NULL); end = longest(v, d, cp, v->stop, (int *)NULL);
freedfa(d); freedfa(d);
FDEBUG(("=== lacon %d match %d\n", n, (end != NULL))); FDEBUG(("=== lacon %d match %d\n", n, (end != NULL)));
return (sub->subno) ? (end != NULL) : (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 * 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. * 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 * static struct sset *
getvacant(struct vars * v, /* used only for debug flags */ getvacant(v, d, cp, start)
struct dfa * d, struct vars *v; /* used only for debug flags */
chr *cp, struct dfa *d;
chr *start) chr *cp;
chr *start;
{ {
int i; int i;
struct sset *ss; struct sset *ss;
struct sset *p; struct sset *p;
struct arcp ap; struct arcp ap;
struct arcp lastap; struct arcp lastap;
color co; color co;
ss = pickss(v, d, cp, start); ss = pickss(v, d, cp, start);
assert(!(ss->flags & LOCKED)); assert(!(ss->flags&LOCKED));
/* clear out its inarcs, including self-referential ones */ /* clear out its inarcs, including self-referential ones */
ap = ss->ins; ap = ss->ins;
while ((p = ap.ss) != NULL) while ((p = ap.ss) != NULL) {
{
co = ap.co; 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; p->outs[co] = NULL;
ap = p->inchain[co]; ap = p->inchain[co];
p->inchain[co].ss = NULL; /* paranoia */ p->inchain[co].ss = NULL; /* paranoia */
} }
ss->ins.ss = NULL; ss->ins.ss = NULL;
/* take it off the inarc chains of the ssets reached by its outarcs */ /* 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]; p = ss->outs[i];
assert(p != ss); /* not self-referential */ assert(p != ss); /* not self-referential */
if (p == NULL) if (p == NULL)
continue; /* NOTE CONTINUE */ continue; /* NOTE CONTINUE */
FDEBUG(("del outarc %d from c%d's in chn\n", i, p - d->ssets)); FDEBUG(("del outarc %d from c%d's in chn\n", i, p - d->ssets));
if (p->ins.ss == ss && p->ins.co == i) if (p->ins.ss == ss && p->ins.co == i)
p->ins = ss->inchain[i]; p->ins = ss->inchain[i];
else else {
{
assert(p->ins.ss != NULL); assert(p->ins.ss != NULL);
for (ap = p->ins; ap.ss != NULL && for (ap = p->ins; ap.ss != NULL &&
!(ap.ss == ss && ap.co == i); !(ap.ss == ss && ap.co == i);
ap = ap.ss->inchain[ap.co]) ap = ap.ss->inchain[ap.co])
lastap = ap; lastap = ap;
assert(ap.ss != NULL); assert(ap.ss != NULL);
lastap.ss->inchain[lastap.co] = ss->inchain[i]; lastap.ss->inchain[lastap.co] = ss->inchain[i];
@@ -621,35 +601,36 @@ getvacant(struct vars * v, /* used only for debug flags */
} }
/* if ss was a success state, may need to remember location */ /* 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 == NULL || d->lastpost < ss->lastseen))
d->lastpost = ss->lastseen; d->lastpost = ss->lastseen;
/* likewise for a no-progress state */ /* 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 == NULL || d->lastnopr < ss->lastseen))
d->lastnopr = ss->lastseen; d->lastnopr = ss->lastseen;
return ss; return ss;
} }
/* /*
* 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 * static struct sset *
pickss(struct vars * v, /* used only for debug flags */ pickss(v, d, cp, start)
struct dfa * d, struct vars *v; /* used only for debug flags */
chr *cp, struct dfa *d;
chr *start) chr *cp;
chr *start;
{ {
int i; int i;
struct sset *ss; struct sset *ss;
struct sset *end; struct sset *end;
chr *ancient; chr *ancient;
/* shortcut for cases where cache isn't full */ /* shortcut for cases where cache isn't full */
if (d->nssused < d->nssets) if (d->nssused < d->nssets) {
{
i = d->nssused; i = d->nssused;
d->nssused++; d->nssused++;
ss = &d->ssets[i]; 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->ins.co = WHITE; /* give it some value */
ss->outs = &d->outsarea[i * d->ncolors]; ss->outs = &d->outsarea[i * d->ncolors];
ss->inchain = &d->incarea[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->outs[i] = NULL;
ss->inchain[i].ss = 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 */ /* look for oldest, or old enough anyway */
if (cp - start > d->nssets * 2 / 3) /* oldest 33% are expendable */ if (cp - start > d->nssets*2/3) /* oldest 33% are expendable */
ancient = cp - d->nssets * 2 / 3; ancient = cp - d->nssets*2/3;
else else
ancient = start; ancient = start;
for (ss = d->search, end = &d->ssets[d->nssets]; ss < end; ss++) for (ss = d->search, end = &d->ssets[d->nssets]; ss < end; ss++)
if ((ss->lastseen == NULL || ss->lastseen < ancient) && if ((ss->lastseen == NULL || ss->lastseen < ancient) &&
!(ss->flags & LOCKED)) !(ss->flags&LOCKED)) {
{
d->search = ss + 1; d->search = ss + 1;
FDEBUG(("replacing c%d\n", ss - d->ssets)); FDEBUG(("replacing c%d\n", ss - d->ssets));
return ss; return ss;
} }
for (ss = d->ssets, end = d->search; ss < end; ss++) for (ss = d->ssets, end = d->search; ss < end; ss++)
if ((ss->lastseen == NULL || ss->lastseen < ancient) && if ((ss->lastseen == NULL || ss->lastseen < ancient) &&
!(ss->flags & LOCKED)) !(ss->flags&LOCKED)) {
{
d->search = ss + 1; d->search = ss + 1;
FDEBUG(("replacing c%d\n", ss - d->ssets)); FDEBUG(("replacing c%d\n", ss - d->ssets));
return ss; return ss;

View File

@@ -1,21 +1,21 @@
/* /*
* regerror - error-code expansion * regerror - error-code expansion
* *
* Copyright (c) 1998, 1999 Henry Spencer. All rights reserved. * Copyright (c) 1998, 1999 Henry Spencer. All rights reserved.
* *
* Development of this software was funded, in part, by Cray Research Inc., * Development of this software was funded, in part, by Cray Research Inc.,
* UUNET Communications Services Inc., Sun Microsystems Inc., and Scriptics * UUNET Communications Services Inc., Sun Microsystems Inc., and Scriptics
* Corporation, none of whom are responsible for the results. The author * Corporation, none of whom are responsible for the results. The author
* thanks all of them. * thanks all of them.
* *
* Redistribution and use in source and binary forms -- with or without * Redistribution and use in source and binary forms -- with or without
* modification -- are permitted for any purpose, provided that * modification -- are permitted for any purpose, provided that
* redistributions in source form retain this entire copyright notice and * redistributions in source form retain this entire copyright notice and
* indicate the origin and nature of any modifications. * indicate the origin and nature of any modifications.
* *
* I'd appreciate being given credit for this package in the documentation * I'd appreciate being given credit for this package in the documentation
* of software which uses it, but that is not a requirement. * of software which uses it, but that is not a requirement.
* *
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
@@ -27,8 +27,6 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * 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" #include "regguts.h"
@@ -37,88 +35,73 @@
static char unk[] = "*** unknown regex error code 0x%x ***"; static char unk[] = "*** unknown regex error code 0x%x ***";
/* struct to map among codes, code names, and explanations */ /* struct to map among codes, code names, and explanations */
static struct rerr static struct rerr {
{
int code; int code;
char *name; char *name;
char *explain; char *explain;
} rerrs[] = } rerrs[] = {
{
/* the actual table is built from regex.h */ /* the actual table is built from regex.h */
#include "regerrs.h" # include "regerrs.h"
{ { -1, "", "oops" }, /* explanation special-cased in code */
-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 */ /* ARGSUSED */
size_t /* actual space needed (including NUL) */ size_t /* actual space needed (including NUL) */
wx_regerror(int errcode, /* error code, or REG_ATOI or REG_ITOA */ regerror(errcode, preg, errbuf, errbuf_size)
const regex_t *preg, /* associated regex_t (unused at present) */ int errcode; /* error code, or REG_ATOI or REG_ITOA */
char *errbuf, /* result buffer (unless errbuf_size==0) */ CONST regex_t *preg; /* associated regex_t (unused at present) */
size_t errbuf_size) /* available space in errbuf, can be 0 */ char *errbuf; /* result buffer (unless errbuf_size==0) */
size_t errbuf_size; /* available space in errbuf, can be 0 */
{ {
struct rerr *r; struct rerr *r;
char *msg; char *msg;
char convbuf[sizeof(unk) + 50]; /* 50 = plenty for int */ char convbuf[sizeof(unk)+50]; /* 50 = plenty for int */
size_t len; size_t len;
int icode; int icode;
switch (errcode) switch (errcode) {
{ case REG_ATOI: /* convert name to number */
case REG_ATOI: /* convert name to number */
for (r = rerrs; r->code >= 0; r++) for (r = rerrs; r->code >= 0; r++)
if (strcmp(r->name, errbuf) == 0) if (strcmp(r->name, errbuf) == 0)
break; break;
sprintf(convbuf, "%d", r->code); /* -1 for unknown */ sprintf(convbuf, "%d", r->code); /* -1 for unknown */
msg = convbuf;
break;
case REG_ITOA: /* convert number to name */
icode = atoi(errbuf); /* not our problem if this fails */
for (r = rerrs; r->code >= 0; r++)
if (r->code == icode)
break;
if (r->code >= 0)
msg = r->name;
else { /* unknown; tell him the number */
sprintf(convbuf, "REG_%u", (unsigned)icode);
msg = convbuf; msg = convbuf;
break; }
case REG_ITOA: /* convert number to name */ break;
icode = atoi(errbuf); /* not our problem if this fails */ default: /* a real, normal error code */
for (r = rerrs; r->code >= 0; r++) for (r = rerrs; r->code >= 0; r++)
if (r->code == icode) if (r->code == errcode)
break; break;
if (r->code >= 0) if (r->code >= 0)
msg = r->name; msg = r->explain;
else else { /* unknown; say so */
{ /* unknown; tell him the number */ sprintf(convbuf, unk, errcode);
sprintf(convbuf, "REG_%u", (unsigned) icode); msg = convbuf;
msg = convbuf; }
} break;
break;
default: /* a real, normal error code */
for (r = rerrs; r->code >= 0; r++)
if (r->code == errcode)
break;
if (r->code >= 0)
msg = r->explain;
else
{ /* unknown; say so */
sprintf(convbuf, unk, errcode);
msg = convbuf;
}
break;
} }
len = strlen(msg) + 1; /* space needed, including NUL */ len = strlen(msg) + 1; /* space needed, including NUL */
if (errbuf_size > 0) if (errbuf_size > 0) {
{
if (errbuf_size > len) if (errbuf_size > len)
strcpy(errbuf, msg); strcpy(errbuf, msg);
else else { /* truncate to fit */
{ /* truncate to fit */ strncpy(errbuf, msg, errbuf_size-1);
memcpy(errbuf, msg, errbuf_size - 1); /*RN - was strncpy*/ errbuf[errbuf_size-1] = '\0';
errbuf[errbuf_size - 1] = '\0';
} }
} }

View File

@@ -1,75 +1,18 @@
/* { REG_OKAY, "REG_OKAY", "no errors detected" },
* $Id$ { 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_OKAY, "REG_OKAY", "no errors detected" { 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_NOMATCH, "REG_NOMATCH", "failed to match" { 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_BADPAT, "REG_BADPAT", "invalid regexp (reg version 0.8)" { 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_ECOLLATE, "REG_ECOLLATE", "invalid collating element" { REG_BADOPT, "REG_BADOPT", "invalid embedded option" },
},
{
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,16 +1,15 @@
#ifndef _REGEX_H_ #ifndef _REGEX_H_
#define _REGEX_H_ /* never again */ #define _REGEX_H_ /* never again */
/* /*
* regular expressions * regular expressions
* *
* Copyright (c) 1998, 1999 Henry Spencer. All rights reserved. * Copyright (c) 1998, 1999 Henry Spencer. All rights reserved.
* *
* Development of this software was funded, in part, by Cray Research Inc., * Development of this software was funded, in part, by Cray Research Inc.,
* UUNET Communications Services Inc., Sun Microsystems Inc., and Scriptics * UUNET Communications Services Inc., Sun Microsystems Inc., and Scriptics
* Corporation, none of whom are responsible for the results. The author * Corporation, none of whom are responsible for the results. The author
* thanks all of them. * thanks all of them.
* *
* Redistribution and use in source and binary forms -- with or without * Redistribution and use in source and binary forms -- with or without
* modification -- are permitted for any purpose, provided that * modification -- are permitted for any purpose, provided that
* redistributions in source form retain this entire copyright notice and * redistributions in source form retain this entire copyright notice and
@@ -18,7 +17,7 @@
* *
* I'd appreciate being given credit for this package in the documentation * I'd appreciate being given credit for this package in the documentation
* of software which uses it, but that is not a requirement. * of software which uses it, but that is not a requirement.
* *
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
@@ -30,35 +29,98 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * 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 #ifdef __cplusplus
extern "C" { extern "C" {
#endif #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. * interface types etc.
@@ -66,136 +128,214 @@ extern "C" {
/* /*
* regoff_t has to be large enough to hold either off_t or ssize_t, * 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; 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 * other interface types
*/ */
/* the biggie, a compiled RE (or rather, a front end to same) */ /* the biggie, a compiled RE (or rather, a front end to same) */
typedef struct typedef struct {
{ int re_magic; /* magic number */
int re_magic; /* magic number */ size_t re_nsub; /* number of subexpressions */
size_t re_nsub; /* number of subexpressions */ long re_info; /* information about RE */
long re_info; /* information about RE */ # define REG_UBACKREF 000001
#define REG_UBACKREF 000001 # define REG_ULOOKAHEAD 000002
#define REG_ULOOKAHEAD 000002 # define REG_UBOUNDS 000004
#define REG_UBOUNDS 000004 # define REG_UBRACES 000010
#define REG_UBRACES 000010 # define REG_UBSALNUM 000020
#define REG_UBSALNUM 000020 # define REG_UPBOTCH 000040
#define REG_UPBOTCH 000040 # define REG_UBBS 000100
#define REG_UBBS 000100 # define REG_UNONPOSIX 000200
#define REG_UNONPOSIX 000200 # define REG_UUNSPEC 000400
#define REG_UUNSPEC 000400 # define REG_UUNPORT 001000
#define REG_UUNPORT 001000 # define REG_ULOCALE 002000
#define REG_ULOCALE 002000 # define REG_UEMPTYMATCH 004000
#define REG_UEMPTYMATCH 004000 # define REG_UIMPOSSIBLE 010000
#define REG_UIMPOSSIBLE 010000 # define REG_USHORTEST 020000
#define REG_USHORTEST 020000 int re_csize; /* sizeof(character) */
int re_csize; /* sizeof(character) */ char *re_endp; /* backward compatibility kludge */
char *re_endp; /* backward compatibility kludge */
/* the rest is opaque pointers to hidden innards */ /* the rest is opaque pointers to hidden innards */
char *re_guts; /* `char *' is more portable than `void *' */ char *re_guts; /* `char *' is more portable than `void *' */
char *re_fns; char *re_fns;
} regex_t; } regex_t;
/* result reporting (may acquire more fields later) */ /* result reporting (may acquire more fields later) */
typedef struct typedef struct {
{ regoff_t rm_so; /* start of substring */
regoff_t rm_so; /* start of substring */ regoff_t rm_eo; /* end of substring */
regoff_t rm_eo; /* end of substring */
} regmatch_t; } regmatch_t;
/* supplementary control and reporting */ /* supplementary control and reporting */
typedef struct typedef struct {
{ regmatch_t rm_extend; /* see REG_EXPECT */
regmatch_t rm_extend; /* see REG_EXPECT */
} rm_detail_t; } 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_BASIC 000000 /* BREs (convenience) */
#define REG_EXTENDED 000001 /* EREs */ #define REG_EXTENDED 000001 /* EREs */
#define REG_ADVF 000002 /* advanced features in EREs */ #define REG_ADVF 000002 /* advanced features in EREs */
#define REG_ADVANCED 000003 /* AREs (which are also EREs) */ #define REG_ADVANCED 000003 /* AREs (which are also EREs) */
#define REG_QUOTE 000004 /* no special characters, none */ #define REG_QUOTE 000004 /* no special characters, none */
#define REG_NOSPEC REG_QUOTE /* historical synonym */ #define REG_NOSPEC REG_QUOTE /* historical synonym */
#define REG_ICASE 000010 /* ignore case */ #define REG_ICASE 000010 /* ignore case */
#define REG_NOSUB 000020 /* don't care about subexpressions */ #define REG_NOSUB 000020 /* don't care about subexpressions */
#define REG_EXPANDED 000040 /* expanded format, white space & comments */ #define REG_EXPANDED 000040 /* expanded format, white space & comments */
#define REG_NLSTOP 000100 /* \n doesn't match . or [^ ] */ #define REG_NLSTOP 000100 /* \n doesn't match . or [^ ] */
#define REG_NLANCH 000200 /* ^ matches after \n, $ before */ #define REG_NLANCH 000200 /* ^ matches after \n, $ before */
#define REG_NEWLINE 000300 /* newlines are line terminators */ #define REG_NEWLINE 000300 /* newlines are line terminators */
#define REG_PEND 000400 /* ugh -- backward-compatibility hack */ #define REG_PEND 000400 /* ugh -- backward-compatibility hack */
#define REG_EXPECT 001000 /* report details on partial/limited #define REG_EXPECT 001000 /* report details on partial/limited matches */
* matches */ #define REG_BOSONLY 002000 /* temporary kludge for BOS-only matches */
#define REG_BOSONLY 002000 /* temporary kludge for BOS-only matches */ #define REG_DUMP 004000 /* none of your business :-) */
#define REG_DUMP 004000 /* none of your business :-) */ #define REG_FAKE 010000 /* none of your business :-) */
#define REG_FAKE 010000 /* none of your business :-) */ #define REG_PROGRESS 020000 /* none of your business :-) */
#define REG_PROGRESS 020000 /* none of your business :-) */
/* /*
* 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_NOTBOL 0001 /* BOS is not BOL */
#define REG_NOTEOL 0002 /* EOS is not EOL */ #define REG_NOTEOL 0002 /* EOS is not EOL */
#define REG_STARTEND 0004 /* backward compatibility kludge */ #define REG_STARTEND 0004 /* backward compatibility kludge */
#define REG_FTRACE 0010 /* none of your business */ #define REG_FTRACE 0010 /* none of your business */
#define REG_MTRACE 0020 /* none of your business */ #define REG_MTRACE 0020 /* none of your business */
#define REG_SMALL 0040 /* none of your business */ #define REG_SMALL 0040 /* none of your business */
/*
* misc generics (may be more functions here eventually)
^ re_void regfree(regex_t *);
*/
/* /*
* error reporting * error reporting
* Be careful if modifying the list of error codes -- the table used by * Be careful if modifying the list of error codes -- the table used by
* regerror() is generated automatically from this file! * 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_OKAY 0 /* no errors detected */
#define REG_NOMATCH 1 /* failed to match */ #define REG_NOMATCH 1 /* failed to match */
#define REG_BADPAT 2 /* invalid regexp */ #define REG_BADPAT 2 /* invalid regexp */
#define REG_ECOLLATE 3 /* invalid collating element */ #define REG_ECOLLATE 3 /* invalid collating element */
#define REG_ECTYPE 4 /* invalid character class */ #define REG_ECTYPE 4 /* invalid character class */
#define REG_EESCAPE 5 /* invalid escape \ sequence */ #define REG_EESCAPE 5 /* invalid escape \ sequence */
#define REG_ESUBREG 6 /* invalid backreference number */ #define REG_ESUBREG 6 /* invalid backreference number */
#define REG_EBRACK 7 /* brackets [] not balanced */ #define REG_EBRACK 7 /* brackets [] not balanced */
#define REG_EPAREN 8 /* parentheses () not balanced */ #define REG_EPAREN 8 /* parentheses () not balanced */
#define REG_EBRACE 9 /* braces {} not balanced */ #define REG_EBRACE 9 /* braces {} not balanced */
#define REG_BADBR 10 /* invalid repetition count(s) */ #define REG_BADBR 10 /* invalid repetition count(s) */
#define REG_ERANGE 11 /* invalid character range */ #define REG_ERANGE 11 /* invalid character range */
#define REG_ESPACE 12 /* out of memory */ #define REG_ESPACE 12 /* out of memory */
#define REG_BADRPT 13 /* quantifier operand invalid */ #define REG_BADRPT 13 /* quantifier operand invalid */
#define REG_ASSERT 15 /* "can't happen" -- you found a bug */ #define REG_ASSERT 15 /* "can't happen" -- you found a bug */
#define REG_INVARG 16 /* invalid argument to regex function */ #define REG_INVARG 16 /* invalid argument to regex function */
#define REG_MIXED 17 /* character widths of regex and string #define REG_MIXED 17 /* character widths of regex and string differ */
* differ */ #define REG_BADOPT 18 /* invalid embedded option */
#define REG_BADOPT 18 /* invalid embedded option */
/* two specials for debugging and testing */ /* two specials for debugging and testing */
#define REG_ATOI 101 /* convert error-code name to number */ #define REG_ATOI 101 /* convert error-code name to number */
#define REG_ITOA 102 /* convert error-code number to name */ #define REG_ITOA 102 /* convert error-code number to name */
/* /*
* the prototypes for exported functions * the prototypes, as possibly munched by regfwd
*/ */
extern int wx_regcomp(regex_t *, const wx_wchar *, size_t, int); /* =====^!^===== begin forwards =====^!^===== */
extern int regcomp(regex_t *, const wx_wchar *, int); /* automatically gathered by fwd; do not hand-edit */
extern int wx_regexec(regex_t *, const wx_wchar *, size_t, rm_detail_t *, size_t, regmatch_t[], int); /* === regproto.h === */
extern int regexec(regex_t *, const wx_wchar *, size_t, regmatch_t[], int); #ifndef __REG_NOCHAR
extern void regfree(regex_t *); int re_comp _ANSI_ARGS_((regex_t *, __REG_CONST char *, size_t, int));
extern size_t regerror(int, const regex_t *, char *, size_t); #endif
extern void wx_regfree(regex_t *); #ifndef __REG_NOFRONT
extern size_t wx_regerror(int, const regex_t *, char *, size_t); 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 #ifdef __cplusplus
} }
#endif #endif
#endif /* _REGEX_H_ */
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -1,21 +1,21 @@
/* /*
* regfree - free an RE * regfree - free an RE
* *
* Copyright (c) 1998, 1999 Henry Spencer. All rights reserved. * Copyright (c) 1998, 1999 Henry Spencer. All rights reserved.
* *
* Development of this software was funded, in part, by Cray Research Inc., * Development of this software was funded, in part, by Cray Research Inc.,
* UUNET Communications Services Inc., Sun Microsystems Inc., and Scriptics * UUNET Communications Services Inc., Sun Microsystems Inc., and Scriptics
* Corporation, none of whom are responsible for the results. The author * Corporation, none of whom are responsible for the results. The author
* thanks all of them. * thanks all of them.
* *
* Redistribution and use in source and binary forms -- with or without * Redistribution and use in source and binary forms -- with or without
* modification -- are permitted for any purpose, provided that * modification -- are permitted for any purpose, provided that
* redistributions in source form retain this entire copyright notice and * redistributions in source form retain this entire copyright notice and
* indicate the origin and nature of any modifications. * indicate the origin and nature of any modifications.
* *
* I'd appreciate being given credit for this package in the documentation * I'd appreciate being given credit for this package in the documentation
* of software which uses it, but that is not a requirement. * of software which uses it, but that is not a requirement.
* *
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
@@ -27,7 +27,6 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * 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 * You might think that this could be incorporated into regcomp.c, and
@@ -39,19 +38,16 @@
#include "regguts.h" #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. * Ignoring invocation with NULL is a convenience.
*/ */
void VOID
regfree(regex_t *re) regfree(re)
{ wx_regfree(re); } regex_t *re;
void
wx_regfree(regex_t *re)
{ {
if (re == NULL) if (re == NULL)
return; return;
(*((struct fns *) re->re_fns)->free) (re); (*((struct fns *)re->re_fns)->free)(re);
} }

View File

@@ -1,21 +1,21 @@
/* /*
* Internal interface definitions, etc., for the reg package * Internal interface definitions, etc., for the reg package
* *
* Copyright (c) 1998, 1999 Henry Spencer. All rights reserved. * Copyright (c) 1998, 1999 Henry Spencer. All rights reserved.
* *
* Development of this software was funded, in part, by Cray Research Inc., * Development of this software was funded, in part, by Cray Research Inc.,
* UUNET Communications Services Inc., Sun Microsystems Inc., and Scriptics * UUNET Communications Services Inc., Sun Microsystems Inc., and Scriptics
* Corporation, none of whom are responsible for the results. The author * Corporation, none of whom are responsible for the results. The author
* thanks all of them. * thanks all of them.
* *
* Redistribution and use in source and binary forms -- with or without * Redistribution and use in source and binary forms -- with or without
* modification -- are permitted for any purpose, provided that * modification -- are permitted for any purpose, provided that
* redistributions in source form retain this entire copyright notice and * redistributions in source form retain this entire copyright notice and
* indicate the origin and nature of any modifications. * indicate the origin and nature of any modifications.
* *
* I'd appreciate being given credit for this package in the documentation * I'd appreciate being given credit for this package in the documentation
* of software which uses it, but that is not a requirement. * of software which uses it, but that is not a requirement.
* *
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
@@ -26,8 +26,6 @@
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Id$
*/ */
@@ -45,43 +43,63 @@
* Things that regcustom.h might override. * 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 */ /* assertions */
#ifndef __WXWINCE__
#ifndef assert #ifndef assert
#ifndef REG_DEBUG # ifndef REG_DEBUG
# ifndef NDEBUG # define NDEBUG /* no assertions */
# define NDEBUG /* no assertions */
# endif # endif
#endif
#include <assert.h> #include <assert.h>
#endif #endif
#else
// To do: assertion on WinCE
#define assert(x)
#endif
/* voids */ /* voids */
#ifndef VOID
#define VOID void /* for function return values */
#endif
#ifndef DISCARD #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 #endif
#ifndef VS #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 #endif
/* function-pointer declarator */ /* function-pointer declarator */
#ifndef FUNCPTR #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 #endif
/* memory allocation */ /* memory allocation */
#ifndef MALLOC #ifndef MALLOC
#define MALLOC(n) malloc(n) #define MALLOC(n) malloc(n)
#endif #endif
#ifndef REALLOC #ifndef REALLOC
#define REALLOC(p, n) realloc(VS(p), n) #define REALLOC(p, n) realloc(VS(p), n)
#endif #endif
#ifndef FREE #ifndef FREE
#define FREE(p) free(VS(p)) #define FREE(p) free(VS(p))
#endif #endif
/* want size of a char in bits, and max value in bounded quantifiers */ /* want size of a char in bits, and max value in bounded quantifiers */
@@ -89,7 +107,7 @@
#include <limits.h> #include <limits.h>
#endif #endif
#ifndef _POSIX2_RE_DUP_MAX #ifndef _POSIX2_RE_DUP_MAX
#define _POSIX2_RE_DUP_MAX 255 /* normally from <limits.h> */ #define _POSIX2_RE_DUP_MAX 255 /* normally from <limits.h> */
#endif #endif
@@ -98,13 +116,13 @@
* misc * misc
*/ */
#define NOTREACHED 0 #define NOTREACHED 0
#define xxx 1 #define xxx 1
#define DUPMAX _POSIX2_RE_DUP_MAX #define DUPMAX _POSIX2_RE_DUP_MAX
#define INFINITY (DUPMAX+1) #define INFINITY (DUPMAX+1)
#define REMAGIC 0xfed7 /* magic number for main struct */ #define REMAGIC 0xfed7 /* magic number for main struct */
@@ -113,12 +131,12 @@
*/ */
#ifdef REG_DEBUG #ifdef REG_DEBUG
/* FDEBUG does finite-state tracing */ /* FDEBUG does finite-state tracing */
#define FDEBUG(arglist) { if (v->eflags&REG_FTRACE) printf arglist; } #define FDEBUG(arglist) { if (v->eflags&REG_FTRACE) printf arglist; }
/* MDEBUG does higher-level tracing */ /* MDEBUG does higher-level tracing */
#define MDEBUG(arglist) { if (v->eflags&REG_MTRACE) printf arglist; } #define MDEBUG(arglist) { if (v->eflags&REG_MTRACE) printf arglist; }
#else #else
#define FDEBUG(arglist) {} #define FDEBUG(arglist) {}
#define MDEBUG(arglist) {} #define MDEBUG(arglist) {}
#endif #endif
@@ -126,25 +144,24 @@
/* /*
* bitmap manipulation * bitmap manipulation
*/ */
#define UBITS (CHAR_BIT * sizeof(unsigned)) #define UBITS (CHAR_BIT * sizeof(unsigned))
#define BSET(uv, sn) ((uv)[(sn)/UBITS] |= (unsigned)1 << ((sn)%UBITS)) #define BSET(uv, sn) ((uv)[(sn)/UBITS] |= (unsigned)1 << ((sn)%UBITS))
#define ISBSET(uv, sn) ((uv)[(sn)/UBITS] & ((unsigned)1 << ((sn)%UBITS))) #define ISBSET(uv, sn) ((uv)[(sn)/UBITS] & ((unsigned)1 << ((sn)%UBITS)))
/* /*
* We dissect a chr into byts for colormap table indexing. Here we define * We dissect a chr into byts for colormap table indexing. Here we define
* a byt, which will be the same as a byte on most machines... The exact * a byt, which will be the same as a byte on most machines... The exact
* size of a byt is not critical, but about 8 bits is good, and extraction * size of a byt is not critical, but about 8 bits is good, and extraction
* of 8-bit chunks is sometimes especially fast. * of 8-bit chunks is sometimes especially fast.
*/ */
#ifndef BYTBITS #ifndef BYTBITS
#define BYTBITS 8 /* bits in a byt */ #define BYTBITS 8 /* bits in a byt */
#endif #endif
#define BYTTAB (1<<BYTBITS) /* size of table with one entry per byt #define BYTTAB (1<<BYTBITS) /* size of table with one entry per byt value */
* value */ #define BYTMASK (BYTTAB-1) /* bit mask for byt */
#define BYTMASK (BYTTAB-1) /* bit mask for byt */ #define NBYTS ((CHRBITS+BYTBITS-1)/BYTBITS)
#define NBYTS ((CHRBITS+BYTBITS-1)/BYTBITS)
/* the definition of GETCOLOR(), below, assumes NBYTS <= 4 */ /* the definition of GETCOLOR(), below, assumes NBYTS <= 4 */
@@ -153,86 +170,79 @@
* As soon as possible, we map chrs into equivalence classes -- "colors" -- * As soon as possible, we map chrs into equivalence classes -- "colors" --
* which are of much more manageable number. * which are of much more manageable number.
*/ */
typedef short color; /* colors of characters */ typedef short color; /* colors of characters */
typedef int pcolor; /* what color promotes to */ typedef int pcolor; /* what color promotes to */
#define COLORLESS (-1) /* impossible color */
#define COLORLESS (-1) /* impossible color */ #define WHITE 0 /* default color, parent of all others */
#define WHITE 0 /* default color, parent of all others */
/* /*
* A colormap is a tree -- more precisely, a DAG -- indexed at each level * A colormap is a tree -- more precisely, a DAG -- indexed at each level
* by a byt of the chr, to map the chr to a color efficiently. Because * by a byt of the chr, to map the chr to a color efficiently. Because
* lower sections of the tree can be shared, it can exploit the usual * lower sections of the tree can be shared, it can exploit the usual
* sparseness of such a mapping table. The tree is always NBYTS levels * sparseness of such a mapping table. The tree is always NBYTS levels
* deep (in the past it was shallower during construction but was "filled" * deep (in the past it was shallower during construction but was "filled"
* to full depth at the end of that); areas that are unaltered as yet point * to full depth at the end of that); areas that are unaltered as yet point
* to "fill blocks" which are entirely WHITE in color. * to "fill blocks" which are entirely WHITE in color.
*/ */
/* the tree itself */ /* the tree itself */
struct colors struct colors {
{ color ccolor[BYTTAB];
color ccolor[BYTTAB];
}; };
struct ptrs struct ptrs {
{
union tree *pptr[BYTTAB]; union tree *pptr[BYTTAB];
}; };
union tree union tree {
{
struct colors colors; struct colors colors;
struct ptrs ptrs; struct ptrs ptrs;
}; };
#define tcolor colors.ccolor
#define tcolor colors.ccolor #define tptr ptrs.pptr
#define tptr ptrs.pptr
/* internal per-color structure for the color machinery */ /* internal per-color structure for the color machinery */
struct colordesc struct colordesc {
{ uchr nchrs; /* number of chars of this color */
uchr nchrs; /* number of chars of this color */ color sub; /* open subcolor (if any); free chain ptr */
color sub; /* open subcolor (if any); free chain ptr */ # define NOSUB COLORLESS
#define NOSUB COLORLESS struct arc *arcs; /* color chain */
struct arc *arcs; /* color chain */ int flags;
int flags; # define FREECOL 01 /* currently free */
#define FREECOL 01 /* currently free */ # define PSEUDO 02 /* pseudocolor, no real chars */
#define PSEUDO 02 /* pseudocolor, no real chars */ # define UNUSEDCOLOR(cd) ((cd)->flags&FREECOL)
#define UNUSEDCOLOR(cd) ((cd)->flags&FREECOL) union tree *block; /* block of solid color, if any */
union tree *block; /* block of solid color, if any */
}; };
/* the color map itself */ /* the color map itself */
struct colormap struct colormap {
{ int magic;
int magic; # define CMMAGIC 0x876
#define CMMAGIC 0x876 struct vars *v; /* for compile error reporting */
struct vars *v; /* for compile error reporting */ size_t ncds; /* number of colordescs */
size_t ncds; /* number of colordescs */ size_t max; /* highest in use */
size_t max; /* highest in use */ color free; /* beginning of free chain (if non-0) */
color free; /* beginning of free chain (if non-0) */
struct colordesc *cd; struct colordesc *cd;
#define CDEND(cm) (&(cm)->cd[(cm)->max + 1]) # define CDEND(cm) (&(cm)->cd[(cm)->max + 1])
#define NINLINECDS ((size_t)10) # define NINLINECDS ((size_t)10)
struct colordesc cdspace[NINLINECDS]; struct colordesc cdspace[NINLINECDS];
union tree tree[NBYTS]; /* tree top, plus fill blocks */ union tree tree[NBYTS]; /* tree top, plus fill blocks */
}; };
/* optimization magic to do fast chr->color mapping */ /* optimization magic to do fast chr->color mapping */
#define B0(c) ((c) & BYTMASK) #define B0(c) ((c) & BYTMASK)
#define B1(c) (((c)>>BYTBITS) & BYTMASK) #define B1(c) (((c)>>BYTBITS) & BYTMASK)
#define B2(c) (((c)>>(2*BYTBITS)) & BYTMASK) #define B2(c) (((c)>>(2*BYTBITS)) & BYTMASK)
#define B3(c) (((c)>>(3*BYTBITS)) & BYTMASK) #define B3(c) (((c)>>(3*BYTBITS)) & BYTMASK)
#if NBYTS == 1 #if NBYTS == 1
#define GETCOLOR(cm, c) ((cm)->tree->tcolor[B0(c)]) #define GETCOLOR(cm, c) ((cm)->tree->tcolor[B0(c)])
#endif #endif
/* beware, for NBYTS>1, GETCOLOR() is unsafe -- 2nd arg used repeatedly */ /* beware, for NBYTS>1, GETCOLOR() is unsafe -- 2nd arg used repeatedly */
#if NBYTS == 2 #if NBYTS == 2
#define GETCOLOR(cm, c) ((cm)->tree->tptr[B1(c)]->tcolor[B0(c)]) #define GETCOLOR(cm, c) ((cm)->tree->tptr[B1(c)]->tcolor[B0(c)])
#endif #endif
#if NBYTS == 4 #if NBYTS == 4
#define GETCOLOR(cm, c) ((cm)->tree->tptr[B3(c)]->tptr[B2(c)]->tptr[B1(c)]->tcolor[B0(c)]) #define GETCOLOR(cm, c) ((cm)->tree->tptr[B3(c)]->tptr[B2(c)]->tptr[B1(c)]->tcolor[B0(c)])
#endif #endif
@@ -241,23 +251,22 @@ struct colormap
* Interface definitions for locale-interface functions in locale.c. * Interface definitions for locale-interface functions in locale.c.
* Multi-character collating elements (MCCEs) cause most of the trouble. * Multi-character collating elements (MCCEs) cause most of the trouble.
*/ */
struct cvec struct cvec {
{ int nchrs; /* number of chrs */
int nchrs; /* number of chrs */ int chrspace; /* number of chrs possible */
int chrspace; /* number of chrs possible */ chr *chrs; /* pointer to vector of chrs */
chr *chrs; /* pointer to vector of chrs */ int nranges; /* number of ranges (chr pairs) */
int nranges; /* number of ranges (chr pairs) */ int rangespace; /* number of chrs possible */
int rangespace; /* number of chrs possible */ chr *ranges; /* pointer to vector of chr pairs */
chr *ranges; /* pointer to vector of chr pairs */ int nmcces; /* number of MCCEs */
int nmcces; /* number of MCCEs */ int mccespace; /* number of MCCEs possible */
int mccespace; /* number of MCCEs possible */ int nmccechrs; /* number of chrs used for MCCEs */
int nmccechrs; /* number of chrs used for MCCEs */ chr *mcces[1]; /* pointers to 0-terminated MCCEs */
chr *mcces[1]; /* pointers to 0-terminated MCCEs */ /* and both batches of chrs are on the end */
/* and both batches of chrs are on the end */
}; };
/* caution: this value cannot be changed easily */ /* caution: this value cannot be changed easily */
#define MAXMCCE 2 /* length of longest MCCE */ #define MAXMCCE 2 /* length of longest MCCE */
@@ -269,59 +278,54 @@ struct cvec
*/ */
struct state; struct state;
struct arc struct arc {
{ int type;
int type; # define ARCFREE '\0'
#define ARCFREE '\0' color co;
color co; struct state *from; /* where it's from (and contained within) */
struct state *from; /* where it's from (and contained within) */ struct state *to; /* where it's to */
struct state *to; /* where it's to */ struct arc *outchain; /* *from's outs chain or free chain */
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 *inchain; /* *to's ins chain */ struct arc *colorchain; /* color's arc chain */
struct arc *colorchain; /* color's arc chain */
}; };
struct arcbatch struct arcbatch { /* for bulk allocation of arcs */
{ /* for bulk allocation of arcs */
struct arcbatch *next; struct arcbatch *next;
#define ABSIZE 10 # define ABSIZE 10
struct arc a[ABSIZE]; struct arc a[ABSIZE];
}; };
struct state struct state {
{ int no;
int no; # define FREESTATE (-1)
#define FREESTATE (-1) char flag; /* marks special states */
char flag; /* marks special states */ int nins; /* number of inarcs */
int nins; /* number of inarcs */ struct arc *ins; /* chain of inarcs */
struct arc *ins; /* chain of inarcs */ int nouts; /* number of outarcs */
int nouts; /* number of outarcs */ struct arc *outs; /* chain of outarcs */
struct arc *outs; /* chain of outarcs */ struct arc *free; /* chain of free arcs */
struct arc *free; /* chain of free arcs */ struct state *tmp; /* temporary for traversal algorithms */
struct state *tmp; /* temporary for traversal algorithms */ struct state *next; /* chain for traversing all */
struct state *next; /* chain for traversing all */ struct state *prev; /* back chain */
struct state *prev; /* back chain */ struct arcbatch oas; /* first arcbatch, avoid malloc in easy case */
struct arcbatch oas; /* first arcbatch, avoid malloc in easy int noas; /* number of arcs used in first arcbatch */
* case */
int noas; /* number of arcs used in first arcbatch */
}; };
struct nfa struct nfa {
{ struct state *pre; /* pre-initial state */
struct state *pre; /* pre-initial state */ struct state *init; /* initial state */
struct state *init; /* initial state */ struct state *final; /* final state */
struct state *final; /* final state */ struct state *post; /* post-final state */
struct state *post; /* post-final state */ int nstates; /* for numbering states */
int nstates; /* for numbering states */ struct state *states; /* state-chain header */
struct state *states; /* state-chain header */ struct state *slast; /* tail of the chain */
struct state *slast; /* tail of the chain */ struct state *free; /* free list */
struct state *free; /* free list */ struct colormap *cm; /* the color map */
struct colormap *cm; /* the color map */ color bos[2]; /* colors, if any, assigned to BOS and BOL */
color bos[2]; /* colors, if any, assigned to BOS and BOL */ color eos[2]; /* colors, if any, assigned to EOS and EOL */
color eos[2]; /* colors, if any, assigned to EOS and EOL */ struct vars *v; /* simplifies compile error reporting */
struct vars *v; /* simplifies compile error reporting */ struct nfa *parent; /* parent NFA, if any */
struct nfa *parent; /* parent NFA, if any */
}; };
@@ -329,64 +333,58 @@ struct nfa
/* /*
* definitions for compacted NFA * definitions for compacted NFA
*/ */
struct carc struct carc {
{ color co; /* COLORLESS is list terminator */
color co; /* COLORLESS is list terminator */ int to; /* state number */
int to; /* state number */
}; };
struct cnfa struct cnfa {
{ int nstates; /* number of states */
int nstates; /* number of states */ int ncolors; /* number of colors */
int ncolors; /* number of colors */ int flags;
int flags; # define HASLACONS 01 /* uses lookahead constraints */
#define HASLACONS 01 /* uses lookahead constraints */ int pre; /* setup state number */
int pre; /* setup state number */ int post; /* teardown state number */
int post; /* teardown state number */ color bos[2]; /* colors, if any, assigned to BOS and BOL */
color bos[2]; /* colors, if any, assigned to BOS and BOL */ color eos[2]; /* colors, if any, assigned to EOS and EOL */
color eos[2]; /* colors, if any, assigned to EOS and EOL */ struct carc **states; /* vector of pointers to outarc lists */
struct carc **states; /* vector of pointers to outarc lists */ struct carc *arcs; /* the area for the lists */
struct carc *arcs; /* the area for the lists */
}; };
#define ZAPCNFA(cnfa) ((cnfa).nstates = 0)
#define ZAPCNFA(cnfa) ((cnfa).nstates = 0) #define NULLCNFA(cnfa) ((cnfa).nstates == 0)
#define NULLCNFA(cnfa) ((cnfa).nstates == 0)
/* /*
* subexpression tree * subexpression tree
*/ */
struct subre struct subre {
{ char op; /* '|', '.' (concat), 'b' (backref), '(', '=' */
char op; /* '|', '.' (concat), 'b' (backref), '(', char flags;
* '=' */ # define LONGER 01 /* prefers longer match */
char flags; # define SHORTER 02 /* prefers shorter match */
#define LONGER 01 /* prefers longer match */ # define MIXED 04 /* mixed preference below */
#define SHORTER 02 /* prefers shorter match */ # define CAP 010 /* capturing parens below */
#define MIXED 04 /* mixed preference below */ # define BACKR 020 /* back reference below */
#define CAP 010 /* capturing parens below */ # define INUSE 0100 /* in use in final tree */
#define BACKR 020 /* back reference below */ # define LOCAL 03 /* bits which may not propagate up */
#define INUSE 0100 /* in use in final tree */ # define LMIX(f) ((f)<<2) /* LONGER -> MIXED */
#define LOCAL 03 /* bits which may not propagate up */ # define SMIX(f) ((f)<<1) /* SHORTER -> MIXED */
#define LMIX(f) ((f)<<2) /* LONGER -> MIXED */ # define UP(f) (((f)&~LOCAL) | (LMIX(f) & SMIX(f) & MIXED))
#define SMIX(f) ((f)<<1) /* SHORTER -> MIXED */ # define MESSY(f) ((f)&(MIXED|CAP|BACKR))
#define UP(f) (((f)&~LOCAL) | (LMIX(f) & SMIX(f) & MIXED)) # define PREF(f) ((f)&LOCAL)
#define MESSY(f) ((f)&(MIXED|CAP|BACKR)) # define PREF2(f1, f2) ((PREF(f1) != 0) ? PREF(f1) : PREF(f2))
#define PREF(f) ((f)&LOCAL) # define COMBINE(f1, f2) (UP((f1)|(f2)) | PREF2(f1, f2))
#define PREF2(f1, f2) ((PREF(f1) != 0) ? PREF(f1) : PREF(f2)) short retry; /* index into retry memory */
#define COMBINE(f1, f2) (UP((f1)|(f2)) | PREF2(f1, f2)) int subno; /* subexpression number (for 'b' and '(') */
short retry; /* index into retry memory */ short min; /* min repetitions, for backref only */
int subno; /* subexpression number (for 'b' and '(') */ short max; /* max repetitions, for backref only */
short min; /* min repetitions, for backref only */ struct subre *left; /* left child, if any (also freelist chain) */
short max; /* max repetitions, for backref only */ struct subre *right; /* right child, if any */
struct subre *left; /* left child, if any (also freelist struct state *begin; /* outarcs from here... */
* chain) */ struct state *end; /* ...ending in inarcs here */
struct subre *right; /* right child, if any */ struct cnfa cnfa; /* compacted NFA, if any */
struct state *begin; /* outarcs from here... */ struct subre *chain; /* for bookkeeping and error cleanup */
struct state *end; /* ...ending in inarcs here */
struct cnfa cnfa; /* compacted NFA, if any */
struct subre *chain; /* for bookkeeping and error cleanup */
}; };
@@ -395,9 +393,8 @@ struct subre
* table of function pointers for generic manipulation functions * table of function pointers for generic manipulation functions
* A regex_t's re_fns points to one of these. * A regex_t's re_fns points to one of these.
*/ */
struct fns struct fns {
{ VOID FUNCPTR(free, (regex_t *));
void FUNCPTR(free, (regex_t *));
}; };
@@ -405,18 +402,17 @@ struct fns
/* /*
* the insides of a regex_t, hidden behind a void * * the insides of a regex_t, hidden behind a void *
*/ */
struct guts struct guts {
{ int magic;
int magic; # define GUTSMAGIC 0xfed9
#define GUTSMAGIC 0xfed9 int cflags; /* copy of compile flags */
int cflags; /* copy of compile flags */ long info; /* copy of re_info */
long info; /* copy of re_info */ size_t nsub; /* copy of re_nsub */
size_t nsub; /* copy of re_nsub */
struct subre *tree; struct subre *tree;
struct cnfa search; /* for fast preliminary search */ struct cnfa search; /* for fast preliminary search */
int ntree; int ntree;
struct colormap cmap; 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 */ struct subre *lacons; /* lookahead-constraint vector */
int nlacons; /* size of lacons */ int nlacons; /* size of lacons */
}; };