reverted to TCL version of regex library

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

View File

@@ -28,7 +28,6 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * 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
@@ -43,11 +42,13 @@
/* /*
* 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;
@@ -70,24 +71,25 @@ initcm(struct vars * v,
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;
@@ -96,8 +98,7 @@ freecm(struct colormap * cm)
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,12 +140,14 @@ cmtreefree(struct colormap * cm,
} }
/* /*
* setcolor - set the color of a character in a colormap - setcolor - set the color of a character in a colormap
^ static color setcolor(struct colormap *, pchr, pcolor);
*/ */
static color /* previous color */ 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;
@@ -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,28 +195,32 @@ 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;
@@ -228,37 +229,29 @@ newcolor(struct colormap * cm)
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,51 +291,45 @@ 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;
@@ -354,10 +342,13 @@ pseudocolor(struct colormap * cm)
} }
/* /*
* subcolor - allocate a new subcolor (if necessary) to this chr - subcolor - allocate a new subcolor (if necessary) to this chr
^ static color subcolor(struct colormap *, pchr c);
*/ */
static color 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 */
@@ -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,14 +396,17 @@ newsub(struct colormap * cm,
} }
/* /*
* subrange - allocate new subcolors to this range of chrs, fill in arcs - subrange - allocate new subcolors to this range of chrs, fill in arcs
^ static VOID subrange(struct vars *, pchr, pchr, struct state *,
^ struct state *);
*/ */
static void 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;
@@ -420,8 +414,8 @@ subrange(struct vars * v,
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 */
@@ -437,13 +431,15 @@ subrange(struct vars * v,
} }
/* /*
* subblock - allocate new subcolors for one tree block of chrs, fill in arcs - subblock - allocate new subcolors for one tree block of chrs, fill in arcs
^ static VOID subblock(struct vars *, pchr, struct state *, struct state *);
*/ */
static void 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;
@@ -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,11 +522,13 @@ subblock(struct vars * v,
} }
/* /*
* okcolors - promote subcolors to full colors - okcolors - promote subcolors to full colors
^ static VOID okcolors(struct nfa *, struct colormap *);
*/ */
static void 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);
@@ -547,27 +537,20 @@ okcolors(struct nfa * nfa,
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,11 +591,13 @@ colorchain(struct colormap * cm,
} }
/* /*
* uncolorchain - delete this arc from the color chain of its color - uncolorchain - delete this arc from the color chain of its color
^ static VOID uncolorchain(struct colormap *, struct arc *);
*/ */
static void 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;
@@ -621,8 +605,7 @@ uncolorchain(struct colormap * cm,
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);
@@ -632,11 +615,13 @@ uncolorchain(struct colormap * cm,
} }
/* /*
* singleton - is this character in its own color? - singleton - is this character in its own color?
^ static int singleton(struct colormap *, pchr c);
*/ */
static int /* predicate */ 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 */
@@ -647,15 +632,18 @@ singleton(struct colormap * cm,
} }
/* /*
* rainbow - add arcs of all full colors (but one) between specified states - rainbow - add arcs of all full colors (but one) between specified states
^ static VOID rainbow(struct nfa *, struct colormap *, int, pcolor,
^ struct state *, struct state *);
*/ */
static void 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);
@@ -663,23 +651,24 @@ rainbow(struct nfa * nfa,
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);
@@ -687,20 +676,26 @@ colorcomplement(struct nfa * nfa,
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;
@@ -708,19 +703,18 @@ dumpcolors(struct colormap * cm,
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++)
@@ -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

@@ -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; len = endp - startp;
assert(len > 0); assert(len > 0);
assert(cv->nchrs + len < cv->chrspace - cv->nmccechrs); assert(cv->nchrs + len < cv->chrspace - cv->nmccechrs);
assert(cv->nmcces < cv->mccespace); assert(cv->nmcces < cv->mccespace);
d = &cv->chrs[cv->chrspace - cv->nmccechrs - len - 1]; d = &cv->chrs[cv->chrspace - cv->nmccechrs - len - 1];
cv->mcces[cv->nmcces++] = d; cv->mcces[cv->nmcces++] = d;
for (s = startp, i = len; i > 0; s++, i--) for (s = startp, i = len; i > 0; s++, i--) {
*d++ = *s; *d++ = *s;
}
*d++ = 0; /* endmarker */ *d++ = 0; /* endmarker */
assert(d == &cv->chrs[cv->chrspace - cv->nmccechrs]); assert(d == &cv->chrs[cv->chrspace - cv->nmccechrs]);
cv->nmccechrs += len + 1; 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); v->cv = newcvec(nchrs, nranges, nmcces);
if (v->cv == NULL) if (v->cv == NULL) {
ERR(REG_ESPACE); 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);
} }

View File

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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,3 @@
#ifndef _REGEX_CUSTOM_H_
#define _REGEX_CUSTOM_H_
/* /*
* Copyright (c) 1998, 1999 Henry Spencer. All rights reserved. * Copyright (c) 1998, 1999 Henry Spencer. All rights reserved.
* *
@@ -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 CHR(c) ((unsigned char) (c)) /* turn char literal into chr
* literal */
#define DIGITVAL(c) ((c)-'0') /* turn chr digit into its value */ #define DIGITVAL(c) ((c)-'0') /* turn chr digit into its value */
#if TCL_UTF_MAX > 3
#if wxUSE_WCHAR_T #define CHRBITS 32 /* bits in a chr; must not use sizeof */
# define CHRBITS (SIZEOF_WCHAR_T << 3) /* bits in a chr; must not use sizeof */ #define CHR_MIN 0x00000000 /* smallest and largest chr; the value */
# define CHR_MAX ((1 << CHRBITS) - 1) #define CHR_MAX 0xffffffff /* CHR_MAX-CHR_MIN+1 should fit in uchr */
# define CHR_MIN 0x00000000 /* smallest and largest chr; the value */ #else
#else /*ANSI*/ #define CHRBITS 16 /* bits in a chr; must not use sizeof */
# define CHRBITS 8 #define CHR_MIN 0x0000 /* smallest and largest chr; the value */
# define CHR_MAX 0xFF #define CHR_MAX 0xffff /* CHR_MAX-CHR_MIN+1 should fit in uchr */
# define CHR_MIN 0x00 #endif
#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

@@ -28,19 +28,19 @@
* 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;
@@ -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,16 +72,14 @@ 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 */
} }
@@ -93,13 +88,11 @@ longest(struct vars * v, /* used only for debug and exec flags */
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 */
} }
@@ -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,7 +119,7 @@ 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 */
@@ -137,17 +129,19 @@ longest(struct vars * v, /* used only for debug and exec flags */
} }
/* /*
* shortest - shortest-preferred matching engine - shortest - shortest-preferred matching engine
^ static chr *shortest(struct vars *, struct dfa *, chr *, chr *, chr *,
^ chr **, int *);
*/ */
static chr * /* endpoint, or NULL */ 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;
@@ -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,77 +173,71 @@ 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;
@@ -262,19 +247,22 @@ lastcold(struct vars * v,
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;
@@ -283,15 +271,12 @@ newdfa(struct vars * v,
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,13 +353,14 @@ freedfa(struct dfa * d)
} }
/* /*
* hash - construct a hash code for a bitvector - hash - construct a hash code for a bitvector
*
* There are probably better ways, but they're more expensive. * 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;
@@ -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,15 +407,18 @@ initialize(struct vars * v, /* used only for debug flags */
} }
/* /*
* miss - handle a cache miss - miss - handle a cache miss
^ static struct sset *miss(struct vars *, struct dfa *, struct sset *,
^ pcolor, chr *, chr *);
*/ */
static struct sset * /* NULL if goes to empty set */ 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;
@@ -445,8 +432,7 @@ miss(struct vars * v, /* used only for debug flags */
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,16 +456,14 @@ 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;
@@ -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,25 +502,26 @@ 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;
@@ -552,27 +534,28 @@ lacon(struct vars * v,
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;
@@ -582,14 +565,13 @@ getvacant(struct vars * v, /* used only for debug flags */
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 */
@@ -597,8 +579,7 @@ getvacant(struct vars * v, /* used only for debug flags */
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)
@@ -606,8 +587,7 @@ getvacant(struct vars * v, /* used only for debug flags */
FDEBUG(("del outarc %d from c%d's in chn\n", i, p - d->ssets)); 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);
@@ -621,12 +601,12 @@ getvacant(struct vars * v, /* used only for debug flags */
} }
/* if ss was a success state, may need to remember location */ /* if ss 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;
@@ -634,13 +614,15 @@ getvacant(struct vars * v, /* used only for debug flags */
} }
/* /*
* pickss - pick the next stateset to be used - pickss - pick the next stateset to be used
^ static struct sset *pickss(struct vars *, struct dfa *, chr *, chr *);
*/ */
static struct sset * 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;
@@ -648,8 +630,7 @@ pickss(struct vars * v, /* used only for debug flags */
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

@@ -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,45 +35,34 @@
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)
@@ -90,9 +77,8 @@ wx_regerror(int errcode, /* error code, or REG_ATOI or REG_ITOA */
break; break;
if (r->code >= 0) if (r->code >= 0)
msg = r->name; msg = r->name;
else else { /* unknown; tell him the number */
{ /* unknown; tell him the number */ sprintf(convbuf, "REG_%u", (unsigned)icode);
sprintf(convbuf, "REG_%u", (unsigned) icode);
msg = convbuf; msg = convbuf;
} }
break; break;
@@ -102,8 +88,7 @@ wx_regerror(int errcode, /* error code, or REG_ATOI or REG_ITOA */
break; break;
if (r->code >= 0) if (r->code >= 0)
msg = r->explain; msg = r->explain;
else else { /* unknown; say so */
{ /* unknown; say so */
sprintf(convbuf, unk, errcode); sprintf(convbuf, unk, errcode);
msg = convbuf; msg = convbuf;
} }
@@ -111,14 +96,12 @@ wx_regerror(int errcode, /* error code, or REG_ATOI or REG_ITOA */
} }
len = strlen(msg) + 1; /* space needed, including NUL */ 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,6 +1,5 @@
#ifndef _REGEX_H_ #ifndef _REGEX_H_
#define _REGEX_H_ /* never again */ #define _REGEX_H_ /* never again */
/* /*
* regular expressions * regular expressions
* *
@@ -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,34 +128,58 @@ 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 */
@@ -102,22 +188,29 @@ typedef struct
} 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 */
@@ -132,8 +225,7 @@ typedef struct
#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 :-) */
@@ -142,7 +234,18 @@ typedef struct
/* /*
* regex execution flags * execution
^ #ifndef __REG_NOCHAR
^ int re_exec(regex_t *, __REG_CONST char *, size_t,
^ rm_detail_t *, size_t, regmatch_t [], int);
^ #endif
^ #ifndef __REG_NOFRONT
^ int regexec(regex_t *, __REG_CONST char *, size_t, regmatch_t [], int);
^ #endif
^ #ifdef __REG_WIDE_T
^ int __REG_WIDE_EXEC(regex_t *, __REG_CONST __REG_WIDE_T *, size_t,
^ rm_detail_t *, size_t, regmatch_t [], int);
^ #endif
*/ */
#define REG_NOTBOL 0001 /* BOS is not BOL */ #define REG_NOTBOL 0001 /* BOS is not BOL */
#define REG_NOTEOL 0002 /* EOS is not EOL */ #define REG_NOTEOL 0002 /* EOS is not EOL */
@@ -152,10 +255,24 @@ typedef struct
#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 */
@@ -173,8 +290,7 @@ typedef struct
#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 */
@@ -183,19 +299,43 @@ typedef struct
/* /*
* the prototypes for exported functions * the prototypes, as possibly munched by regfwd
*/ */
extern int wx_regcomp(regex_t *, const wx_wchar *, size_t, int); /* =====^!^===== 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

@@ -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

@@ -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,32 +43,52 @@
* 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 */
@@ -141,8 +159,7 @@
#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 */
@@ -155,7 +172,6 @@
*/ */
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 */
@@ -172,49 +188,43 @@ typedef int pcolor; /* what color promotes to */
*/ */
/* 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 */
}; };
@@ -241,8 +251,7 @@ 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 */
@@ -269,30 +278,27 @@ 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 */
@@ -302,13 +308,11 @@ struct state
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 struct arcbatch oas; /* first arcbatch, avoid malloc in easy case */
* case */
int noas; /* number of arcs used in first arcbatch */ 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 */
@@ -329,18 +333,16 @@ 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 */
@@ -348,7 +350,6 @@ struct cnfa
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)
@@ -357,31 +358,28 @@ struct cnfa
/* /*
* subexpression tree * subexpression tree
*/ */
struct subre struct subre {
{ char op; /* '|', '.' (concat), 'b' (backref), '(', '=' */
char op; /* '|', '.' (concat), 'b' (backref), '(',
* '=' */
char flags; char flags;
#define LONGER 01 /* prefers longer match */ # define LONGER 01 /* prefers longer match */
#define SHORTER 02 /* prefers shorter match */ # define SHORTER 02 /* prefers shorter match */
#define MIXED 04 /* mixed preference below */ # define MIXED 04 /* mixed preference below */
#define CAP 010 /* capturing parens below */ # define CAP 010 /* capturing parens below */
#define BACKR 020 /* back reference below */ # define BACKR 020 /* back reference below */
#define INUSE 0100 /* in use in final tree */ # define INUSE 0100 /* in use in final tree */
#define LOCAL 03 /* bits which may not propagate up */ # define LOCAL 03 /* bits which may not propagate up */
#define LMIX(f) ((f)<<2) /* LONGER -> MIXED */ # define LMIX(f) ((f)<<2) /* LONGER -> MIXED */
#define SMIX(f) ((f)<<1) /* SHORTER -> MIXED */ # define SMIX(f) ((f)<<1) /* SHORTER -> MIXED */
#define UP(f) (((f)&~LOCAL) | (LMIX(f) & SMIX(f) & MIXED)) # define UP(f) (((f)&~LOCAL) | (LMIX(f) & SMIX(f) & MIXED))
#define MESSY(f) ((f)&(MIXED|CAP|BACKR)) # define MESSY(f) ((f)&(MIXED|CAP|BACKR))
#define PREF(f) ((f)&LOCAL) # define PREF(f) ((f)&LOCAL)
#define PREF2(f1, f2) ((PREF(f1) != 0) ? PREF(f1) : PREF(f2)) # define PREF2(f1, f2) ((PREF(f1) != 0) ? PREF(f1) : PREF(f2))
#define COMBINE(f1, f2) (UP((f1)|(f2)) | PREF2(f1, f2)) # define COMBINE(f1, f2) (UP((f1)|(f2)) | PREF2(f1, f2))
short retry; /* index into retry memory */ short retry; /* index into retry memory */
int subno; /* subexpression number (for 'b' and '(') */ int subno; /* subexpression number (for 'b' and '(') */
short min; /* min repetitions, for backref only */ short min; /* min repetitions, for backref only */
short max; /* max repetitions, for backref only */ short max; /* max repetitions, for backref only */
struct subre *left; /* left child, if any (also freelist struct subre *left; /* left child, if any (also freelist chain) */
* chain) */
struct subre *right; /* right child, if any */ struct subre *right; /* right child, if any */
struct state *begin; /* outarcs from here... */ struct state *begin; /* outarcs from here... */
struct state *end; /* ...ending in inarcs here */ struct state *end; /* ...ending in inarcs here */
@@ -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,10 +402,9 @@ 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 */
@@ -416,7 +412,7 @@ struct guts
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 */
}; };