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:
@@ -2,7 +2,7 @@
|
|||||||
* colorings of characters
|
* colorings of characters
|
||||||
* This file is #included by regcomp.c.
|
* This file is #included by regcomp.c.
|
||||||
*
|
*
|
||||||
* Copyright (c) 1998, 1999 Henry Spencer. All rights reserved.
|
* Copyright (c) 1998, 1999 Henry Spencer. All rights reserved.
|
||||||
*
|
*
|
||||||
* Development of this software was funded, in part, by Cray Research Inc.,
|
* Development of this software was funded, in part, by Cray Research Inc.,
|
||||||
* UUNET Communications Services Inc., Sun Microsystems Inc., and Scriptics
|
* UUNET Communications Services Inc., Sun Microsystems Inc., and Scriptics
|
||||||
@@ -28,7 +28,6 @@
|
|||||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $Header$
|
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* Note that there are some incestuous relationships between this code and
|
* Note that there are some incestuous relationships between this code and
|
||||||
@@ -37,20 +36,22 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define CISERR() VISERR(cm->v)
|
#define CISERR() VISERR(cm->v)
|
||||||
#define CERR(e) VERR(cm->v, (e))
|
#define CERR(e) VERR(cm->v, (e))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* initcm - set up new colormap
|
- initcm - set up new colormap
|
||||||
|
^ static VOID initcm(struct vars *, struct colormap *);
|
||||||
*/
|
*/
|
||||||
static void
|
static VOID
|
||||||
initcm(struct vars * v,
|
initcm(v, cm)
|
||||||
struct colormap * cm)
|
struct vars *v;
|
||||||
|
struct colormap *cm;
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int j;
|
int j;
|
||||||
union tree *t;
|
union tree *t;
|
||||||
union tree *nextt;
|
union tree *nextt;
|
||||||
struct colordesc *cd;
|
struct colordesc *cd;
|
||||||
@@ -63,41 +64,41 @@ initcm(struct vars * v,
|
|||||||
cm->max = 0;
|
cm->max = 0;
|
||||||
cm->free = 0;
|
cm->free = 0;
|
||||||
|
|
||||||
cd = cm->cd; /* cm->cd[WHITE] */
|
cd = cm->cd; /* cm->cd[WHITE] */
|
||||||
cd->sub = NOSUB;
|
cd->sub = NOSUB;
|
||||||
cd->arcs = NULL;
|
cd->arcs = NULL;
|
||||||
cd->flags = 0;
|
cd->flags = 0;
|
||||||
cd->nchrs = CHR_MAX - CHR_MIN + 1;
|
cd->nchrs = CHR_MAX - CHR_MIN + 1;
|
||||||
|
|
||||||
/* upper levels of tree */
|
/* upper levels of tree */
|
||||||
for (t = &cm->tree[0], j = NBYTS - 1; j > 0; t = nextt, j--)
|
for (t = &cm->tree[0], j = NBYTS-1; j > 0; t = nextt, j--) {
|
||||||
{
|
|
||||||
nextt = t + 1;
|
nextt = t + 1;
|
||||||
for (i = BYTTAB - 1; i >= 0; i--)
|
for (i = BYTTAB-1; i >= 0; i--)
|
||||||
t->tptr[i] = nextt;
|
t->tptr[i] = nextt;
|
||||||
}
|
}
|
||||||
/* bottom level is solid white */
|
/* bottom level is solid white */
|
||||||
t = &cm->tree[NBYTS - 1];
|
t = &cm->tree[NBYTS-1];
|
||||||
for (i = BYTTAB - 1; i >= 0; i--)
|
for (i = BYTTAB-1; i >= 0; i--)
|
||||||
t->tcolor[i] = WHITE;
|
t->tcolor[i] = WHITE;
|
||||||
cd->block = t;
|
cd->block = t;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* freecm - free dynamically-allocated things in a colormap
|
- freecm - free dynamically-allocated things in a colormap
|
||||||
|
^ static VOID freecm(struct colormap *);
|
||||||
*/
|
*/
|
||||||
static void
|
static VOID
|
||||||
freecm(struct colormap * cm)
|
freecm(cm)
|
||||||
|
struct colormap *cm;
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
union tree *cb;
|
union tree *cb;
|
||||||
|
|
||||||
cm->magic = 0;
|
cm->magic = 0;
|
||||||
if (NBYTS > 1)
|
if (NBYTS > 1)
|
||||||
cmtreefree(cm, cm->tree, 0);
|
cmtreefree(cm, cm->tree, 0);
|
||||||
for (i = 1; i <= cm->max; i++) /* skip WHITE */
|
for (i = 1; i <= cm->max; i++) /* skip WHITE */
|
||||||
if (!UNUSEDCOLOR(&cm->cd[i]))
|
if (!UNUSEDCOLOR(&cm->cd[i])) {
|
||||||
{
|
|
||||||
cb = cm->cd[i].block;
|
cb = cm->cd[i].block;
|
||||||
if (cb != NULL)
|
if (cb != NULL)
|
||||||
FREE(cb);
|
FREE(cb);
|
||||||
@@ -107,32 +108,29 @@ freecm(struct colormap * cm)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* cmtreefree - free a non-terminal part of a colormap tree
|
- cmtreefree - free a non-terminal part of a colormap tree
|
||||||
|
^ static VOID cmtreefree(struct colormap *, union tree *, int);
|
||||||
*/
|
*/
|
||||||
static void
|
static VOID
|
||||||
cmtreefree(struct colormap * cm,
|
cmtreefree(cm, tree, level)
|
||||||
union tree * tree,
|
struct colormap *cm;
|
||||||
int level) /* level number (top == 0) of this block */
|
union tree *tree;
|
||||||
|
int level; /* level number (top == 0) of this block */
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
union tree *t;
|
union tree *t;
|
||||||
union tree *fillt = &cm->tree[level + 1];
|
union tree *fillt = &cm->tree[level+1];
|
||||||
union tree *cb;
|
union tree *cb;
|
||||||
|
|
||||||
assert(level < NBYTS - 1); /* this level has pointers */
|
assert(level < NBYTS-1); /* this level has pointers */
|
||||||
for (i = BYTTAB - 1; i >= 0; i--)
|
for (i = BYTTAB-1; i >= 0; i--) {
|
||||||
{
|
|
||||||
t = tree->tptr[i];
|
t = tree->tptr[i];
|
||||||
assert(t != NULL);
|
assert(t != NULL);
|
||||||
if (t != fillt)
|
if (t != fillt) {
|
||||||
{
|
if (level < NBYTS-2) { /* more pointer blocks below */
|
||||||
if (level < NBYTS - 2)
|
cmtreefree(cm, t, level+1);
|
||||||
{ /* more pointer blocks below */
|
|
||||||
cmtreefree(cm, t, level + 1);
|
|
||||||
FREE(t);
|
FREE(t);
|
||||||
}
|
} else { /* color block below */
|
||||||
else
|
|
||||||
{ /* color block below */
|
|
||||||
cb = cm->cd[t->tcolor[0]].block;
|
cb = cm->cd[t->tcolor[0]].block;
|
||||||
if (t != cb) /* not a solid block */
|
if (t != cb) /* not a solid block */
|
||||||
FREE(t);
|
FREE(t);
|
||||||
@@ -142,24 +140,26 @@ cmtreefree(struct colormap * cm,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* setcolor - set the color of a character in a colormap
|
- setcolor - set the color of a character in a colormap
|
||||||
|
^ static color setcolor(struct colormap *, pchr, pcolor);
|
||||||
*/
|
*/
|
||||||
static color /* previous color */
|
static color /* previous color */
|
||||||
setcolor(struct colormap * cm,
|
setcolor(cm, c, co)
|
||||||
chr c,
|
struct colormap *cm;
|
||||||
pcolor co)
|
pchr c;
|
||||||
|
pcolor co;
|
||||||
{
|
{
|
||||||
uchr uc = c;
|
uchr uc = c;
|
||||||
int shift;
|
int shift;
|
||||||
int level;
|
int level;
|
||||||
int b;
|
int b;
|
||||||
int bottom;
|
int bottom;
|
||||||
union tree *t;
|
union tree *t;
|
||||||
union tree *newt;
|
union tree *newt;
|
||||||
union tree *fillt;
|
union tree *fillt;
|
||||||
union tree *lastt;
|
union tree *lastt;
|
||||||
union tree *cb;
|
union tree *cb;
|
||||||
color prev;
|
color prev;
|
||||||
|
|
||||||
assert(cm->magic == CMMAGIC);
|
assert(cm->magic == CMMAGIC);
|
||||||
if (CISERR() || co == COLORLESS)
|
if (CISERR() || co == COLORLESS)
|
||||||
@@ -167,30 +167,27 @@ setcolor(struct colormap * cm,
|
|||||||
|
|
||||||
t = cm->tree;
|
t = cm->tree;
|
||||||
for (level = 0, shift = BYTBITS * (NBYTS - 1); shift > 0;
|
for (level = 0, shift = BYTBITS * (NBYTS - 1); shift > 0;
|
||||||
level++, shift -= BYTBITS)
|
level++, shift -= BYTBITS) {
|
||||||
{
|
|
||||||
b = (uc >> shift) & BYTMASK;
|
b = (uc >> shift) & BYTMASK;
|
||||||
lastt = t;
|
lastt = t;
|
||||||
t = lastt->tptr[b];
|
t = lastt->tptr[b];
|
||||||
assert(t != NULL);
|
assert(t != NULL);
|
||||||
fillt = &cm->tree[level + 1];
|
fillt = &cm->tree[level+1];
|
||||||
bottom = (shift <= BYTBITS) ? 1 : 0;
|
bottom = (shift <= BYTBITS) ? 1 : 0;
|
||||||
cb = (bottom) ? cm->cd[t->tcolor[0]].block : fillt;
|
cb = (bottom) ? cm->cd[t->tcolor[0]].block : fillt;
|
||||||
if (t == fillt || t == cb)
|
if (t == fillt || t == cb) { /* must allocate a new block */
|
||||||
{ /* must allocate a new block */
|
newt = (union tree *)MALLOC((bottom) ?
|
||||||
newt = (union tree *) MALLOC((bottom) ?
|
sizeof(struct colors) : sizeof(struct ptrs));
|
||||||
sizeof(struct colors) : sizeof(struct ptrs));
|
if (newt == NULL) {
|
||||||
if (newt == NULL)
|
|
||||||
{
|
|
||||||
CERR(REG_ESPACE);
|
CERR(REG_ESPACE);
|
||||||
return COLORLESS;
|
return COLORLESS;
|
||||||
}
|
}
|
||||||
if (bottom)
|
if (bottom)
|
||||||
memcpy(VS(newt->tcolor), VS(t->tcolor),
|
memcpy(VS(newt->tcolor), VS(t->tcolor),
|
||||||
BYTTAB * sizeof(color));
|
BYTTAB*sizeof(color));
|
||||||
else
|
else
|
||||||
memcpy(VS(newt->tptr), VS(t->tptr),
|
memcpy(VS(newt->tptr), VS(t->tptr),
|
||||||
BYTTAB * sizeof(union tree *));
|
BYTTAB*sizeof(union tree *));
|
||||||
t = newt;
|
t = newt;
|
||||||
lastt->tptr[b] = t;
|
lastt->tptr[b] = t;
|
||||||
}
|
}
|
||||||
@@ -198,67 +195,63 @@ setcolor(struct colormap * cm,
|
|||||||
|
|
||||||
b = uc & BYTMASK;
|
b = uc & BYTMASK;
|
||||||
prev = t->tcolor[b];
|
prev = t->tcolor[b];
|
||||||
t->tcolor[b] = (color) co;
|
t->tcolor[b] = (color)co;
|
||||||
return prev;
|
return prev;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* maxcolor - report largest color number in use
|
- maxcolor - report largest color number in use
|
||||||
|
^ static color maxcolor(struct colormap *);
|
||||||
*/
|
*/
|
||||||
static color
|
static color
|
||||||
maxcolor(struct colormap * cm)
|
maxcolor(cm)
|
||||||
|
struct colormap *cm;
|
||||||
{
|
{
|
||||||
if (CISERR())
|
if (CISERR())
|
||||||
return COLORLESS;
|
return COLORLESS;
|
||||||
|
|
||||||
return (color) cm->max;
|
return (color)cm->max;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* newcolor - find a new color (must be subject of setcolor at once)
|
- newcolor - find a new color (must be subject of setcolor at once)
|
||||||
* Beware: may relocate the colordescs.
|
* Beware: may relocate the colordescs.
|
||||||
|
^ static color newcolor(struct colormap *);
|
||||||
*/
|
*/
|
||||||
static color /* COLORLESS for error */
|
static color /* COLORLESS for error */
|
||||||
newcolor(struct colormap * cm)
|
newcolor(cm)
|
||||||
|
struct colormap *cm;
|
||||||
{
|
{
|
||||||
struct colordesc *cd;
|
struct colordesc *cd;
|
||||||
struct colordesc *new;
|
struct colordesc *new;
|
||||||
size_t n;
|
size_t n;
|
||||||
|
|
||||||
if (CISERR())
|
if (CISERR())
|
||||||
return COLORLESS;
|
return COLORLESS;
|
||||||
|
|
||||||
if (cm->free != 0)
|
if (cm->free != 0) {
|
||||||
{
|
|
||||||
assert(cm->free > 0);
|
assert(cm->free > 0);
|
||||||
assert((size_t) cm->free < cm->ncds);
|
assert((size_t)cm->free < cm->ncds);
|
||||||
cd = &cm->cd[cm->free];
|
cd = &cm->cd[cm->free];
|
||||||
assert(UNUSEDCOLOR(cd));
|
assert(UNUSEDCOLOR(cd));
|
||||||
assert(cd->arcs == NULL);
|
assert(cd->arcs == NULL);
|
||||||
cm->free = cd->sub;
|
cm->free = cd->sub;
|
||||||
}
|
} else if (cm->max < cm->ncds - 1) {
|
||||||
else if (cm->max < cm->ncds - 1)
|
|
||||||
{
|
|
||||||
cm->max++;
|
cm->max++;
|
||||||
cd = &cm->cd[cm->max];
|
cd = &cm->cd[cm->max];
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
/* oops, must allocate more */
|
/* oops, must allocate more */
|
||||||
n = cm->ncds * 2;
|
n = cm->ncds * 2;
|
||||||
if (cm->cd == cm->cdspace)
|
if (cm->cd == cm->cdspace) {
|
||||||
{
|
new = (struct colordesc *)MALLOC(n *
|
||||||
new = (struct colordesc *) MALLOC(n *
|
sizeof(struct colordesc));
|
||||||
sizeof(struct colordesc));
|
|
||||||
if (new != NULL)
|
if (new != NULL)
|
||||||
memcpy(VS(new), VS(cm->cdspace), cm->ncds *
|
memcpy(VS(new), VS(cm->cdspace), cm->ncds *
|
||||||
sizeof(struct colordesc));
|
sizeof(struct colordesc));
|
||||||
}
|
} else
|
||||||
else
|
new = (struct colordesc *)REALLOC(cm->cd,
|
||||||
new = (struct colordesc *) REALLOC(cm->cd,
|
n * sizeof(struct colordesc));
|
||||||
n * sizeof(struct colordesc));
|
if (new == NULL) {
|
||||||
if (new == NULL)
|
|
||||||
{
|
|
||||||
CERR(REG_ESPACE);
|
CERR(REG_ESPACE);
|
||||||
return COLORLESS;
|
return COLORLESS;
|
||||||
}
|
}
|
||||||
@@ -275,19 +268,20 @@ newcolor(struct colormap * cm)
|
|||||||
cd->flags = 0;
|
cd->flags = 0;
|
||||||
cd->block = NULL;
|
cd->block = NULL;
|
||||||
|
|
||||||
return (color) (cd - cm->cd);
|
return (color)(cd - cm->cd);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* freecolor - free a color (must have no arcs or subcolor)
|
- freecolor - free a color (must have no arcs or subcolor)
|
||||||
|
^ static VOID freecolor(struct colormap *, pcolor);
|
||||||
*/
|
*/
|
||||||
static void
|
static VOID
|
||||||
freecolor(struct colormap * cm,
|
freecolor(cm, co)
|
||||||
pcolor co)
|
struct colormap *cm;
|
||||||
|
pcolor co;
|
||||||
{
|
{
|
||||||
struct colordesc *cd = &cm->cd[co];
|
struct colordesc *cd = &cm->cd[co];
|
||||||
color pco,
|
color pco, nco; /* for freelist scan */
|
||||||
nco; /* for freelist scan */
|
|
||||||
|
|
||||||
assert(co >= 0);
|
assert(co >= 0);
|
||||||
if (co == WHITE)
|
if (co == WHITE)
|
||||||
@@ -297,53 +291,47 @@ freecolor(struct colormap * cm,
|
|||||||
assert(cd->sub == NOSUB);
|
assert(cd->sub == NOSUB);
|
||||||
assert(cd->nchrs == 0);
|
assert(cd->nchrs == 0);
|
||||||
cd->flags = FREECOL;
|
cd->flags = FREECOL;
|
||||||
if (cd->block != NULL)
|
if (cd->block != NULL) {
|
||||||
{
|
|
||||||
FREE(cd->block);
|
FREE(cd->block);
|
||||||
cd->block = NULL; /* just paranoia */
|
cd->block = NULL; /* just paranoia */
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((size_t) co == cm->max)
|
if ((size_t)co == cm->max) {
|
||||||
{
|
|
||||||
while (cm->max > WHITE && UNUSEDCOLOR(&cm->cd[cm->max]))
|
while (cm->max > WHITE && UNUSEDCOLOR(&cm->cd[cm->max]))
|
||||||
cm->max--;
|
cm->max--;
|
||||||
assert(cm->free >= 0);
|
assert(cm->free >= 0);
|
||||||
while ((size_t) cm->free > cm->max)
|
while ((size_t)cm->free > cm->max)
|
||||||
cm->free = cm->cd[cm->free].sub;
|
cm->free = cm->cd[cm->free].sub;
|
||||||
if (cm->free > 0)
|
if (cm->free > 0) {
|
||||||
{
|
|
||||||
assert(cm->free < cm->max);
|
assert(cm->free < cm->max);
|
||||||
pco = cm->free;
|
pco = cm->free;
|
||||||
nco = cm->cd[pco].sub;
|
nco = cm->cd[pco].sub;
|
||||||
while (nco > 0)
|
while (nco > 0)
|
||||||
if ((size_t) nco > cm->max)
|
if ((size_t)nco > cm->max) {
|
||||||
{
|
|
||||||
/* take this one out of freelist */
|
/* take this one out of freelist */
|
||||||
nco = cm->cd[nco].sub;
|
nco = cm->cd[nco].sub;
|
||||||
cm->cd[pco].sub = nco;
|
cm->cd[pco].sub = nco;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
assert(nco < cm->max);
|
assert(nco < cm->max);
|
||||||
pco = nco;
|
pco = nco;
|
||||||
nco = cm->cd[pco].sub;
|
nco = cm->cd[pco].sub;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
cd->sub = cm->free;
|
cd->sub = cm->free;
|
||||||
cm->free = (color) (cd - cm->cd);
|
cm->free = (color)(cd - cm->cd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* pseudocolor - allocate a false color, to be managed by other means
|
- pseudocolor - allocate a false color, to be managed by other means
|
||||||
|
^ static color pseudocolor(struct colormap *);
|
||||||
*/
|
*/
|
||||||
static color
|
static color
|
||||||
pseudocolor(struct colormap * cm)
|
pseudocolor(cm)
|
||||||
|
struct colormap *cm;
|
||||||
{
|
{
|
||||||
color co;
|
color co;
|
||||||
|
|
||||||
co = newcolor(cm);
|
co = newcolor(cm);
|
||||||
if (CISERR())
|
if (CISERR())
|
||||||
@@ -354,13 +342,16 @@ pseudocolor(struct colormap * cm)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* subcolor - allocate a new subcolor (if necessary) to this chr
|
- subcolor - allocate a new subcolor (if necessary) to this chr
|
||||||
|
^ static color subcolor(struct colormap *, pchr c);
|
||||||
*/
|
*/
|
||||||
static color
|
static color
|
||||||
subcolor(struct colormap * cm, chr c)
|
subcolor(cm, c)
|
||||||
|
struct colormap *cm;
|
||||||
|
pchr c;
|
||||||
{
|
{
|
||||||
color co; /* current color of c */
|
color co; /* current color of c */
|
||||||
color sco; /* new subcolor */
|
color sco; /* new subcolor */
|
||||||
|
|
||||||
co = GETCOLOR(cm, c);
|
co = GETCOLOR(cm, c);
|
||||||
sco = newsub(cm, co);
|
sco = newsub(cm, co);
|
||||||
@@ -368,8 +359,8 @@ subcolor(struct colormap * cm, chr c)
|
|||||||
return COLORLESS;
|
return COLORLESS;
|
||||||
assert(sco != COLORLESS);
|
assert(sco != COLORLESS);
|
||||||
|
|
||||||
if (co == sco) /* already in an open subcolor */
|
if (co == sco) /* already in an open subcolor */
|
||||||
return co; /* rest is redundant */
|
return co; /* rest is redundant */
|
||||||
cm->cd[co].nchrs--;
|
cm->cd[co].nchrs--;
|
||||||
cm->cd[sco].nchrs++;
|
cm->cd[sco].nchrs++;
|
||||||
setcolor(cm, c, sco);
|
setcolor(cm, c, sco);
|
||||||
@@ -377,22 +368,22 @@ subcolor(struct colormap * cm, chr c)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* newsub - allocate a new subcolor (if necessary) for a color
|
- newsub - allocate a new subcolor (if necessary) for a color
|
||||||
|
^ static color newsub(struct colormap *, pcolor);
|
||||||
*/
|
*/
|
||||||
static color
|
static color
|
||||||
newsub(struct colormap * cm,
|
newsub(cm, co)
|
||||||
pcolor co)
|
struct colormap *cm;
|
||||||
|
pcolor co;
|
||||||
{
|
{
|
||||||
color sco; /* new subcolor */
|
color sco; /* new subcolor */
|
||||||
|
|
||||||
sco = cm->cd[co].sub;
|
sco = cm->cd[co].sub;
|
||||||
if (sco == NOSUB)
|
if (sco == NOSUB) { /* color has no open subcolor */
|
||||||
{ /* color has no open subcolor */
|
if (cm->cd[co].nchrs == 1) /* optimization */
|
||||||
if (cm->cd[co].nchrs == 1) /* optimization */
|
|
||||||
return co;
|
return co;
|
||||||
sco = newcolor(cm); /* must create subcolor */
|
sco = newcolor(cm); /* must create subcolor */
|
||||||
if (sco == COLORLESS)
|
if (sco == COLORLESS) {
|
||||||
{
|
|
||||||
assert(CISERR());
|
assert(CISERR());
|
||||||
return COLORLESS;
|
return COLORLESS;
|
||||||
}
|
}
|
||||||
@@ -405,26 +396,29 @@ newsub(struct colormap * cm,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* subrange - allocate new subcolors to this range of chrs, fill in arcs
|
- subrange - allocate new subcolors to this range of chrs, fill in arcs
|
||||||
|
^ static VOID subrange(struct vars *, pchr, pchr, struct state *,
|
||||||
|
^ struct state *);
|
||||||
*/
|
*/
|
||||||
static void
|
static VOID
|
||||||
subrange(struct vars * v,
|
subrange(v, from, to, lp, rp)
|
||||||
chr from,
|
struct vars *v;
|
||||||
chr to,
|
pchr from;
|
||||||
struct state * lp,
|
pchr to;
|
||||||
struct state * rp)
|
struct state *lp;
|
||||||
|
struct state *rp;
|
||||||
{
|
{
|
||||||
uchr uf;
|
uchr uf;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
assert(from <= to);
|
assert(from <= to);
|
||||||
|
|
||||||
/* first, align "from" on a tree-block boundary */
|
/* first, align "from" on a tree-block boundary */
|
||||||
uf = (uchr) from;
|
uf = (uchr)from;
|
||||||
i = (int) (((uf + BYTTAB - 1) & (uchr) ~BYTMASK) - uf);
|
i = (int)( ((uf + BYTTAB-1) & (uchr)~BYTMASK) - uf );
|
||||||
for (; from <= to && i > 0; i--, from++)
|
for (; from <= to && i > 0; i--, from++)
|
||||||
newarc(v->nfa, PLAIN, subcolor(v->cm, from), lp, rp);
|
newarc(v->nfa, PLAIN, subcolor(v->cm, from), lp, rp);
|
||||||
if (from > to) /* didn't reach a boundary */
|
if (from > to) /* didn't reach a boundary */
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* deal with whole blocks */
|
/* deal with whole blocks */
|
||||||
@@ -437,28 +431,30 @@ subrange(struct vars * v,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* subblock - allocate new subcolors for one tree block of chrs, fill in arcs
|
- subblock - allocate new subcolors for one tree block of chrs, fill in arcs
|
||||||
|
^ static VOID subblock(struct vars *, pchr, struct state *, struct state *);
|
||||||
*/
|
*/
|
||||||
static void
|
static VOID
|
||||||
subblock(struct vars * v,
|
subblock(v, start, lp, rp)
|
||||||
chr start, /* first of BYTTAB chrs */
|
struct vars *v;
|
||||||
struct state * lp,
|
pchr start; /* first of BYTTAB chrs */
|
||||||
struct state * rp)
|
struct state *lp;
|
||||||
|
struct state *rp;
|
||||||
{
|
{
|
||||||
uchr uc = start;
|
uchr uc = start;
|
||||||
struct colormap *cm = v->cm;
|
struct colormap *cm = v->cm;
|
||||||
int shift;
|
int shift;
|
||||||
int level;
|
int level;
|
||||||
int i;
|
int i;
|
||||||
int b;
|
int b;
|
||||||
union tree *t;
|
union tree *t;
|
||||||
union tree *cb;
|
union tree *cb;
|
||||||
union tree *fillt;
|
union tree *fillt;
|
||||||
union tree *lastt;
|
union tree *lastt;
|
||||||
int previ;
|
int previ;
|
||||||
int ndone;
|
int ndone;
|
||||||
color co;
|
color co;
|
||||||
color sco;
|
color sco;
|
||||||
|
|
||||||
assert((uc % BYTTAB) == 0);
|
assert((uc % BYTTAB) == 0);
|
||||||
|
|
||||||
@@ -466,23 +462,20 @@ subblock(struct vars * v,
|
|||||||
t = cm->tree;
|
t = cm->tree;
|
||||||
fillt = NULL;
|
fillt = NULL;
|
||||||
for (level = 0, shift = BYTBITS * (NBYTS - 1); shift > 0;
|
for (level = 0, shift = BYTBITS * (NBYTS - 1); shift > 0;
|
||||||
level++, shift -= BYTBITS)
|
level++, shift -= BYTBITS) {
|
||||||
{
|
|
||||||
b = (uc >> shift) & BYTMASK;
|
b = (uc >> shift) & BYTMASK;
|
||||||
lastt = t;
|
lastt = t;
|
||||||
t = lastt->tptr[b];
|
t = lastt->tptr[b];
|
||||||
assert(t != NULL);
|
assert(t != NULL);
|
||||||
fillt = &cm->tree[level + 1];
|
fillt = &cm->tree[level+1];
|
||||||
if (t == fillt && shift > BYTBITS)
|
if (t == fillt && shift > BYTBITS) { /* need new ptr block */
|
||||||
{ /* need new ptr block */
|
t = (union tree *)MALLOC(sizeof(struct ptrs));
|
||||||
t = (union tree *) MALLOC(sizeof(struct ptrs));
|
if (t == NULL) {
|
||||||
if (t == NULL)
|
|
||||||
{
|
|
||||||
CERR(REG_ESPACE);
|
CERR(REG_ESPACE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
memcpy(VS(t->tptr), VS(fillt->tptr),
|
memcpy(VS(t->tptr), VS(fillt->tptr),
|
||||||
BYTTAB * sizeof(union tree *));
|
BYTTAB*sizeof(union tree *));
|
||||||
lastt->tptr[b] = t;
|
lastt->tptr[b] = t;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -490,16 +483,13 @@ subblock(struct vars * v,
|
|||||||
/* special cases: fill block or solid block */
|
/* special cases: fill block or solid block */
|
||||||
co = t->tcolor[0];
|
co = t->tcolor[0];
|
||||||
cb = cm->cd[co].block;
|
cb = cm->cd[co].block;
|
||||||
if (t == fillt || t == cb)
|
if (t == fillt || t == cb) {
|
||||||
{
|
|
||||||
/* either way, we want a subcolor solid block */
|
/* either way, we want a subcolor solid block */
|
||||||
sco = newsub(cm, co);
|
sco = newsub(cm, co);
|
||||||
t = cm->cd[sco].block;
|
t = cm->cd[sco].block;
|
||||||
if (t == NULL)
|
if (t == NULL) { /* must set it up */
|
||||||
{ /* must set it up */
|
t = (union tree *)MALLOC(sizeof(struct colors));
|
||||||
t = (union tree *) MALLOC(sizeof(struct colors));
|
if (t == NULL) {
|
||||||
if (t == NULL)
|
|
||||||
{
|
|
||||||
CERR(REG_ESPACE);
|
CERR(REG_ESPACE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -517,14 +507,12 @@ subblock(struct vars * v,
|
|||||||
|
|
||||||
/* general case, a mixed block to be altered */
|
/* general case, a mixed block to be altered */
|
||||||
i = 0;
|
i = 0;
|
||||||
while (i < BYTTAB)
|
while (i < BYTTAB) {
|
||||||
{
|
|
||||||
co = t->tcolor[i];
|
co = t->tcolor[i];
|
||||||
sco = newsub(cm, co);
|
sco = newsub(cm, co);
|
||||||
newarc(v->nfa, PLAIN, sco, lp, rp);
|
newarc(v->nfa, PLAIN, sco, lp, rp);
|
||||||
previ = i;
|
previ = i;
|
||||||
do
|
do {
|
||||||
{
|
|
||||||
t->tcolor[i++] = sco;
|
t->tcolor[i++] = sco;
|
||||||
} while (i < BYTTAB && t->tcolor[i] == co);
|
} while (i < BYTTAB && t->tcolor[i] == co);
|
||||||
ndone = i - previ;
|
ndone = i - previ;
|
||||||
@@ -534,40 +522,35 @@ subblock(struct vars * v,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* okcolors - promote subcolors to full colors
|
- okcolors - promote subcolors to full colors
|
||||||
|
^ static VOID okcolors(struct nfa *, struct colormap *);
|
||||||
*/
|
*/
|
||||||
static void
|
static VOID
|
||||||
okcolors(struct nfa * nfa,
|
okcolors(nfa, cm)
|
||||||
struct colormap * cm)
|
struct nfa *nfa;
|
||||||
|
struct colormap *cm;
|
||||||
{
|
{
|
||||||
struct colordesc *cd;
|
struct colordesc *cd;
|
||||||
struct colordesc *end = CDEND(cm);
|
struct colordesc *end = CDEND(cm);
|
||||||
struct colordesc *scd;
|
struct colordesc *scd;
|
||||||
struct arc *a;
|
struct arc *a;
|
||||||
color co;
|
color co;
|
||||||
color sco;
|
color sco;
|
||||||
|
|
||||||
for (cd = cm->cd, co = 0; cd < end; cd++, co++)
|
for (cd = cm->cd, co = 0; cd < end; cd++, co++) {
|
||||||
{
|
|
||||||
sco = cd->sub;
|
sco = cd->sub;
|
||||||
if (UNUSEDCOLOR(cd) || sco == NOSUB)
|
if (UNUSEDCOLOR(cd) || sco == NOSUB) {
|
||||||
{
|
|
||||||
/* has no subcolor, no further action */
|
/* has no subcolor, no further action */
|
||||||
}
|
} else if (sco == co) {
|
||||||
else if (sco == co)
|
|
||||||
{
|
|
||||||
/* is subcolor, let parent deal with it */
|
/* is subcolor, let parent deal with it */
|
||||||
}
|
} else if (cd->nchrs == 0) {
|
||||||
else if (cd->nchrs == 0)
|
|
||||||
{
|
|
||||||
/* parent empty, its arcs change color to subcolor */
|
/* parent empty, its arcs change color to subcolor */
|
||||||
cd->sub = NOSUB;
|
cd->sub = NOSUB;
|
||||||
scd = &cm->cd[sco];
|
scd = &cm->cd[sco];
|
||||||
assert(scd->nchrs > 0);
|
assert(scd->nchrs > 0);
|
||||||
assert(scd->sub == sco);
|
assert(scd->sub == sco);
|
||||||
scd->sub = NOSUB;
|
scd->sub = NOSUB;
|
||||||
while ((a = cd->arcs) != NULL)
|
while ((a = cd->arcs) != NULL) {
|
||||||
{
|
|
||||||
assert(a->co == co);
|
assert(a->co == co);
|
||||||
/* uncolorchain(cm, a); */
|
/* uncolorchain(cm, a); */
|
||||||
cd->arcs = a->colorchain;
|
cd->arcs = a->colorchain;
|
||||||
@@ -577,17 +560,14 @@ okcolors(struct nfa * nfa,
|
|||||||
scd->arcs = a;
|
scd->arcs = a;
|
||||||
}
|
}
|
||||||
freecolor(cm, co);
|
freecolor(cm, co);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
/* parent's arcs must gain parallel subcolor arcs */
|
/* parent's arcs must gain parallel subcolor arcs */
|
||||||
cd->sub = NOSUB;
|
cd->sub = NOSUB;
|
||||||
scd = &cm->cd[sco];
|
scd = &cm->cd[sco];
|
||||||
assert(scd->nchrs > 0);
|
assert(scd->nchrs > 0);
|
||||||
assert(scd->sub == sco);
|
assert(scd->sub == sco);
|
||||||
scd->sub = NOSUB;
|
scd->sub = NOSUB;
|
||||||
for (a = cd->arcs; a != NULL; a = a->colorchain)
|
for (a = cd->arcs; a != NULL; a = a->colorchain) {
|
||||||
{
|
|
||||||
assert(a->co == co);
|
assert(a->co == co);
|
||||||
newarc(nfa, a->type, sco, a->from, a->to);
|
newarc(nfa, a->type, sco, a->from, a->to);
|
||||||
}
|
}
|
||||||
@@ -596,11 +576,13 @@ okcolors(struct nfa * nfa,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* colorchain - add this arc to the color chain of its color
|
- colorchain - add this arc to the color chain of its color
|
||||||
|
^ static VOID colorchain(struct colormap *, struct arc *);
|
||||||
*/
|
*/
|
||||||
static void
|
static VOID
|
||||||
colorchain(struct colormap * cm,
|
colorchain(cm, a)
|
||||||
struct arc * a)
|
struct colormap *cm;
|
||||||
|
struct arc *a;
|
||||||
{
|
{
|
||||||
struct colordesc *cd = &cm->cd[a->co];
|
struct colordesc *cd = &cm->cd[a->co];
|
||||||
|
|
||||||
@@ -609,36 +591,39 @@ colorchain(struct colormap * cm,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* uncolorchain - delete this arc from the color chain of its color
|
- uncolorchain - delete this arc from the color chain of its color
|
||||||
|
^ static VOID uncolorchain(struct colormap *, struct arc *);
|
||||||
*/
|
*/
|
||||||
static void
|
static VOID
|
||||||
uncolorchain(struct colormap * cm,
|
uncolorchain(cm, a)
|
||||||
struct arc * a)
|
struct colormap *cm;
|
||||||
|
struct arc *a;
|
||||||
{
|
{
|
||||||
struct colordesc *cd = &cm->cd[a->co];
|
struct colordesc *cd = &cm->cd[a->co];
|
||||||
struct arc *aa;
|
struct arc *aa;
|
||||||
|
|
||||||
aa = cd->arcs;
|
aa = cd->arcs;
|
||||||
if (aa == a) /* easy case */
|
if (aa == a) /* easy case */
|
||||||
cd->arcs = a->colorchain;
|
cd->arcs = a->colorchain;
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
for (; aa != NULL && aa->colorchain != a; aa = aa->colorchain)
|
for (; aa != NULL && aa->colorchain != a; aa = aa->colorchain)
|
||||||
continue;
|
continue;
|
||||||
assert(aa != NULL);
|
assert(aa != NULL);
|
||||||
aa->colorchain = a->colorchain;
|
aa->colorchain = a->colorchain;
|
||||||
}
|
}
|
||||||
a->colorchain = NULL; /* paranoia */
|
a->colorchain = NULL; /* paranoia */
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* singleton - is this character in its own color?
|
- singleton - is this character in its own color?
|
||||||
|
^ static int singleton(struct colormap *, pchr c);
|
||||||
*/
|
*/
|
||||||
static int /* predicate */
|
static int /* predicate */
|
||||||
singleton(struct colormap * cm,
|
singleton(cm, c)
|
||||||
chr c)
|
struct colormap *cm;
|
||||||
|
pchr c;
|
||||||
{
|
{
|
||||||
color co; /* color of c */
|
color co; /* color of c */
|
||||||
|
|
||||||
co = GETCOLOR(cm, c);
|
co = GETCOLOR(cm, c);
|
||||||
if (cm->cd[co].nchrs == 1 && cm->cd[co].sub == NOSUB)
|
if (cm->cd[co].nchrs == 1 && cm->cd[co].sub == NOSUB)
|
||||||
@@ -647,81 +632,90 @@ singleton(struct colormap * cm,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* rainbow - add arcs of all full colors (but one) between specified states
|
- rainbow - add arcs of all full colors (but one) between specified states
|
||||||
|
^ static VOID rainbow(struct nfa *, struct colormap *, int, pcolor,
|
||||||
|
^ struct state *, struct state *);
|
||||||
*/
|
*/
|
||||||
static void
|
static VOID
|
||||||
rainbow(struct nfa * nfa,
|
rainbow(nfa, cm, type, but, from, to)
|
||||||
struct colormap * cm,
|
struct nfa *nfa;
|
||||||
int type,
|
struct colormap *cm;
|
||||||
pcolor but, /* COLORLESS if no exceptions */
|
int type;
|
||||||
struct state * from,
|
pcolor but; /* COLORLESS if no exceptions */
|
||||||
struct state * to)
|
struct state *from;
|
||||||
|
struct state *to;
|
||||||
{
|
{
|
||||||
struct colordesc *cd;
|
struct colordesc *cd;
|
||||||
struct colordesc *end = CDEND(cm);
|
struct colordesc *end = CDEND(cm);
|
||||||
color co;
|
color co;
|
||||||
|
|
||||||
for (cd = cm->cd, co = 0; cd < end && !CISERR(); cd++, co++)
|
for (cd = cm->cd, co = 0; cd < end && !CISERR(); cd++, co++)
|
||||||
if (!UNUSEDCOLOR(cd) && cd->sub != co && co != but &&
|
if (!UNUSEDCOLOR(cd) && cd->sub != co && co != but &&
|
||||||
!(cd->flags & PSEUDO))
|
!(cd->flags&PSEUDO))
|
||||||
newarc(nfa, type, co, from, to);
|
newarc(nfa, type, co, from, to);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* colorcomplement - add arcs of complementary colors
|
- colorcomplement - add arcs of complementary colors
|
||||||
*
|
|
||||||
* The calling sequence ought to be reconciled with cloneouts().
|
* The calling sequence ought to be reconciled with cloneouts().
|
||||||
|
^ static VOID colorcomplement(struct nfa *, struct colormap *, int,
|
||||||
|
^ struct state *, struct state *, struct state *);
|
||||||
*/
|
*/
|
||||||
static void
|
static VOID
|
||||||
colorcomplement(struct nfa * nfa,
|
colorcomplement(nfa, cm, type, of, from, to)
|
||||||
struct colormap * cm,
|
struct nfa *nfa;
|
||||||
int type,
|
struct colormap *cm;
|
||||||
struct state * of, /* complements of this guy's PLAIN
|
int type;
|
||||||
* outarcs */
|
struct state *of; /* complements of this guy's PLAIN outarcs */
|
||||||
struct state * from,
|
struct state *from;
|
||||||
struct state * to)
|
struct state *to;
|
||||||
{
|
{
|
||||||
struct colordesc *cd;
|
struct colordesc *cd;
|
||||||
struct colordesc *end = CDEND(cm);
|
struct colordesc *end = CDEND(cm);
|
||||||
color co;
|
color co;
|
||||||
|
|
||||||
assert(of != from);
|
assert(of != from);
|
||||||
for (cd = cm->cd, co = 0; cd < end && !CISERR(); cd++, co++)
|
for (cd = cm->cd, co = 0; cd < end && !CISERR(); cd++, co++)
|
||||||
if (!UNUSEDCOLOR(cd) && !(cd->flags & PSEUDO))
|
if (!UNUSEDCOLOR(cd) && !(cd->flags&PSEUDO))
|
||||||
if (findarc(of, PLAIN, co) == NULL)
|
if (findarc(of, PLAIN, co) == NULL)
|
||||||
newarc(nfa, type, co, from, to);
|
newarc(nfa, type, co, from, to);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef REG_DEBUG
|
#ifdef REG_DEBUG
|
||||||
|
/*
|
||||||
|
^ #ifdef REG_DEBUG
|
||||||
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* dumpcolors - debugging output
|
- dumpcolors - debugging output
|
||||||
|
^ static VOID dumpcolors(struct colormap *, FILE *);
|
||||||
*/
|
*/
|
||||||
static void
|
static VOID
|
||||||
dumpcolors(struct colormap * cm,
|
dumpcolors(cm, f)
|
||||||
FILE *f)
|
struct colormap *cm;
|
||||||
|
FILE *f;
|
||||||
{
|
{
|
||||||
struct colordesc *cd;
|
struct colordesc *cd;
|
||||||
struct colordesc *end;
|
struct colordesc *end;
|
||||||
color co;
|
color co;
|
||||||
chr c;
|
chr c;
|
||||||
char *has;
|
char *has;
|
||||||
|
|
||||||
fprintf(f, "max %ld\n", (long) cm->max);
|
fprintf(f, "max %ld\n", (long)cm->max);
|
||||||
if (NBYTS > 1)
|
if (NBYTS > 1)
|
||||||
fillcheck(cm, cm->tree, 0, f);
|
fillcheck(cm, cm->tree, 0, f);
|
||||||
end = CDEND(cm);
|
end = CDEND(cm);
|
||||||
for (cd = cm->cd + 1, co = 1; cd < end; cd++, co++) /* skip 0 */
|
for (cd = cm->cd + 1, co = 1; cd < end; cd++, co++) /* skip 0 */
|
||||||
if (!UNUSEDCOLOR(cd))
|
if (!UNUSEDCOLOR(cd)) {
|
||||||
{
|
|
||||||
assert(cd->nchrs > 0);
|
assert(cd->nchrs > 0);
|
||||||
has = (cd->block != NULL) ? "#" : "";
|
has = (cd->block != NULL) ? "#" : "";
|
||||||
if (cd->flags & PSEUDO)
|
if (cd->flags&PSEUDO)
|
||||||
fprintf(f, "#%2ld%s(ps): ", (long) co, has);
|
fprintf(f, "#%2ld%s(ps): ", (long)co, has);
|
||||||
else
|
else
|
||||||
fprintf(f, "#%2ld%s(%2d): ", (long) co,
|
fprintf(f, "#%2ld%s(%2d): ", (long)co,
|
||||||
has, cd->nchrs);
|
has, cd->nchrs);
|
||||||
/* it's hard to do this more efficiently */
|
/* it's hard to do this more efficiently */
|
||||||
for (c = CHR_MIN; c < CHR_MAX; c++)
|
for (c = CHR_MIN; c < CHR_MAX; c++)
|
||||||
if (GETCOLOR(cm, c) == co)
|
if (GETCOLOR(cm, c) == co)
|
||||||
@@ -734,51 +728,51 @@ dumpcolors(struct colormap * cm,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* fillcheck - check proper filling of a tree
|
- fillcheck - check proper filling of a tree
|
||||||
|
^ static VOID fillcheck(struct colormap *, union tree *, int, FILE *);
|
||||||
*/
|
*/
|
||||||
static void
|
static VOID
|
||||||
fillcheck(struct colormap * cm,
|
fillcheck(cm, tree, level, f)
|
||||||
union tree * tree,
|
struct colormap *cm;
|
||||||
int level, /* level number (top == 0) of this block */
|
union tree *tree;
|
||||||
FILE *f)
|
int level; /* level number (top == 0) of this block */
|
||||||
|
FILE *f;
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
union tree *t;
|
union tree *t;
|
||||||
union tree *fillt = &cm->tree[level + 1];
|
union tree *fillt = &cm->tree[level+1];
|
||||||
|
|
||||||
assert(level < NBYTS - 1); /* this level has pointers */
|
assert(level < NBYTS-1); /* this level has pointers */
|
||||||
for (i = BYTTAB - 1; i >= 0; i--)
|
for (i = BYTTAB-1; i >= 0; i--) {
|
||||||
{
|
|
||||||
t = tree->tptr[i];
|
t = tree->tptr[i];
|
||||||
if (t == NULL)
|
if (t == NULL)
|
||||||
fprintf(f, "NULL found in filled tree!\n");
|
fprintf(f, "NULL found in filled tree!\n");
|
||||||
else if (t == fillt)
|
else if (t == fillt)
|
||||||
{
|
{}
|
||||||
}
|
else if (level < NBYTS-2) /* more pointer blocks below */
|
||||||
else if (level < NBYTS - 2) /* more pointer blocks below */
|
fillcheck(cm, t, level+1, f);
|
||||||
fillcheck(cm, t, level + 1, f);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* dumpchr - print a chr
|
- dumpchr - print a chr
|
||||||
*
|
|
||||||
* Kind of char-centric but works well enough for debug use.
|
* Kind of char-centric but works well enough for debug use.
|
||||||
|
^ static VOID dumpchr(pchr, FILE *);
|
||||||
*/
|
*/
|
||||||
static void
|
static VOID
|
||||||
dumpchr(chr c,
|
dumpchr(c, f)
|
||||||
FILE *f)
|
pchr c;
|
||||||
|
FILE *f;
|
||||||
{
|
{
|
||||||
#if wxUSE_UNICODE
|
|
||||||
fprintf(f, "Debugging not implemented in unicode mode");
|
|
||||||
#else
|
|
||||||
if (c == '\\')
|
if (c == '\\')
|
||||||
fprintf(f, "\\\\");
|
fprintf(f, "\\\\");
|
||||||
else if (c > ' ' && c <= '~')
|
else if (c > ' ' && c <= '~')
|
||||||
putc((char) c, f);
|
putc((char)c, f);
|
||||||
else
|
else
|
||||||
fprintf(f, "\\u%04lx", (long) c);
|
fprintf(f, "\\u%04lx", (long)c);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* REG_DEBUG */
|
/*
|
||||||
|
^ #endif
|
||||||
|
*/
|
||||||
|
#endif /* ifdef REG_DEBUG */
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
* Utility functions for handling cvecs
|
* Utility functions for handling cvecs
|
||||||
* This file is #included by regcomp.c.
|
* This file is #included by regcomp.c.
|
||||||
*
|
*
|
||||||
* Copyright (c) 1998, 1999 Henry Spencer. All rights reserved.
|
* Copyright (c) 1998, 1999 Henry Spencer. All rights reserved.
|
||||||
*
|
*
|
||||||
* Development of this software was funded, in part, by Cray Research Inc.,
|
* Development of this software was funded, in part, by Cray Research Inc.,
|
||||||
* UUNET Communications Services Inc., Sun Microsystems Inc., and Scriptics
|
* UUNET Communications Services Inc., Sun Microsystems Inc., and Scriptics
|
||||||
@@ -28,162 +28,181 @@
|
|||||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $Header$
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* newcvec - allocate a new cvec
|
- newcvec - allocate a new cvec
|
||||||
|
^ static struct cvec *newcvec(int, int, int);
|
||||||
*/
|
*/
|
||||||
static struct cvec *
|
static struct cvec *
|
||||||
newcvec(int nchrs, /* to hold this many chrs... */
|
newcvec(nchrs, nranges, nmcces)
|
||||||
int nranges, /* ... and this many ranges... */
|
int nchrs; /* to hold this many chrs... */
|
||||||
int nmcces) /* ... and this many MCCEs */
|
int nranges; /* ... and this many ranges... */
|
||||||
|
int nmcces; /* ... and this many MCCEs */
|
||||||
{
|
{
|
||||||
size_t n;
|
size_t n;
|
||||||
size_t nc;
|
size_t nc;
|
||||||
struct cvec *cv;
|
struct cvec *cv;
|
||||||
|
|
||||||
nc = (size_t) nchrs + (size_t) nmcces *(MAXMCCE + 1) + (size_t) nranges *2;
|
nc = (size_t)nchrs + (size_t)nmcces*(MAXMCCE+1) + (size_t)nranges*2;
|
||||||
|
n = sizeof(struct cvec) + (size_t)(nmcces-1)*sizeof(chr *)
|
||||||
n = sizeof(struct cvec) + (size_t) (nmcces - 1) * sizeof(chr *)
|
+ nc*sizeof(chr);
|
||||||
+ nc * sizeof(chr);
|
cv = (struct cvec *)MALLOC(n);
|
||||||
cv = (struct cvec *) MALLOC(n);
|
if (cv == NULL) {
|
||||||
if (cv == NULL)
|
return NULL;
|
||||||
return NULL;
|
}
|
||||||
cv->chrspace = nchrs;
|
cv->chrspace = nchrs;
|
||||||
cv->chrs = (chr *) &cv->mcces[nmcces]; /* chrs just after MCCE
|
cv->chrs = (chr *)&cv->mcces[nmcces]; /* chrs just after MCCE ptrs */
|
||||||
* ptrs */
|
cv->mccespace = nmcces;
|
||||||
cv->mccespace = nmcces;
|
cv->ranges = cv->chrs + nchrs + nmcces*(MAXMCCE+1);
|
||||||
cv->ranges = cv->chrs + nchrs + nmcces * (MAXMCCE + 1);
|
cv->rangespace = nranges;
|
||||||
cv->rangespace = nranges;
|
return clearcvec(cv);
|
||||||
return clearcvec(cv);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* clearcvec - clear a possibly-new cvec
|
- clearcvec - clear a possibly-new cvec
|
||||||
* Returns pointer as convenience.
|
* Returns pointer as convenience.
|
||||||
|
^ static struct cvec *clearcvec(struct cvec *);
|
||||||
*/
|
*/
|
||||||
static struct cvec *
|
static struct cvec *
|
||||||
clearcvec(struct cvec * cv)
|
clearcvec(cv)
|
||||||
|
struct cvec *cv; /* character vector */
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
assert(cv != NULL);
|
assert(cv != NULL);
|
||||||
cv->nchrs = 0;
|
cv->nchrs = 0;
|
||||||
assert(cv->chrs == (chr *) &cv->mcces[cv->mccespace]);
|
assert(cv->chrs == (chr *)&cv->mcces[cv->mccespace]);
|
||||||
cv->nmcces = 0;
|
cv->nmcces = 0;
|
||||||
cv->nmccechrs = 0;
|
cv->nmccechrs = 0;
|
||||||
cv->nranges = 0;
|
cv->nranges = 0;
|
||||||
for (i = 0; i < cv->mccespace; i++)
|
for (i = 0; i < cv->mccespace; i++) {
|
||||||
cv->mcces[i] = NULL;
|
cv->mcces[i] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
return cv;
|
return cv;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* addchr - add a chr to a cvec
|
- addchr - add a chr to a cvec
|
||||||
|
^ static VOID addchr(struct cvec *, pchr);
|
||||||
*/
|
*/
|
||||||
static void
|
static VOID
|
||||||
addchr(struct cvec * cv, /* character vector */
|
addchr(cv, c)
|
||||||
chr c) /* character to add */
|
struct cvec *cv; /* character vector */
|
||||||
|
pchr c; /* character to add */
|
||||||
{
|
{
|
||||||
assert(cv->nchrs < cv->chrspace - cv->nmccechrs);
|
assert(cv->nchrs < cv->chrspace - cv->nmccechrs);
|
||||||
cv->chrs[cv->nchrs++] = (chr) c;
|
cv->chrs[cv->nchrs++] = (chr)c;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* addrange - add a range to a cvec
|
- addrange - add a range to a cvec
|
||||||
|
^ static VOID addrange(struct cvec *, pchr, pchr);
|
||||||
*/
|
*/
|
||||||
static void
|
static VOID
|
||||||
addrange(struct cvec * cv, /* character vector */
|
addrange(cv, from, to)
|
||||||
chr from, /* first character of range */
|
struct cvec *cv; /* character vector */
|
||||||
chr to) /* last character of range */
|
pchr from; /* first character of range */
|
||||||
|
pchr to; /* last character of range */
|
||||||
{
|
{
|
||||||
assert(cv->nranges < cv->rangespace);
|
assert(cv->nranges < cv->rangespace);
|
||||||
cv->ranges[cv->nranges * 2] = (chr) from;
|
cv->ranges[cv->nranges*2] = (chr)from;
|
||||||
cv->ranges[cv->nranges * 2 + 1] = (chr) to;
|
cv->ranges[cv->nranges*2 + 1] = (chr)to;
|
||||||
cv->nranges++;
|
cv->nranges++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* addmcce - add an MCCE to a cvec
|
- addmcce - add an MCCE to a cvec
|
||||||
|
^ static VOID addmcce(struct cvec *, chr *, chr *);
|
||||||
*/
|
*/
|
||||||
static void
|
static VOID
|
||||||
addmcce(struct cvec * cv, /* character vector */
|
addmcce(cv, startp, endp)
|
||||||
chr *startp, /* beginning of text */
|
struct cvec *cv; /* character vector */
|
||||||
chr *endp) /* just past end of text */
|
chr *startp; /* beginning of text */
|
||||||
|
chr *endp; /* just past end of text */
|
||||||
{
|
{
|
||||||
int len;
|
int len;
|
||||||
int i;
|
int i;
|
||||||
chr *s;
|
chr *s;
|
||||||
chr *d;
|
chr *d;
|
||||||
|
|
||||||
if (startp == NULL && endp == NULL)
|
if (startp == NULL && endp == NULL) {
|
||||||
return;
|
return;
|
||||||
len = endp - startp;
|
}
|
||||||
assert(len > 0);
|
len = endp - startp;
|
||||||
assert(cv->nchrs + len < cv->chrspace - cv->nmccechrs);
|
assert(len > 0);
|
||||||
assert(cv->nmcces < cv->mccespace);
|
assert(cv->nchrs + len < cv->chrspace - cv->nmccechrs);
|
||||||
d = &cv->chrs[cv->chrspace - cv->nmccechrs - len - 1];
|
assert(cv->nmcces < cv->mccespace);
|
||||||
cv->mcces[cv->nmcces++] = d;
|
d = &cv->chrs[cv->chrspace - cv->nmccechrs - len - 1];
|
||||||
for (s = startp, i = len; i > 0; s++, i--)
|
cv->mcces[cv->nmcces++] = d;
|
||||||
*d++ = *s;
|
for (s = startp, i = len; i > 0; s++, i--) {
|
||||||
*d++ = 0; /* endmarker */
|
*d++ = *s;
|
||||||
assert(d == &cv->chrs[cv->chrspace - cv->nmccechrs]);
|
}
|
||||||
cv->nmccechrs += len + 1;
|
*d++ = 0; /* endmarker */
|
||||||
|
assert(d == &cv->chrs[cv->chrspace - cv->nmccechrs]);
|
||||||
|
cv->nmccechrs += len + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* haschr - does a cvec contain this chr?
|
- haschr - does a cvec contain this chr?
|
||||||
|
^ static int haschr(struct cvec *, pchr);
|
||||||
*/
|
*/
|
||||||
static int /* predicate */
|
static int /* predicate */
|
||||||
haschr(struct cvec * cv, /* character vector */
|
haschr(cv, c)
|
||||||
chr c) /* character to test for */
|
struct cvec *cv; /* character vector */
|
||||||
|
pchr c; /* character to test for */
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
chr *p;
|
chr *p;
|
||||||
|
|
||||||
for (p = cv->chrs, i = cv->nchrs; i > 0; p++, i--)
|
for (p = cv->chrs, i = cv->nchrs; i > 0; p++, i--) {
|
||||||
{
|
if (*p == c) {
|
||||||
if (*p == c)
|
return 1;
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
for (p = cv->ranges, i = cv->nranges; i > 0; p += 2, i--)
|
}
|
||||||
{
|
for (p = cv->ranges, i = cv->nranges; i > 0; p += 2, i--) {
|
||||||
if ((*p <= c) && (c <= *(p + 1)))
|
if ((*p <= c) && (c <= *(p+1))) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return 0;
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* getcvec - get a cvec, remembering it as v->cv
|
- getcvec - get a cvec, remembering it as v->cv
|
||||||
|
^ static struct cvec *getcvec(struct vars *, int, int, int);
|
||||||
*/
|
*/
|
||||||
static struct cvec *
|
static struct cvec *
|
||||||
getcvec(struct vars * v, /* context */
|
getcvec(v, nchrs, nranges, nmcces)
|
||||||
int nchrs, /* to hold this many chrs... */
|
struct vars *v; /* context */
|
||||||
int nranges, /* ... and this many ranges... */
|
int nchrs; /* to hold this many chrs... */
|
||||||
int nmcces) /* ... and this many MCCEs */
|
int nranges; /* ... and this many ranges... */
|
||||||
|
int nmcces; /* ... and this many MCCEs */
|
||||||
{
|
{
|
||||||
if (v->cv != NULL && nchrs <= v->cv->chrspace &&
|
if (v->cv != NULL && nchrs <= v->cv->chrspace &&
|
||||||
nranges <= v->cv->rangespace && nmcces <= v->cv->mccespace)
|
nranges <= v->cv->rangespace && nmcces <= v->cv->mccespace) {
|
||||||
return clearcvec(v->cv);
|
return clearcvec(v->cv);
|
||||||
|
}
|
||||||
|
|
||||||
if (v->cv != NULL)
|
if (v->cv != NULL) {
|
||||||
freecvec(v->cv);
|
freecvec(v->cv);
|
||||||
v->cv = newcvec(nchrs, nranges, nmcces);
|
}
|
||||||
if (v->cv == NULL)
|
v->cv = newcvec(nchrs, nranges, nmcces);
|
||||||
ERR(REG_ESPACE);
|
if (v->cv == NULL) {
|
||||||
|
ERR(REG_ESPACE);
|
||||||
|
}
|
||||||
|
|
||||||
return v->cv;
|
return v->cv;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* freecvec - free a cvec
|
- freecvec - free a cvec
|
||||||
|
^ static VOID freecvec(struct cvec *);
|
||||||
*/
|
*/
|
||||||
static void
|
static VOID
|
||||||
freecvec(struct cvec * cv)
|
freecvec(cv)
|
||||||
|
struct cvec *cv; /* character vector */
|
||||||
{
|
{
|
||||||
FREE(cv);
|
FREE(cv);
|
||||||
}
|
}
|
||||||
|
1587
src/regex/regc_lex.c
1587
src/regex/regc_lex.c
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
1154
src/regex/regc_nfa.c
1154
src/regex/regc_nfa.c
File diff suppressed because it is too large
Load Diff
2137
src/regex/regcomp.c
2137
src/regex/regcomp.c
File diff suppressed because it is too large
Load Diff
@@ -1,8 +1,5 @@
|
|||||||
#ifndef _REGEX_CUSTOM_H_
|
|
||||||
#define _REGEX_CUSTOM_H_
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1998, 1999 Henry Spencer. All rights reserved.
|
* Copyright (c) 1998, 1999 Henry Spencer. All rights reserved.
|
||||||
*
|
*
|
||||||
* Development of this software was funded, in part, by Cray Research Inc.,
|
* Development of this software was funded, in part, by Cray Research Inc.,
|
||||||
* UUNET Communications Services Inc., Sun Microsystems Inc., and Scriptics
|
* UUNET Communications Services Inc., Sun Microsystems Inc., and Scriptics
|
||||||
@@ -27,72 +24,97 @@
|
|||||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
|
||||||
* $Id$
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* headers if any */
|
/* headers if any */
|
||||||
|
#include "tclInt.h"
|
||||||
/* FreeBSD, Watcom and DMars require this, CW doesn't have nor need it. */
|
|
||||||
/* Others also don't seem to need it. If you have an error related to */
|
|
||||||
/* (not) including <sys/types.h> please report details to */
|
|
||||||
/* wx-dev@lists.wxwindows.org */
|
|
||||||
#if defined(__UNIX__) || defined(__WATCOMC__) || defined(__DIGITALMARS__)
|
|
||||||
# include <sys/types.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <ctype.h>
|
|
||||||
#include <limits.h>
|
|
||||||
|
|
||||||
#include "wx/wxchar.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* wx_wchar == wxChar
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#define wx_wchar wxChar
|
|
||||||
|
|
||||||
/* overrides for regguts.h definitions, if any */
|
/* overrides for regguts.h definitions, if any */
|
||||||
#define FUNCPTR(name, args) (*name) args
|
#define FUNCPTR(name, args) (*name) _ANSI_ARGS_(args)
|
||||||
#define MALLOC(n) malloc(n)
|
#define MALLOC(n) ckalloc(n)
|
||||||
#define FREE(p) free(VS(p))
|
#define FREE(p) ckfree(VS(p))
|
||||||
#define REALLOC(p,n) realloc(VS(p),n)
|
#define REALLOC(p,n) ckrealloc(VS(p),n)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Do not insert extras between the "begin" and "end" lines -- this
|
||||||
|
* chunk is automatically extracted to be fitted into regex.h.
|
||||||
|
*/
|
||||||
|
/* --- begin --- */
|
||||||
|
/* ensure certain things don't sneak in from system headers */
|
||||||
|
#ifdef __REG_WIDE_T
|
||||||
|
#undef __REG_WIDE_T
|
||||||
|
#endif
|
||||||
|
#ifdef __REG_WIDE_COMPILE
|
||||||
|
#undef __REG_WIDE_COMPILE
|
||||||
|
#endif
|
||||||
|
#ifdef __REG_WIDE_EXEC
|
||||||
|
#undef __REG_WIDE_EXEC
|
||||||
|
#endif
|
||||||
|
#ifdef __REG_REGOFF_T
|
||||||
|
#undef __REG_REGOFF_T
|
||||||
|
#endif
|
||||||
|
#ifdef __REG_VOID_T
|
||||||
|
#undef __REG_VOID_T
|
||||||
|
#endif
|
||||||
|
#ifdef __REG_CONST
|
||||||
|
#undef __REG_CONST
|
||||||
|
#endif
|
||||||
|
#ifdef __REG_NOFRONT
|
||||||
|
#undef __REG_NOFRONT
|
||||||
|
#endif
|
||||||
|
#ifdef __REG_NOCHAR
|
||||||
|
#undef __REG_NOCHAR
|
||||||
|
#endif
|
||||||
|
/* interface types */
|
||||||
|
#define __REG_WIDE_T Tcl_UniChar
|
||||||
|
#define __REG_REGOFF_T long /* not really right, but good enough... */
|
||||||
|
#define __REG_VOID_T VOID
|
||||||
|
#define __REG_CONST CONST
|
||||||
|
/* names and declarations */
|
||||||
|
#define __REG_WIDE_COMPILE TclReComp
|
||||||
|
#define __REG_WIDE_EXEC TclReExec
|
||||||
|
#define __REG_NOFRONT /* don't want regcomp() and regexec() */
|
||||||
|
#define __REG_NOCHAR /* or the char versions */
|
||||||
|
#define regfree TclReFree
|
||||||
|
#define regerror TclReError
|
||||||
|
/* --- end --- */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* internal character type and related */
|
/* internal character type and related */
|
||||||
typedef wx_wchar chr; /* the type itself */
|
typedef Tcl_UniChar chr; /* the type itself */
|
||||||
typedef unsigned long uchr; /* unsigned type that will hold a chr */
|
typedef int pchr; /* what it promotes to */
|
||||||
typedef long celt; /* type to hold chr, MCCE number, or
|
typedef unsigned uchr; /* unsigned type that will hold a chr */
|
||||||
* NOCELT */
|
typedef int celt; /* type to hold chr, MCCE number, or NOCELT */
|
||||||
|
#define NOCELT (-1) /* celt value which is not valid chr or MCCE */
|
||||||
#define NOCELT (-1) /* celt value which is not valid chr or
|
#define CHR(c) (UCHAR(c)) /* turn char literal into chr literal */
|
||||||
* MCCE */
|
#define DIGITVAL(c) ((c)-'0') /* turn chr digit into its value */
|
||||||
#define CHR(c) ((unsigned char) (c)) /* turn char literal into chr
|
#if TCL_UTF_MAX > 3
|
||||||
* literal */
|
#define CHRBITS 32 /* bits in a chr; must not use sizeof */
|
||||||
#define DIGITVAL(c) ((c)-'0') /* turn chr digit into its value */
|
#define CHR_MIN 0x00000000 /* smallest and largest chr; the value */
|
||||||
|
#define CHR_MAX 0xffffffff /* CHR_MAX-CHR_MIN+1 should fit in uchr */
|
||||||
#if wxUSE_WCHAR_T
|
#else
|
||||||
# define CHRBITS (SIZEOF_WCHAR_T << 3) /* bits in a chr; must not use sizeof */
|
#define CHRBITS 16 /* bits in a chr; must not use sizeof */
|
||||||
# define CHR_MAX ((1 << CHRBITS) - 1)
|
#define CHR_MIN 0x0000 /* smallest and largest chr; the value */
|
||||||
# define CHR_MIN 0x00000000 /* smallest and largest chr; the value */
|
#define CHR_MAX 0xffff /* CHR_MAX-CHR_MIN+1 should fit in uchr */
|
||||||
#else /*ANSI*/
|
#endif
|
||||||
# define CHRBITS 8
|
|
||||||
# define CHR_MAX 0xFF
|
|
||||||
# define CHR_MIN 0x00
|
|
||||||
#endif /*wxUSE_WCHAR_T*/
|
|
||||||
|
|
||||||
/* functions operating on chr */
|
/* functions operating on chr */
|
||||||
#define iscalnum(x) wx_isalnum(x)
|
#define iscalnum(x) Tcl_UniCharIsAlnum(x)
|
||||||
#define iscalpha(x) wx_isalpha(x)
|
#define iscalpha(x) Tcl_UniCharIsAlpha(x)
|
||||||
#define iscdigit(x) wx_isdigit(x)
|
#define iscdigit(x) Tcl_UniCharIsDigit(x)
|
||||||
#define iscspace(x) wx_isspace(x)
|
#define iscspace(x) Tcl_UniCharIsSpace(x)
|
||||||
|
|
||||||
extern int wx_strlen(const wx_wchar* szString);
|
/* name the external functions */
|
||||||
|
#define compile TclReComp
|
||||||
|
#define exec TclReExec
|
||||||
|
|
||||||
|
/* enable/disable debugging code (by whether REG_DEBUG is defined or not) */
|
||||||
|
#if 0 /* no debug unless requested by makefile */
|
||||||
|
#define REG_DEBUG /* */
|
||||||
|
#endif
|
||||||
|
|
||||||
/* and pick up the standard header */
|
/* and pick up the standard header */
|
||||||
#include "regex.h"
|
#include "regex.h"
|
||||||
|
|
||||||
#endif /* _REGEX_CUSTOM_H_ */
|
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
* DFA routines
|
* DFA routines
|
||||||
* This file is #included by regexec.c.
|
* This file is #included by regexec.c.
|
||||||
*
|
*
|
||||||
* Copyright (c) 1998, 1999 Henry Spencer. All rights reserved.
|
* Copyright (c) 1998, 1999 Henry Spencer. All rights reserved.
|
||||||
*
|
*
|
||||||
* Development of this software was funded, in part, by Cray Research Inc.,
|
* Development of this software was funded, in part, by Cray Research Inc.,
|
||||||
* UUNET Communications Services Inc., Sun Microsystems Inc., and Scriptics
|
* UUNET Communications Services Inc., Sun Microsystems Inc., and Scriptics
|
||||||
@@ -28,27 +28,27 @@
|
|||||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $Header$
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* longest - longest-preferred matching engine
|
- longest - longest-preferred matching engine
|
||||||
|
^ static chr *longest(struct vars *, struct dfa *, chr *, chr *, int *);
|
||||||
*/
|
*/
|
||||||
static chr * /* endpoint, or NULL */
|
static chr * /* endpoint, or NULL */
|
||||||
longest(struct vars * v, /* used only for debug and exec flags */
|
longest(v, d, start, stop, hitstopp)
|
||||||
struct dfa * d,
|
struct vars *v; /* used only for debug and exec flags */
|
||||||
chr *start, /* where the match should start */
|
struct dfa *d;
|
||||||
chr *stop, /* match must end at or before here */
|
chr *start; /* where the match should start */
|
||||||
int *hitstopp) /* record whether hit v->stop, if non-NULL */
|
chr *stop; /* match must end at or before here */
|
||||||
|
int *hitstopp; /* record whether hit v->stop, if non-NULL */
|
||||||
{
|
{
|
||||||
chr *cp;
|
chr *cp;
|
||||||
chr *realstop = (stop == v->stop) ? stop : stop + 1;
|
chr *realstop = (stop == v->stop) ? stop : stop + 1;
|
||||||
color co;
|
color co;
|
||||||
struct sset *css;
|
struct sset *css;
|
||||||
struct sset *ss;
|
struct sset *ss;
|
||||||
chr *post;
|
chr *post;
|
||||||
int i;
|
int i;
|
||||||
struct colormap *cm = d->cm;
|
struct colormap *cm = d->cm;
|
||||||
|
|
||||||
/* initialize */
|
/* initialize */
|
||||||
@@ -59,15 +59,12 @@ longest(struct vars * v, /* used only for debug and exec flags */
|
|||||||
|
|
||||||
/* startup */
|
/* startup */
|
||||||
FDEBUG(("+++ startup +++\n"));
|
FDEBUG(("+++ startup +++\n"));
|
||||||
if (cp == v->start)
|
if (cp == v->start) {
|
||||||
{
|
co = d->cnfa->bos[(v->eflags®_NOTBOL) ? 0 : 1];
|
||||||
co = d->cnfa->bos[(v->eflags & REG_NOTBOL) ? 0 : 1];
|
FDEBUG(("color %ld\n", (long)co));
|
||||||
FDEBUG(("color %ld\n", (long) co));
|
} else {
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
co = GETCOLOR(cm, *(cp - 1));
|
co = GETCOLOR(cm, *(cp - 1));
|
||||||
FDEBUG(("char %c, color %ld\n", (char) *(cp - 1), (long) co));
|
FDEBUG(("char %c, color %ld\n", (char)*(cp-1), (long)co));
|
||||||
}
|
}
|
||||||
css = miss(v, d, css, co, cp, start);
|
css = miss(v, d, css, co, cp, start);
|
||||||
if (css == NULL)
|
if (css == NULL)
|
||||||
@@ -75,33 +72,29 @@ longest(struct vars * v, /* used only for debug and exec flags */
|
|||||||
css->lastseen = cp;
|
css->lastseen = cp;
|
||||||
|
|
||||||
/* main loop */
|
/* main loop */
|
||||||
if (v->eflags & REG_FTRACE)
|
if (v->eflags®_FTRACE)
|
||||||
while (cp < realstop)
|
while (cp < realstop) {
|
||||||
{
|
|
||||||
FDEBUG(("+++ at c%d +++\n", css - d->ssets));
|
FDEBUG(("+++ at c%d +++\n", css - d->ssets));
|
||||||
co = GETCOLOR(cm, *cp);
|
co = GETCOLOR(cm, *cp);
|
||||||
FDEBUG(("char %c, color %ld\n", (char) *cp, (long) co));
|
FDEBUG(("char %c, color %ld\n", (char)*cp, (long)co));
|
||||||
ss = css->outs[co];
|
ss = css->outs[co];
|
||||||
if (ss == NULL)
|
if (ss == NULL) {
|
||||||
{
|
ss = miss(v, d, css, co, cp+1, start);
|
||||||
ss = miss(v, d, css, co, cp + 1, start);
|
|
||||||
if (ss == NULL)
|
if (ss == NULL)
|
||||||
break; /* NOTE BREAK OUT */
|
break; /* NOTE BREAK OUT */
|
||||||
}
|
}
|
||||||
cp++;
|
cp++;
|
||||||
ss->lastseen = cp;
|
ss->lastseen = cp;
|
||||||
css = ss;
|
css = ss;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
while (cp < realstop)
|
while (cp < realstop) {
|
||||||
{
|
|
||||||
co = GETCOLOR(cm, *cp);
|
co = GETCOLOR(cm, *cp);
|
||||||
ss = css->outs[co];
|
ss = css->outs[co];
|
||||||
if (ss == NULL)
|
if (ss == NULL) {
|
||||||
{
|
ss = miss(v, d, css, co, cp+1, start);
|
||||||
ss = miss(v, d, css, co, cp + 1, start);
|
|
||||||
if (ss == NULL)
|
if (ss == NULL)
|
||||||
break; /* NOTE BREAK OUT */
|
break; /* NOTE BREAK OUT */
|
||||||
}
|
}
|
||||||
cp++;
|
cp++;
|
||||||
ss->lastseen = cp;
|
ss->lastseen = cp;
|
||||||
@@ -110,15 +103,14 @@ longest(struct vars * v, /* used only for debug and exec flags */
|
|||||||
|
|
||||||
/* shutdown */
|
/* shutdown */
|
||||||
FDEBUG(("+++ shutdown at c%d +++\n", css - d->ssets));
|
FDEBUG(("+++ shutdown at c%d +++\n", css - d->ssets));
|
||||||
if (cp == v->stop && stop == v->stop)
|
if (cp == v->stop && stop == v->stop) {
|
||||||
{
|
|
||||||
if (hitstopp != NULL)
|
if (hitstopp != NULL)
|
||||||
*hitstopp = 1;
|
*hitstopp = 1;
|
||||||
co = d->cnfa->eos[(v->eflags & REG_NOTEOL) ? 0 : 1];
|
co = d->cnfa->eos[(v->eflags®_NOTEOL) ? 0 : 1];
|
||||||
FDEBUG(("color %ld\n", (long) co));
|
FDEBUG(("color %ld\n", (long)co));
|
||||||
ss = miss(v, d, css, co, cp, start);
|
ss = miss(v, d, css, co, cp, start);
|
||||||
/* special case: match ended at eol? */
|
/* special case: match ended at eol? */
|
||||||
if (ss != NULL && (ss->flags & POSTSTATE))
|
if (ss != NULL && (ss->flags&POSTSTATE))
|
||||||
return cp;
|
return cp;
|
||||||
else if (ss != NULL)
|
else if (ss != NULL)
|
||||||
ss->lastseen = cp; /* to be tidy */
|
ss->lastseen = cp; /* to be tidy */
|
||||||
@@ -127,32 +119,34 @@ longest(struct vars * v, /* used only for debug and exec flags */
|
|||||||
/* find last match, if any */
|
/* find last match, if any */
|
||||||
post = d->lastpost;
|
post = d->lastpost;
|
||||||
for (ss = d->ssets, i = d->nssused; i > 0; ss++, i--)
|
for (ss = d->ssets, i = d->nssused; i > 0; ss++, i--)
|
||||||
if ((ss->flags & POSTSTATE) && post != ss->lastseen &&
|
if ((ss->flags&POSTSTATE) && post != ss->lastseen &&
|
||||||
(post == NULL || post < ss->lastseen))
|
(post == NULL || post < ss->lastseen))
|
||||||
post = ss->lastseen;
|
post = ss->lastseen;
|
||||||
if (post != NULL) /* found one */
|
if (post != NULL) /* found one */
|
||||||
return post - 1;
|
return post - 1;
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* shortest - shortest-preferred matching engine
|
- shortest - shortest-preferred matching engine
|
||||||
|
^ static chr *shortest(struct vars *, struct dfa *, chr *, chr *, chr *,
|
||||||
|
^ chr **, int *);
|
||||||
*/
|
*/
|
||||||
static chr * /* endpoint, or NULL */
|
static chr * /* endpoint, or NULL */
|
||||||
shortest(struct vars * v,
|
shortest(v, d, start, min, max, coldp, hitstopp)
|
||||||
struct dfa * d,
|
struct vars *v;
|
||||||
chr *start, /* where the match should start */
|
struct dfa *d;
|
||||||
chr *min, /* match must end at or after here */
|
chr *start; /* where the match should start */
|
||||||
chr *max, /* match must end at or before here */
|
chr *min; /* match must end at or after here */
|
||||||
chr **coldp, /* store coldstart pointer here, if
|
chr *max; /* match must end at or before here */
|
||||||
* nonNULL */
|
chr **coldp; /* store coldstart pointer here, if nonNULL */
|
||||||
int *hitstopp) /* record whether hit v->stop, if non-NULL */
|
int *hitstopp; /* record whether hit v->stop, if non-NULL */
|
||||||
{
|
{
|
||||||
chr *cp;
|
chr *cp;
|
||||||
chr *realmin = (min == v->stop) ? min : min + 1;
|
chr *realmin = (min == v->stop) ? min : min + 1;
|
||||||
chr *realmax = (max == v->stop) ? max : max + 1;
|
chr *realmax = (max == v->stop) ? max : max + 1;
|
||||||
color co;
|
color co;
|
||||||
struct sset *css;
|
struct sset *css;
|
||||||
struct sset *ss;
|
struct sset *ss;
|
||||||
struct colormap *cm = d->cm;
|
struct colormap *cm = d->cm;
|
||||||
@@ -165,15 +159,12 @@ shortest(struct vars * v,
|
|||||||
|
|
||||||
/* startup */
|
/* startup */
|
||||||
FDEBUG(("--- startup ---\n"));
|
FDEBUG(("--- startup ---\n"));
|
||||||
if (cp == v->start)
|
if (cp == v->start) {
|
||||||
{
|
co = d->cnfa->bos[(v->eflags®_NOTBOL) ? 0 : 1];
|
||||||
co = d->cnfa->bos[(v->eflags & REG_NOTBOL) ? 0 : 1];
|
FDEBUG(("color %ld\n", (long)co));
|
||||||
FDEBUG(("color %ld\n", (long) co));
|
} else {
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
co = GETCOLOR(cm, *(cp - 1));
|
co = GETCOLOR(cm, *(cp - 1));
|
||||||
FDEBUG(("char %c, color %ld\n", (char) *(cp - 1), (long) co));
|
FDEBUG(("char %c, color %ld\n", (char)*(cp-1), (long)co));
|
||||||
}
|
}
|
||||||
css = miss(v, d, css, co, cp, start);
|
css = miss(v, d, css, co, cp, start);
|
||||||
if (css == NULL)
|
if (css == NULL)
|
||||||
@@ -182,116 +173,110 @@ shortest(struct vars * v,
|
|||||||
ss = css;
|
ss = css;
|
||||||
|
|
||||||
/* main loop */
|
/* main loop */
|
||||||
if (v->eflags & REG_FTRACE)
|
if (v->eflags®_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®_NOTEOL) ? 0 : 1];
|
||||||
{
|
FDEBUG(("color %ld\n", (long)co));
|
||||||
co = d->cnfa->eos[(v->eflags & REG_NOTEOL) ? 0 : 1];
|
|
||||||
FDEBUG(("color %ld\n", (long) co));
|
|
||||||
ss = miss(v, d, css, co, cp, start);
|
ss = miss(v, d, css, co, cp, start);
|
||||||
/* match might have ended at eol */
|
/* match might have ended at eol */
|
||||||
if ((ss == NULL || !(ss->flags & POSTSTATE)) && hitstopp != NULL)
|
if ((ss == NULL || !(ss->flags&POSTSTATE)) && hitstopp != NULL)
|
||||||
*hitstopp = 1;
|
*hitstopp = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ss == NULL || !(ss->flags & POSTSTATE))
|
if (ss == NULL || !(ss->flags&POSTSTATE))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
return cp;
|
return cp;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* lastcold - determine last point at which no progress had been made
|
- lastcold - determine last point at which no progress had been made
|
||||||
|
^ static chr *lastcold(struct vars *, struct dfa *);
|
||||||
*/
|
*/
|
||||||
static chr * /* endpoint, or NULL */
|
static chr * /* endpoint, or NULL */
|
||||||
lastcold(struct vars * v,
|
lastcold(v, d)
|
||||||
struct dfa * d)
|
struct vars *v;
|
||||||
|
struct dfa *d;
|
||||||
{
|
{
|
||||||
struct sset *ss;
|
struct sset *ss;
|
||||||
chr *nopr;
|
chr *nopr;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
nopr = d->lastnopr;
|
nopr = d->lastnopr;
|
||||||
if (nopr == NULL)
|
if (nopr == NULL)
|
||||||
nopr = v->start;
|
nopr = v->start;
|
||||||
for (ss = d->ssets, i = d->nssused; i > 0; ss++, i--)
|
for (ss = d->ssets, i = d->nssused; i > 0; ss++, i--)
|
||||||
if ((ss->flags & NOPROGRESS) && nopr < ss->lastseen)
|
if ((ss->flags&NOPROGRESS) && nopr < ss->lastseen)
|
||||||
nopr = ss->lastseen;
|
nopr = ss->lastseen;
|
||||||
return nopr;
|
return nopr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* newdfa - set up a fresh DFA
|
- newdfa - set up a fresh DFA
|
||||||
|
^ static struct dfa *newdfa(struct vars *, struct cnfa *,
|
||||||
|
^ struct colormap *, struct smalldfa *);
|
||||||
*/
|
*/
|
||||||
static struct dfa *
|
static struct dfa *
|
||||||
newdfa(struct vars * v,
|
newdfa(v, cnfa, cm, small)
|
||||||
struct cnfa * cnfa,
|
struct vars *v;
|
||||||
struct colormap * cm,
|
struct cnfa *cnfa;
|
||||||
struct smalldfa * small) /* preallocated space, may be NULL */
|
struct colormap *cm;
|
||||||
|
struct smalldfa *small; /* preallocated space, may be NULL */
|
||||||
{
|
{
|
||||||
struct dfa *d;
|
struct dfa *d;
|
||||||
size_t nss = cnfa->nstates * 2;
|
size_t nss = cnfa->nstates * 2;
|
||||||
int wordsper = (cnfa->nstates + UBITS - 1) / UBITS;
|
int wordsper = (cnfa->nstates + UBITS - 1) / UBITS;
|
||||||
struct smalldfa *smallwas = small;
|
struct smalldfa *smallwas = small;
|
||||||
|
|
||||||
assert(cnfa != NULL && cnfa->nstates != 0);
|
assert(cnfa != NULL && cnfa->nstates != 0);
|
||||||
|
|
||||||
if (nss <= FEWSTATES && cnfa->ncolors <= FEWCOLORS)
|
if (nss <= FEWSTATES && cnfa->ncolors <= FEWCOLORS) {
|
||||||
{
|
|
||||||
assert(wordsper == 1);
|
assert(wordsper == 1);
|
||||||
if (small == NULL)
|
if (small == NULL) {
|
||||||
{
|
small = (struct smalldfa *)MALLOC(
|
||||||
small = (struct smalldfa *) MALLOC(
|
sizeof(struct smalldfa));
|
||||||
sizeof(struct smalldfa));
|
if (small == NULL) {
|
||||||
if (small == NULL)
|
|
||||||
{
|
|
||||||
ERR(REG_ESPACE);
|
ERR(REG_ESPACE);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -303,36 +288,32 @@ newdfa(struct vars * v,
|
|||||||
d->outsarea = small->outsarea;
|
d->outsarea = small->outsarea;
|
||||||
d->incarea = small->incarea;
|
d->incarea = small->incarea;
|
||||||
d->cptsmalloced = 0;
|
d->cptsmalloced = 0;
|
||||||
d->mallocarea = (smallwas == NULL) ? (char *) small : NULL;
|
d->mallocarea = (smallwas == NULL) ? (char *)small : NULL;
|
||||||
}
|
} else {
|
||||||
else
|
d = (struct dfa *)MALLOC(sizeof(struct dfa));
|
||||||
{
|
if (d == NULL) {
|
||||||
d = (struct dfa *) MALLOC(sizeof(struct dfa));
|
|
||||||
if (d == NULL)
|
|
||||||
{
|
|
||||||
ERR(REG_ESPACE);
|
ERR(REG_ESPACE);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
d->ssets = (struct sset *) MALLOC(nss * sizeof(struct sset));
|
d->ssets = (struct sset *)MALLOC(nss * sizeof(struct sset));
|
||||||
d->statesarea = (unsigned *) MALLOC((nss + WORK) * wordsper *
|
d->statesarea = (unsigned *)MALLOC((nss+WORK) * wordsper *
|
||||||
sizeof(unsigned));
|
sizeof(unsigned));
|
||||||
d->work = &d->statesarea[nss * wordsper];
|
d->work = &d->statesarea[nss * wordsper];
|
||||||
d->outsarea = (struct sset **) MALLOC(nss * cnfa->ncolors *
|
d->outsarea = (struct sset **)MALLOC(nss * cnfa->ncolors *
|
||||||
sizeof(struct sset *));
|
sizeof(struct sset *));
|
||||||
d->incarea = (struct arcp *) MALLOC(nss * cnfa->ncolors *
|
d->incarea = (struct arcp *)MALLOC(nss * cnfa->ncolors *
|
||||||
sizeof(struct arcp));
|
sizeof(struct arcp));
|
||||||
d->cptsmalloced = 1;
|
d->cptsmalloced = 1;
|
||||||
d->mallocarea = (char *) d;
|
d->mallocarea = (char *)d;
|
||||||
if (d->ssets == NULL || d->statesarea == NULL ||
|
if (d->ssets == NULL || d->statesarea == NULL ||
|
||||||
d->outsarea == NULL || d->incarea == NULL)
|
d->outsarea == NULL || d->incarea == NULL) {
|
||||||
{
|
|
||||||
freedfa(d);
|
freedfa(d);
|
||||||
ERR(REG_ESPACE);
|
ERR(REG_ESPACE);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
d->nssets = (v->eflags & REG_SMALL) ? 7 : nss;
|
d->nssets = (v->eflags®_SMALL) ? 7 : nss;
|
||||||
d->nssused = 0;
|
d->nssused = 0;
|
||||||
d->nstates = cnfa->nstates;
|
d->nstates = cnfa->nstates;
|
||||||
d->ncolors = cnfa->ncolors;
|
d->ncolors = cnfa->ncolors;
|
||||||
@@ -349,13 +330,14 @@ newdfa(struct vars * v,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* freedfa - free a DFA
|
- freedfa - free a DFA
|
||||||
|
^ static VOID freedfa(struct dfa *);
|
||||||
*/
|
*/
|
||||||
static void
|
static VOID
|
||||||
freedfa(struct dfa * d)
|
freedfa(d)
|
||||||
|
struct dfa *d;
|
||||||
{
|
{
|
||||||
if (d->cptsmalloced)
|
if (d->cptsmalloced) {
|
||||||
{
|
|
||||||
if (d->ssets != NULL)
|
if (d->ssets != NULL)
|
||||||
FREE(d->ssets);
|
FREE(d->ssets);
|
||||||
if (d->statesarea != NULL)
|
if (d->statesarea != NULL)
|
||||||
@@ -371,16 +353,17 @@ freedfa(struct dfa * d)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* hash - construct a hash code for a bitvector
|
- hash - construct a hash code for a bitvector
|
||||||
*
|
|
||||||
* There are probably better ways, but they're more expensive.
|
* There are probably better ways, but they're more expensive.
|
||||||
|
^ static unsigned hash(unsigned *, int);
|
||||||
*/
|
*/
|
||||||
static unsigned
|
static unsigned
|
||||||
hash(unsigned *uv,
|
hash(uv, n)
|
||||||
int n)
|
unsigned *uv;
|
||||||
|
int n;
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
unsigned h;
|
unsigned h;
|
||||||
|
|
||||||
h = 0;
|
h = 0;
|
||||||
for (i = 0; i < n; i++)
|
for (i = 0; i < n; i++)
|
||||||
@@ -389,28 +372,29 @@ hash(unsigned *uv,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* initialize - hand-craft a cache entry for startup, otherwise get ready
|
- initialize - hand-craft a cache entry for startup, otherwise get ready
|
||||||
|
^ static struct sset *initialize(struct vars *, struct dfa *, chr *);
|
||||||
*/
|
*/
|
||||||
static struct sset *
|
static struct sset *
|
||||||
initialize(struct vars * v, /* used only for debug flags */
|
initialize(v, d, start)
|
||||||
struct dfa * d,
|
struct vars *v; /* used only for debug flags */
|
||||||
chr *start)
|
struct dfa *d;
|
||||||
|
chr *start;
|
||||||
{
|
{
|
||||||
struct sset *ss;
|
struct sset *ss;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* is previous one still there? */
|
/* is previous one still there? */
|
||||||
if (d->nssused > 0 && (d->ssets[0].flags & STARTER))
|
if (d->nssused > 0 && (d->ssets[0].flags&STARTER))
|
||||||
ss = &d->ssets[0];
|
ss = &d->ssets[0];
|
||||||
else
|
else { /* no, must (re)build it */
|
||||||
{ /* no, must (re)build it */
|
|
||||||
ss = getvacant(v, d, start, start);
|
ss = getvacant(v, d, start, start);
|
||||||
for (i = 0; i < d->wordsper; i++)
|
for (i = 0; i < d->wordsper; i++)
|
||||||
ss->states[i] = 0;
|
ss->states[i] = 0;
|
||||||
BSET(ss->states, d->cnfa->pre);
|
BSET(ss->states, d->cnfa->pre);
|
||||||
ss->hash = HASH(ss->states, d->wordsper);
|
ss->hash = HASH(ss->states, d->wordsper);
|
||||||
assert(d->cnfa->pre != d->cnfa->post);
|
assert(d->cnfa->pre != d->cnfa->post);
|
||||||
ss->flags = STARTER | LOCKED | NOPROGRESS;
|
ss->flags = STARTER|LOCKED|NOPROGRESS;
|
||||||
/* lastseen dealt with below */
|
/* lastseen dealt with below */
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -423,30 +407,32 @@ initialize(struct vars * v, /* used only for debug flags */
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* miss - handle a cache miss
|
- miss - handle a cache miss
|
||||||
|
^ static struct sset *miss(struct vars *, struct dfa *, struct sset *,
|
||||||
|
^ pcolor, chr *, chr *);
|
||||||
*/
|
*/
|
||||||
static struct sset * /* NULL if goes to empty set */
|
static struct sset * /* NULL if goes to empty set */
|
||||||
miss(struct vars * v, /* used only for debug flags */
|
miss(v, d, css, co, cp, start)
|
||||||
struct dfa * d,
|
struct vars *v; /* used only for debug flags */
|
||||||
struct sset * css,
|
struct dfa *d;
|
||||||
pcolor co,
|
struct sset *css;
|
||||||
chr *cp, /* next chr */
|
pcolor co;
|
||||||
chr *start) /* where the attempt got started */
|
chr *cp; /* next chr */
|
||||||
|
chr *start; /* where the attempt got started */
|
||||||
{
|
{
|
||||||
struct cnfa *cnfa = d->cnfa;
|
struct cnfa *cnfa = d->cnfa;
|
||||||
int i;
|
int i;
|
||||||
unsigned h;
|
unsigned h;
|
||||||
struct carc *ca;
|
struct carc *ca;
|
||||||
struct sset *p;
|
struct sset *p;
|
||||||
int ispost;
|
int ispost;
|
||||||
int noprogress;
|
int noprogress;
|
||||||
int gotstate;
|
int gotstate;
|
||||||
int dolacons;
|
int dolacons;
|
||||||
int sawlacons;
|
int sawlacons;
|
||||||
|
|
||||||
/* for convenience, we can be called even if it might not be a miss */
|
/* for convenience, we can be called even if it might not be a miss */
|
||||||
if (css->outs[co] != NULL)
|
if (css->outs[co] != NULL) {
|
||||||
{
|
|
||||||
FDEBUG(("hit\n"));
|
FDEBUG(("hit\n"));
|
||||||
return css->outs[co];
|
return css->outs[co];
|
||||||
}
|
}
|
||||||
@@ -460,9 +446,8 @@ miss(struct vars * v, /* used only for debug flags */
|
|||||||
gotstate = 0;
|
gotstate = 0;
|
||||||
for (i = 0; i < d->nstates; i++)
|
for (i = 0; i < d->nstates; i++)
|
||||||
if (ISBSET(css->states, i))
|
if (ISBSET(css->states, i))
|
||||||
for (ca = cnfa->states[i] + 1; ca->co != COLORLESS; ca++)
|
for (ca = cnfa->states[i]+1; ca->co != COLORLESS; ca++)
|
||||||
if (ca->co == co)
|
if (ca->co == co) {
|
||||||
{
|
|
||||||
BSET(d->work, ca->to);
|
BSET(d->work, ca->to);
|
||||||
gotstate = 1;
|
gotstate = 1;
|
||||||
if (ca->to == cnfa->post)
|
if (ca->to == cnfa->post)
|
||||||
@@ -471,23 +456,21 @@ miss(struct vars * v, /* used only for debug flags */
|
|||||||
noprogress = 0;
|
noprogress = 0;
|
||||||
FDEBUG(("%d -> %d\n", i, ca->to));
|
FDEBUG(("%d -> %d\n", i, ca->to));
|
||||||
}
|
}
|
||||||
dolacons = (gotstate) ? (cnfa->flags & HASLACONS) : 0;
|
dolacons = (gotstate) ? (cnfa->flags&HASLACONS) : 0;
|
||||||
sawlacons = 0;
|
sawlacons = 0;
|
||||||
while (dolacons)
|
while (dolacons) { /* transitive closure */
|
||||||
{ /* transitive closure */
|
|
||||||
dolacons = 0;
|
dolacons = 0;
|
||||||
for (i = 0; i < d->nstates; i++)
|
for (i = 0; i < d->nstates; i++)
|
||||||
if (ISBSET(d->work, i))
|
if (ISBSET(d->work, i))
|
||||||
for (ca = cnfa->states[i] + 1; ca->co != COLORLESS;
|
for (ca = cnfa->states[i]+1; ca->co != COLORLESS;
|
||||||
ca++)
|
ca++) {
|
||||||
{
|
|
||||||
if (ca->co <= cnfa->ncolors)
|
if (ca->co <= cnfa->ncolors)
|
||||||
continue; /* NOTE CONTINUE */
|
continue; /* NOTE CONTINUE */
|
||||||
sawlacons = 1;
|
sawlacons = 1;
|
||||||
if (ISBSET(d->work, ca->to))
|
if (ISBSET(d->work, ca->to))
|
||||||
continue; /* NOTE CONTINUE */
|
continue; /* NOTE CONTINUE */
|
||||||
if (!lacon(v, cnfa, cp, ca->co))
|
if (!lacon(v, cnfa, cp, ca->co))
|
||||||
continue; /* NOTE CONTINUE */
|
continue; /* NOTE CONTINUE */
|
||||||
BSET(d->work, ca->to);
|
BSET(d->work, ca->to);
|
||||||
dolacons = 1;
|
dolacons = 1;
|
||||||
if (ca->to == cnfa->post)
|
if (ca->to == cnfa->post)
|
||||||
@@ -503,13 +486,11 @@ miss(struct vars * v, /* used only for debug flags */
|
|||||||
|
|
||||||
/* next, is that in the cache? */
|
/* next, is that in the cache? */
|
||||||
for (p = d->ssets, i = d->nssused; i > 0; p++, i--)
|
for (p = d->ssets, i = d->nssused; i > 0; p++, i--)
|
||||||
if (HIT(h, d->work, p, d->wordsper))
|
if (HIT(h, d->work, p, d->wordsper)) {
|
||||||
{
|
|
||||||
FDEBUG(("cached c%d\n", p - d->ssets));
|
FDEBUG(("cached c%d\n", p - d->ssets));
|
||||||
break; /* NOTE BREAK OUT */
|
break; /* NOTE BREAK OUT */
|
||||||
}
|
}
|
||||||
if (i == 0)
|
if (i == 0) { /* nope, need a new cache entry */
|
||||||
{ /* nope, need a new cache entry */
|
|
||||||
p = getvacant(v, d, cp, start);
|
p = getvacant(v, d, cp, start);
|
||||||
assert(p != css);
|
assert(p != css);
|
||||||
for (i = 0; i < d->wordsper; i++)
|
for (i = 0; i < d->wordsper; i++)
|
||||||
@@ -521,97 +502,96 @@ miss(struct vars * v, /* used only for debug flags */
|
|||||||
/* lastseen to be dealt with by caller */
|
/* lastseen to be dealt with by caller */
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!sawlacons)
|
if (!sawlacons) { /* lookahead conds. always cache miss */
|
||||||
{ /* lookahead conds. always cache miss */
|
|
||||||
FDEBUG(("c%d[%d]->c%d\n", css - d->ssets, co, p - d->ssets));
|
FDEBUG(("c%d[%d]->c%d\n", css - d->ssets, co, p - d->ssets));
|
||||||
css->outs[co] = p;
|
css->outs[co] = p;
|
||||||
css->inchain[co] = p->ins;
|
css->inchain[co] = p->ins;
|
||||||
p->ins.ss = css;
|
p->ins.ss = css;
|
||||||
p->ins.co = (color) co;
|
p->ins.co = (color)co;
|
||||||
}
|
}
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* lacon - lookahead-constraint checker for miss()
|
- lacon - lookahead-constraint checker for miss()
|
||||||
|
^ static int lacon(struct vars *, struct cnfa *, chr *, pcolor);
|
||||||
*/
|
*/
|
||||||
static int /* predicate: constraint satisfied? */
|
static int /* predicate: constraint satisfied? */
|
||||||
lacon(struct vars * v,
|
lacon(v, pcnfa, cp, co)
|
||||||
struct cnfa * pcnfa, /* parent cnfa */
|
struct vars *v;
|
||||||
chr *cp,
|
struct cnfa *pcnfa; /* parent cnfa */
|
||||||
pcolor co) /* "color" of the lookahead constraint */
|
chr *cp;
|
||||||
|
pcolor co; /* "color" of the lookahead constraint */
|
||||||
{
|
{
|
||||||
int n;
|
int n;
|
||||||
struct subre *sub;
|
struct subre *sub;
|
||||||
struct dfa *d;
|
struct dfa *d;
|
||||||
struct smalldfa sd;
|
struct smalldfa sd;
|
||||||
chr *end;
|
chr *end;
|
||||||
|
|
||||||
n = co - pcnfa->ncolors;
|
n = co - pcnfa->ncolors;
|
||||||
assert(n < v->g->nlacons && v->g->lacons != NULL);
|
assert(n < v->g->nlacons && v->g->lacons != NULL);
|
||||||
FDEBUG(("=== testing lacon %d\n", n));
|
FDEBUG(("=== testing lacon %d\n", n));
|
||||||
sub = &v->g->lacons[n];
|
sub = &v->g->lacons[n];
|
||||||
d = newdfa(v, &sub->cnfa, &v->g->cmap, &sd);
|
d = newdfa(v, &sub->cnfa, &v->g->cmap, &sd);
|
||||||
if (d == NULL)
|
if (d == NULL) {
|
||||||
{
|
|
||||||
ERR(REG_ESPACE);
|
ERR(REG_ESPACE);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
end = longest(v, d, cp, v->stop, (int *) NULL);
|
end = longest(v, d, cp, v->stop, (int *)NULL);
|
||||||
freedfa(d);
|
freedfa(d);
|
||||||
FDEBUG(("=== lacon %d match %d\n", n, (end != NULL)));
|
FDEBUG(("=== lacon %d match %d\n", n, (end != NULL)));
|
||||||
return (sub->subno) ? (end != NULL) : (end == NULL);
|
return (sub->subno) ? (end != NULL) : (end == NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* getvacant - get a vacant state set
|
- getvacant - get a vacant state set
|
||||||
* This routine clears out the inarcs and outarcs, but does not otherwise
|
* This routine clears out the inarcs and outarcs, but does not otherwise
|
||||||
* clear the innards of the state set -- that's up to the caller.
|
* clear the innards of the state set -- that's up to the caller.
|
||||||
|
^ static struct sset *getvacant(struct vars *, struct dfa *, chr *, chr *);
|
||||||
*/
|
*/
|
||||||
static struct sset *
|
static struct sset *
|
||||||
getvacant(struct vars * v, /* used only for debug flags */
|
getvacant(v, d, cp, start)
|
||||||
struct dfa * d,
|
struct vars *v; /* used only for debug flags */
|
||||||
chr *cp,
|
struct dfa *d;
|
||||||
chr *start)
|
chr *cp;
|
||||||
|
chr *start;
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
struct sset *ss;
|
struct sset *ss;
|
||||||
struct sset *p;
|
struct sset *p;
|
||||||
struct arcp ap;
|
struct arcp ap;
|
||||||
struct arcp lastap;
|
struct arcp lastap;
|
||||||
color co;
|
color co;
|
||||||
|
|
||||||
ss = pickss(v, d, cp, start);
|
ss = pickss(v, d, cp, start);
|
||||||
assert(!(ss->flags & LOCKED));
|
assert(!(ss->flags&LOCKED));
|
||||||
|
|
||||||
/* clear out its inarcs, including self-referential ones */
|
/* clear out its inarcs, including self-referential ones */
|
||||||
ap = ss->ins;
|
ap = ss->ins;
|
||||||
while ((p = ap.ss) != NULL)
|
while ((p = ap.ss) != NULL) {
|
||||||
{
|
|
||||||
co = ap.co;
|
co = ap.co;
|
||||||
FDEBUG(("zapping c%d's %ld outarc\n", p - d->ssets, (long) co));
|
FDEBUG(("zapping c%d's %ld outarc\n", p - d->ssets, (long)co));
|
||||||
p->outs[co] = NULL;
|
p->outs[co] = NULL;
|
||||||
ap = p->inchain[co];
|
ap = p->inchain[co];
|
||||||
p->inchain[co].ss = NULL; /* paranoia */
|
p->inchain[co].ss = NULL; /* paranoia */
|
||||||
}
|
}
|
||||||
ss->ins.ss = NULL;
|
ss->ins.ss = NULL;
|
||||||
|
|
||||||
/* take it off the inarc chains of the ssets reached by its outarcs */
|
/* take it off the inarc chains of the ssets reached by its outarcs */
|
||||||
for (i = 0; i < d->ncolors; i++)
|
for (i = 0; i < d->ncolors; i++) {
|
||||||
{
|
|
||||||
p = ss->outs[i];
|
p = ss->outs[i];
|
||||||
assert(p != ss); /* not self-referential */
|
assert(p != ss); /* not self-referential */
|
||||||
if (p == NULL)
|
if (p == NULL)
|
||||||
continue; /* NOTE CONTINUE */
|
continue; /* NOTE CONTINUE */
|
||||||
FDEBUG(("del outarc %d from c%d's in chn\n", i, p - d->ssets));
|
FDEBUG(("del outarc %d from c%d's in chn\n", i, p - d->ssets));
|
||||||
if (p->ins.ss == ss && p->ins.co == i)
|
if (p->ins.ss == ss && p->ins.co == i)
|
||||||
p->ins = ss->inchain[i];
|
p->ins = ss->inchain[i];
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
assert(p->ins.ss != NULL);
|
assert(p->ins.ss != NULL);
|
||||||
for (ap = p->ins; ap.ss != NULL &&
|
for (ap = p->ins; ap.ss != NULL &&
|
||||||
!(ap.ss == ss && ap.co == i);
|
!(ap.ss == ss && ap.co == i);
|
||||||
ap = ap.ss->inchain[ap.co])
|
ap = ap.ss->inchain[ap.co])
|
||||||
lastap = ap;
|
lastap = ap;
|
||||||
assert(ap.ss != NULL);
|
assert(ap.ss != NULL);
|
||||||
lastap.ss->inchain[lastap.co] = ss->inchain[i];
|
lastap.ss->inchain[lastap.co] = ss->inchain[i];
|
||||||
@@ -621,35 +601,36 @@ getvacant(struct vars * v, /* used only for debug flags */
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* if ss was a success state, may need to remember location */
|
/* if ss was a success state, may need to remember location */
|
||||||
if ((ss->flags & POSTSTATE) && ss->lastseen != d->lastpost &&
|
if ((ss->flags&POSTSTATE) && ss->lastseen != d->lastpost &&
|
||||||
(d->lastpost == NULL || d->lastpost < ss->lastseen))
|
(d->lastpost == NULL || d->lastpost < ss->lastseen))
|
||||||
d->lastpost = ss->lastseen;
|
d->lastpost = ss->lastseen;
|
||||||
|
|
||||||
/* likewise for a no-progress state */
|
/* likewise for a no-progress state */
|
||||||
if ((ss->flags & NOPROGRESS) && ss->lastseen != d->lastnopr &&
|
if ((ss->flags&NOPROGRESS) && ss->lastseen != d->lastnopr &&
|
||||||
(d->lastnopr == NULL || d->lastnopr < ss->lastseen))
|
(d->lastnopr == NULL || d->lastnopr < ss->lastseen))
|
||||||
d->lastnopr = ss->lastseen;
|
d->lastnopr = ss->lastseen;
|
||||||
|
|
||||||
return ss;
|
return ss;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* pickss - pick the next stateset to be used
|
- pickss - pick the next stateset to be used
|
||||||
|
^ static struct sset *pickss(struct vars *, struct dfa *, chr *, chr *);
|
||||||
*/
|
*/
|
||||||
static struct sset *
|
static struct sset *
|
||||||
pickss(struct vars * v, /* used only for debug flags */
|
pickss(v, d, cp, start)
|
||||||
struct dfa * d,
|
struct vars *v; /* used only for debug flags */
|
||||||
chr *cp,
|
struct dfa *d;
|
||||||
chr *start)
|
chr *cp;
|
||||||
|
chr *start;
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
struct sset *ss;
|
struct sset *ss;
|
||||||
struct sset *end;
|
struct sset *end;
|
||||||
chr *ancient;
|
chr *ancient;
|
||||||
|
|
||||||
/* shortcut for cases where cache isn't full */
|
/* shortcut for cases where cache isn't full */
|
||||||
if (d->nssused < d->nssets)
|
if (d->nssused < d->nssets) {
|
||||||
{
|
|
||||||
i = d->nssused;
|
i = d->nssused;
|
||||||
d->nssused++;
|
d->nssused++;
|
||||||
ss = &d->ssets[i];
|
ss = &d->ssets[i];
|
||||||
@@ -661,8 +642,7 @@ pickss(struct vars * v, /* used only for debug flags */
|
|||||||
ss->ins.co = WHITE; /* give it some value */
|
ss->ins.co = WHITE; /* give it some value */
|
||||||
ss->outs = &d->outsarea[i * d->ncolors];
|
ss->outs = &d->outsarea[i * d->ncolors];
|
||||||
ss->inchain = &d->incarea[i * d->ncolors];
|
ss->inchain = &d->incarea[i * d->ncolors];
|
||||||
for (i = 0; i < d->ncolors; i++)
|
for (i = 0; i < d->ncolors; i++) {
|
||||||
{
|
|
||||||
ss->outs[i] = NULL;
|
ss->outs[i] = NULL;
|
||||||
ss->inchain[i].ss = NULL;
|
ss->inchain[i].ss = NULL;
|
||||||
}
|
}
|
||||||
@@ -670,22 +650,20 @@ pickss(struct vars * v, /* used only for debug flags */
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* look for oldest, or old enough anyway */
|
/* look for oldest, or old enough anyway */
|
||||||
if (cp - start > d->nssets * 2 / 3) /* oldest 33% are expendable */
|
if (cp - start > d->nssets*2/3) /* oldest 33% are expendable */
|
||||||
ancient = cp - d->nssets * 2 / 3;
|
ancient = cp - d->nssets*2/3;
|
||||||
else
|
else
|
||||||
ancient = start;
|
ancient = start;
|
||||||
for (ss = d->search, end = &d->ssets[d->nssets]; ss < end; ss++)
|
for (ss = d->search, end = &d->ssets[d->nssets]; ss < end; ss++)
|
||||||
if ((ss->lastseen == NULL || ss->lastseen < ancient) &&
|
if ((ss->lastseen == NULL || ss->lastseen < ancient) &&
|
||||||
!(ss->flags & LOCKED))
|
!(ss->flags&LOCKED)) {
|
||||||
{
|
|
||||||
d->search = ss + 1;
|
d->search = ss + 1;
|
||||||
FDEBUG(("replacing c%d\n", ss - d->ssets));
|
FDEBUG(("replacing c%d\n", ss - d->ssets));
|
||||||
return ss;
|
return ss;
|
||||||
}
|
}
|
||||||
for (ss = d->ssets, end = d->search; ss < end; ss++)
|
for (ss = d->ssets, end = d->search; ss < end; ss++)
|
||||||
if ((ss->lastseen == NULL || ss->lastseen < ancient) &&
|
if ((ss->lastseen == NULL || ss->lastseen < ancient) &&
|
||||||
!(ss->flags & LOCKED))
|
!(ss->flags&LOCKED)) {
|
||||||
{
|
|
||||||
d->search = ss + 1;
|
d->search = ss + 1;
|
||||||
FDEBUG(("replacing c%d\n", ss - d->ssets));
|
FDEBUG(("replacing c%d\n", ss - d->ssets));
|
||||||
return ss;
|
return ss;
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* regerror - error-code expansion
|
* regerror - error-code expansion
|
||||||
*
|
*
|
||||||
* Copyright (c) 1998, 1999 Henry Spencer. All rights reserved.
|
* Copyright (c) 1998, 1999 Henry Spencer. All rights reserved.
|
||||||
*
|
*
|
||||||
* Development of this software was funded, in part, by Cray Research Inc.,
|
* Development of this software was funded, in part, by Cray Research Inc.,
|
||||||
* UUNET Communications Services Inc., Sun Microsystems Inc., and Scriptics
|
* UUNET Communications Services Inc., Sun Microsystems Inc., and Scriptics
|
||||||
@@ -27,8 +27,6 @@
|
|||||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $Header: /projects/cvsroot/pgsql-server/src/backend/regex/regerror.c,v 1.26 2003/08/04 00:43:21 momjian Exp $
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "regguts.h"
|
#include "regguts.h"
|
||||||
@@ -37,88 +35,73 @@
|
|||||||
static char unk[] = "*** unknown regex error code 0x%x ***";
|
static char unk[] = "*** unknown regex error code 0x%x ***";
|
||||||
|
|
||||||
/* struct to map among codes, code names, and explanations */
|
/* struct to map among codes, code names, and explanations */
|
||||||
static struct rerr
|
static struct rerr {
|
||||||
{
|
|
||||||
int code;
|
int code;
|
||||||
char *name;
|
char *name;
|
||||||
char *explain;
|
char *explain;
|
||||||
} rerrs[] =
|
} rerrs[] = {
|
||||||
|
|
||||||
{
|
|
||||||
/* the actual table is built from regex.h */
|
/* the actual table is built from regex.h */
|
||||||
#include "regerrs.h"
|
# include "regerrs.h"
|
||||||
{
|
{ -1, "", "oops" }, /* explanation special-cased in code */
|
||||||
-1, "", "oops"
|
|
||||||
}, /* explanation special-cased in code */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
size_t
|
|
||||||
regerror(int errcode, /* error code, or REG_ATOI or REG_ITOA */
|
|
||||||
const regex_t *preg, /* associated regex_t (unused at present) */
|
|
||||||
char *errbuf, /* result buffer (unless errbuf_size==0) */
|
|
||||||
size_t errbuf_size) /* available space in errbuf, can be 0 */
|
|
||||||
{ return wx_regerror(errcode, preg, errbuf, errbuf_size); }
|
|
||||||
/*
|
/*
|
||||||
* pg_regerror - the interface to error numbers
|
- regerror - the interface to error numbers
|
||||||
*/
|
*/
|
||||||
/* ARGSUSED */
|
/* ARGSUSED */
|
||||||
size_t /* actual space needed (including NUL) */
|
size_t /* actual space needed (including NUL) */
|
||||||
wx_regerror(int errcode, /* error code, or REG_ATOI or REG_ITOA */
|
regerror(errcode, preg, errbuf, errbuf_size)
|
||||||
const regex_t *preg, /* associated regex_t (unused at present) */
|
int errcode; /* error code, or REG_ATOI or REG_ITOA */
|
||||||
char *errbuf, /* result buffer (unless errbuf_size==0) */
|
CONST regex_t *preg; /* associated regex_t (unused at present) */
|
||||||
size_t errbuf_size) /* available space in errbuf, can be 0 */
|
char *errbuf; /* result buffer (unless errbuf_size==0) */
|
||||||
|
size_t errbuf_size; /* available space in errbuf, can be 0 */
|
||||||
{
|
{
|
||||||
struct rerr *r;
|
struct rerr *r;
|
||||||
char *msg;
|
char *msg;
|
||||||
char convbuf[sizeof(unk) + 50]; /* 50 = plenty for int */
|
char convbuf[sizeof(unk)+50]; /* 50 = plenty for int */
|
||||||
size_t len;
|
size_t len;
|
||||||
int icode;
|
int icode;
|
||||||
|
|
||||||
switch (errcode)
|
switch (errcode) {
|
||||||
{
|
case REG_ATOI: /* convert name to number */
|
||||||
case REG_ATOI: /* convert name to number */
|
|
||||||
for (r = rerrs; r->code >= 0; r++)
|
for (r = rerrs; r->code >= 0; r++)
|
||||||
if (strcmp(r->name, errbuf) == 0)
|
if (strcmp(r->name, errbuf) == 0)
|
||||||
break;
|
break;
|
||||||
sprintf(convbuf, "%d", r->code); /* -1 for unknown */
|
sprintf(convbuf, "%d", r->code); /* -1 for unknown */
|
||||||
|
msg = convbuf;
|
||||||
|
break;
|
||||||
|
case REG_ITOA: /* convert number to name */
|
||||||
|
icode = atoi(errbuf); /* not our problem if this fails */
|
||||||
|
for (r = rerrs; r->code >= 0; r++)
|
||||||
|
if (r->code == icode)
|
||||||
|
break;
|
||||||
|
if (r->code >= 0)
|
||||||
|
msg = r->name;
|
||||||
|
else { /* unknown; tell him the number */
|
||||||
|
sprintf(convbuf, "REG_%u", (unsigned)icode);
|
||||||
msg = convbuf;
|
msg = convbuf;
|
||||||
break;
|
}
|
||||||
case REG_ITOA: /* convert number to name */
|
break;
|
||||||
icode = atoi(errbuf); /* not our problem if this fails */
|
default: /* a real, normal error code */
|
||||||
for (r = rerrs; r->code >= 0; r++)
|
for (r = rerrs; r->code >= 0; r++)
|
||||||
if (r->code == icode)
|
if (r->code == errcode)
|
||||||
break;
|
break;
|
||||||
if (r->code >= 0)
|
if (r->code >= 0)
|
||||||
msg = r->name;
|
msg = r->explain;
|
||||||
else
|
else { /* unknown; say so */
|
||||||
{ /* unknown; tell him the number */
|
sprintf(convbuf, unk, errcode);
|
||||||
sprintf(convbuf, "REG_%u", (unsigned) icode);
|
msg = convbuf;
|
||||||
msg = convbuf;
|
}
|
||||||
}
|
break;
|
||||||
break;
|
|
||||||
default: /* a real, normal error code */
|
|
||||||
for (r = rerrs; r->code >= 0; r++)
|
|
||||||
if (r->code == errcode)
|
|
||||||
break;
|
|
||||||
if (r->code >= 0)
|
|
||||||
msg = r->explain;
|
|
||||||
else
|
|
||||||
{ /* unknown; say so */
|
|
||||||
sprintf(convbuf, unk, errcode);
|
|
||||||
msg = convbuf;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
len = strlen(msg) + 1; /* space needed, including NUL */
|
len = strlen(msg) + 1; /* space needed, including NUL */
|
||||||
if (errbuf_size > 0)
|
if (errbuf_size > 0) {
|
||||||
{
|
|
||||||
if (errbuf_size > len)
|
if (errbuf_size > len)
|
||||||
strcpy(errbuf, msg);
|
strcpy(errbuf, msg);
|
||||||
else
|
else { /* truncate to fit */
|
||||||
{ /* truncate to fit */
|
strncpy(errbuf, msg, errbuf_size-1);
|
||||||
memcpy(errbuf, msg, errbuf_size - 1); /*RN - was strncpy*/
|
errbuf[errbuf_size-1] = '\0';
|
||||||
errbuf[errbuf_size - 1] = '\0';
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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"
|
|
||||||
},
|
|
||||||
|
@@ -1,10 +1,9 @@
|
|||||||
#ifndef _REGEX_H_
|
#ifndef _REGEX_H_
|
||||||
#define _REGEX_H_ /* never again */
|
#define _REGEX_H_ /* never again */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* regular expressions
|
* regular expressions
|
||||||
*
|
*
|
||||||
* Copyright (c) 1998, 1999 Henry Spencer. All rights reserved.
|
* Copyright (c) 1998, 1999 Henry Spencer. All rights reserved.
|
||||||
*
|
*
|
||||||
* Development of this software was funded, in part, by Cray Research Inc.,
|
* Development of this software was funded, in part, by Cray Research Inc.,
|
||||||
* UUNET Communications Services Inc., Sun Microsystems Inc., and Scriptics
|
* UUNET Communications Services Inc., Sun Microsystems Inc., and Scriptics
|
||||||
@@ -30,35 +29,98 @@
|
|||||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $Id$
|
*
|
||||||
|
*
|
||||||
|
* Prototypes etc. marked with "^" within comments get gathered up (and
|
||||||
|
* possibly edited) by the regfwd program and inserted near the bottom of
|
||||||
|
* this file.
|
||||||
|
*
|
||||||
|
* We offer the option of declaring one wide-character version of the
|
||||||
|
* RE functions as well as the char versions. To do that, define
|
||||||
|
* __REG_WIDE_T to the type of wide characters (unfortunately, there
|
||||||
|
* is no consensus that wchar_t is suitable) and __REG_WIDE_COMPILE and
|
||||||
|
* __REG_WIDE_EXEC to the names to be used for the compile and execute
|
||||||
|
* functions (suggestion: re_Xcomp and re_Xexec, where X is a letter
|
||||||
|
* suggestive of the wide type, e.g. re_ucomp and re_uexec for Unicode).
|
||||||
|
* For cranky old compilers, it may be necessary to do something like:
|
||||||
|
* #define __REG_WIDE_COMPILE(a,b,c,d) re_Xcomp(a,b,c,d)
|
||||||
|
* #define __REG_WIDE_EXEC(a,b,c,d,e,f,g) re_Xexec(a,b,c,d,e,f,g)
|
||||||
|
* rather than just #defining the names as parameterless macros.
|
||||||
|
*
|
||||||
|
* For some specialized purposes, it may be desirable to suppress the
|
||||||
|
* declarations of the "front end" functions, regcomp() and regexec(),
|
||||||
|
* or of the char versions of the compile and execute functions. To
|
||||||
|
* suppress the front-end functions, define __REG_NOFRONT. To suppress
|
||||||
|
* the char versions, define __REG_NOCHAR.
|
||||||
|
*
|
||||||
|
* The right place to do those defines (and some others you may want, see
|
||||||
|
* below) would be <sys/types.h>. If you don't have control of that file,
|
||||||
|
* the right place to add your own defines to this file is marked below.
|
||||||
|
* This is normally done automatically, by the makefile and regmkhdr, based
|
||||||
|
* on the contents of regcustom.h.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Add your own defines, if needed, here.
|
* voodoo for C++
|
||||||
*/
|
*/
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*****************************
|
|
||||||
WXWINDOWS CUSTOM
|
|
||||||
*****************************/
|
|
||||||
#ifndef _REGEX_CUSTOM_H_
|
|
||||||
# define wx_wchar wxChar
|
|
||||||
/* FreeBSD, Watcom and DMars require this, CW doesn't have nor need it. */
|
|
||||||
/* Others also don't seem to need it. If you have an error related to */
|
|
||||||
/* (not) including <sys/types.h> please report details to */
|
|
||||||
/* wx-dev@lists.wxwindows.org */
|
|
||||||
# if defined(__UNIX__) || defined(__WATCOMC__) || defined(__DIGITALMARS__)
|
|
||||||
# include <sys/types.h>
|
|
||||||
# endif
|
|
||||||
#endif /* ndef _REGEX_CUSTOM_H_ */
|
|
||||||
/*****************************
|
|
||||||
END WXWINDOWS CUSTOM
|
|
||||||
*****************************/
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
/*
|
||||||
|
* Add your own defines, if needed, here.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Location where a chunk of regcustom.h is automatically spliced into
|
||||||
|
* this file (working from its prototype, regproto.h).
|
||||||
|
*/
|
||||||
|
/* --- begin --- */
|
||||||
|
/* ensure certain things don't sneak in from system headers */
|
||||||
|
#ifdef __REG_WIDE_T
|
||||||
|
#undef __REG_WIDE_T
|
||||||
|
#endif
|
||||||
|
#ifdef __REG_WIDE_COMPILE
|
||||||
|
#undef __REG_WIDE_COMPILE
|
||||||
|
#endif
|
||||||
|
#ifdef __REG_WIDE_EXEC
|
||||||
|
#undef __REG_WIDE_EXEC
|
||||||
|
#endif
|
||||||
|
#ifdef __REG_REGOFF_T
|
||||||
|
#undef __REG_REGOFF_T
|
||||||
|
#endif
|
||||||
|
#ifdef __REG_VOID_T
|
||||||
|
#undef __REG_VOID_T
|
||||||
|
#endif
|
||||||
|
#ifdef __REG_CONST
|
||||||
|
#undef __REG_CONST
|
||||||
|
#endif
|
||||||
|
#ifdef __REG_NOFRONT
|
||||||
|
#undef __REG_NOFRONT
|
||||||
|
#endif
|
||||||
|
#ifdef __REG_NOCHAR
|
||||||
|
#undef __REG_NOCHAR
|
||||||
|
#endif
|
||||||
|
/* interface types */
|
||||||
|
#define __REG_WIDE_T Tcl_UniChar
|
||||||
|
#define __REG_REGOFF_T long /* not really right, but good enough... */
|
||||||
|
#define __REG_VOID_T VOID
|
||||||
|
#define __REG_CONST CONST
|
||||||
|
/* names and declarations */
|
||||||
|
#define __REG_WIDE_COMPILE TclReComp
|
||||||
|
#define __REG_WIDE_EXEC TclReExec
|
||||||
|
#define __REG_NOFRONT /* don't want regcomp() and regexec() */
|
||||||
|
#define __REG_NOCHAR /* or the char versions */
|
||||||
|
#define regfree TclReFree
|
||||||
|
#define regerror TclReError
|
||||||
|
/* --- end --- */
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* interface types etc.
|
* interface types etc.
|
||||||
@@ -66,136 +128,214 @@ extern "C" {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* regoff_t has to be large enough to hold either off_t or ssize_t,
|
* regoff_t has to be large enough to hold either off_t or ssize_t,
|
||||||
* and must be signed; it's only a guess that long is suitable.
|
* and must be signed; it's only a guess that long is suitable, so we
|
||||||
|
* offer <sys/types.h> an override.
|
||||||
*/
|
*/
|
||||||
|
#ifdef __REG_REGOFF_T
|
||||||
|
typedef __REG_REGOFF_T regoff_t;
|
||||||
|
#else
|
||||||
typedef long regoff_t;
|
typedef long regoff_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For benefit of old compilers, we offer <sys/types.h> the option of
|
||||||
|
* overriding the `void' type used to declare nonexistent return types.
|
||||||
|
*/
|
||||||
|
#ifdef __REG_VOID_T
|
||||||
|
typedef __REG_VOID_T re_void;
|
||||||
|
#else
|
||||||
|
typedef void re_void;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Also for benefit of old compilers, <sys/types.h> can supply a macro
|
||||||
|
* which expands to a substitute for `const'.
|
||||||
|
*/
|
||||||
|
#ifndef __REG_CONST
|
||||||
|
#define __REG_CONST const
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* other interface types
|
* other interface types
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* the biggie, a compiled RE (or rather, a front end to same) */
|
/* the biggie, a compiled RE (or rather, a front end to same) */
|
||||||
typedef struct
|
typedef struct {
|
||||||
{
|
int re_magic; /* magic number */
|
||||||
int re_magic; /* magic number */
|
size_t re_nsub; /* number of subexpressions */
|
||||||
size_t re_nsub; /* number of subexpressions */
|
long re_info; /* information about RE */
|
||||||
long re_info; /* information about RE */
|
# define REG_UBACKREF 000001
|
||||||
#define REG_UBACKREF 000001
|
# define REG_ULOOKAHEAD 000002
|
||||||
#define REG_ULOOKAHEAD 000002
|
# define REG_UBOUNDS 000004
|
||||||
#define REG_UBOUNDS 000004
|
# define REG_UBRACES 000010
|
||||||
#define REG_UBRACES 000010
|
# define REG_UBSALNUM 000020
|
||||||
#define REG_UBSALNUM 000020
|
# define REG_UPBOTCH 000040
|
||||||
#define REG_UPBOTCH 000040
|
# define REG_UBBS 000100
|
||||||
#define REG_UBBS 000100
|
# define REG_UNONPOSIX 000200
|
||||||
#define REG_UNONPOSIX 000200
|
# define REG_UUNSPEC 000400
|
||||||
#define REG_UUNSPEC 000400
|
# define REG_UUNPORT 001000
|
||||||
#define REG_UUNPORT 001000
|
# define REG_ULOCALE 002000
|
||||||
#define REG_ULOCALE 002000
|
# define REG_UEMPTYMATCH 004000
|
||||||
#define REG_UEMPTYMATCH 004000
|
# define REG_UIMPOSSIBLE 010000
|
||||||
#define REG_UIMPOSSIBLE 010000
|
# define REG_USHORTEST 020000
|
||||||
#define REG_USHORTEST 020000
|
int re_csize; /* sizeof(character) */
|
||||||
int re_csize; /* sizeof(character) */
|
char *re_endp; /* backward compatibility kludge */
|
||||||
char *re_endp; /* backward compatibility kludge */
|
|
||||||
/* the rest is opaque pointers to hidden innards */
|
/* the rest is opaque pointers to hidden innards */
|
||||||
char *re_guts; /* `char *' is more portable than `void *' */
|
char *re_guts; /* `char *' is more portable than `void *' */
|
||||||
char *re_fns;
|
char *re_fns;
|
||||||
} regex_t;
|
} regex_t;
|
||||||
|
|
||||||
/* result reporting (may acquire more fields later) */
|
/* result reporting (may acquire more fields later) */
|
||||||
typedef struct
|
typedef struct {
|
||||||
{
|
regoff_t rm_so; /* start of substring */
|
||||||
regoff_t rm_so; /* start of substring */
|
regoff_t rm_eo; /* end of substring */
|
||||||
regoff_t rm_eo; /* end of substring */
|
|
||||||
} regmatch_t;
|
} regmatch_t;
|
||||||
|
|
||||||
/* supplementary control and reporting */
|
/* supplementary control and reporting */
|
||||||
typedef struct
|
typedef struct {
|
||||||
{
|
regmatch_t rm_extend; /* see REG_EXPECT */
|
||||||
regmatch_t rm_extend; /* see REG_EXPECT */
|
|
||||||
} rm_detail_t;
|
} rm_detail_t;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* regex compilation flags
|
* compilation
|
||||||
|
^ #ifndef __REG_NOCHAR
|
||||||
|
^ int re_comp(regex_t *, __REG_CONST char *, size_t, int);
|
||||||
|
^ #endif
|
||||||
|
^ #ifndef __REG_NOFRONT
|
||||||
|
^ int regcomp(regex_t *, __REG_CONST char *, int);
|
||||||
|
^ #endif
|
||||||
|
^ #ifdef __REG_WIDE_T
|
||||||
|
^ int __REG_WIDE_COMPILE(regex_t *, __REG_CONST __REG_WIDE_T *, size_t, int);
|
||||||
|
^ #endif
|
||||||
*/
|
*/
|
||||||
#define REG_BASIC 000000 /* BREs (convenience) */
|
#define REG_BASIC 000000 /* BREs (convenience) */
|
||||||
#define REG_EXTENDED 000001 /* EREs */
|
#define REG_EXTENDED 000001 /* EREs */
|
||||||
#define REG_ADVF 000002 /* advanced features in EREs */
|
#define REG_ADVF 000002 /* advanced features in EREs */
|
||||||
#define REG_ADVANCED 000003 /* AREs (which are also EREs) */
|
#define REG_ADVANCED 000003 /* AREs (which are also EREs) */
|
||||||
#define REG_QUOTE 000004 /* no special characters, none */
|
#define REG_QUOTE 000004 /* no special characters, none */
|
||||||
#define REG_NOSPEC REG_QUOTE /* historical synonym */
|
#define REG_NOSPEC REG_QUOTE /* historical synonym */
|
||||||
#define REG_ICASE 000010 /* ignore case */
|
#define REG_ICASE 000010 /* ignore case */
|
||||||
#define REG_NOSUB 000020 /* don't care about subexpressions */
|
#define REG_NOSUB 000020 /* don't care about subexpressions */
|
||||||
#define REG_EXPANDED 000040 /* expanded format, white space & comments */
|
#define REG_EXPANDED 000040 /* expanded format, white space & comments */
|
||||||
#define REG_NLSTOP 000100 /* \n doesn't match . or [^ ] */
|
#define REG_NLSTOP 000100 /* \n doesn't match . or [^ ] */
|
||||||
#define REG_NLANCH 000200 /* ^ matches after \n, $ before */
|
#define REG_NLANCH 000200 /* ^ matches after \n, $ before */
|
||||||
#define REG_NEWLINE 000300 /* newlines are line terminators */
|
#define REG_NEWLINE 000300 /* newlines are line terminators */
|
||||||
#define REG_PEND 000400 /* ugh -- backward-compatibility hack */
|
#define REG_PEND 000400 /* ugh -- backward-compatibility hack */
|
||||||
#define REG_EXPECT 001000 /* report details on partial/limited
|
#define REG_EXPECT 001000 /* report details on partial/limited matches */
|
||||||
* matches */
|
#define REG_BOSONLY 002000 /* temporary kludge for BOS-only matches */
|
||||||
#define REG_BOSONLY 002000 /* temporary kludge for BOS-only matches */
|
#define REG_DUMP 004000 /* none of your business :-) */
|
||||||
#define REG_DUMP 004000 /* none of your business :-) */
|
#define REG_FAKE 010000 /* none of your business :-) */
|
||||||
#define REG_FAKE 010000 /* none of your business :-) */
|
#define REG_PROGRESS 020000 /* none of your business :-) */
|
||||||
#define REG_PROGRESS 020000 /* none of your business :-) */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* regex execution flags
|
* execution
|
||||||
|
^ #ifndef __REG_NOCHAR
|
||||||
|
^ int re_exec(regex_t *, __REG_CONST char *, size_t,
|
||||||
|
^ rm_detail_t *, size_t, regmatch_t [], int);
|
||||||
|
^ #endif
|
||||||
|
^ #ifndef __REG_NOFRONT
|
||||||
|
^ int regexec(regex_t *, __REG_CONST char *, size_t, regmatch_t [], int);
|
||||||
|
^ #endif
|
||||||
|
^ #ifdef __REG_WIDE_T
|
||||||
|
^ int __REG_WIDE_EXEC(regex_t *, __REG_CONST __REG_WIDE_T *, size_t,
|
||||||
|
^ rm_detail_t *, size_t, regmatch_t [], int);
|
||||||
|
^ #endif
|
||||||
*/
|
*/
|
||||||
#define REG_NOTBOL 0001 /* BOS is not BOL */
|
#define REG_NOTBOL 0001 /* BOS is not BOL */
|
||||||
#define REG_NOTEOL 0002 /* EOS is not EOL */
|
#define REG_NOTEOL 0002 /* EOS is not EOL */
|
||||||
#define REG_STARTEND 0004 /* backward compatibility kludge */
|
#define REG_STARTEND 0004 /* backward compatibility kludge */
|
||||||
#define REG_FTRACE 0010 /* none of your business */
|
#define REG_FTRACE 0010 /* none of your business */
|
||||||
#define REG_MTRACE 0020 /* none of your business */
|
#define REG_MTRACE 0020 /* none of your business */
|
||||||
#define REG_SMALL 0040 /* none of your business */
|
#define REG_SMALL 0040 /* none of your business */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* misc generics (may be more functions here eventually)
|
||||||
|
^ re_void regfree(regex_t *);
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* error reporting
|
* error reporting
|
||||||
* Be careful if modifying the list of error codes -- the table used by
|
* Be careful if modifying the list of error codes -- the table used by
|
||||||
* regerror() is generated automatically from this file!
|
* regerror() is generated automatically from this file!
|
||||||
|
*
|
||||||
|
* Note that there is no wide-char variant of regerror at this time; what
|
||||||
|
* kind of character is used for error reports is independent of what kind
|
||||||
|
* is used in matching.
|
||||||
|
*
|
||||||
|
^ extern size_t regerror(int, __REG_CONST regex_t *, char *, size_t);
|
||||||
*/
|
*/
|
||||||
#define REG_OKAY 0 /* no errors detected */
|
#define REG_OKAY 0 /* no errors detected */
|
||||||
#define REG_NOMATCH 1 /* failed to match */
|
#define REG_NOMATCH 1 /* failed to match */
|
||||||
#define REG_BADPAT 2 /* invalid regexp */
|
#define REG_BADPAT 2 /* invalid regexp */
|
||||||
#define REG_ECOLLATE 3 /* invalid collating element */
|
#define REG_ECOLLATE 3 /* invalid collating element */
|
||||||
#define REG_ECTYPE 4 /* invalid character class */
|
#define REG_ECTYPE 4 /* invalid character class */
|
||||||
#define REG_EESCAPE 5 /* invalid escape \ sequence */
|
#define REG_EESCAPE 5 /* invalid escape \ sequence */
|
||||||
#define REG_ESUBREG 6 /* invalid backreference number */
|
#define REG_ESUBREG 6 /* invalid backreference number */
|
||||||
#define REG_EBRACK 7 /* brackets [] not balanced */
|
#define REG_EBRACK 7 /* brackets [] not balanced */
|
||||||
#define REG_EPAREN 8 /* parentheses () not balanced */
|
#define REG_EPAREN 8 /* parentheses () not balanced */
|
||||||
#define REG_EBRACE 9 /* braces {} not balanced */
|
#define REG_EBRACE 9 /* braces {} not balanced */
|
||||||
#define REG_BADBR 10 /* invalid repetition count(s) */
|
#define REG_BADBR 10 /* invalid repetition count(s) */
|
||||||
#define REG_ERANGE 11 /* invalid character range */
|
#define REG_ERANGE 11 /* invalid character range */
|
||||||
#define REG_ESPACE 12 /* out of memory */
|
#define REG_ESPACE 12 /* out of memory */
|
||||||
#define REG_BADRPT 13 /* quantifier operand invalid */
|
#define REG_BADRPT 13 /* quantifier operand invalid */
|
||||||
#define REG_ASSERT 15 /* "can't happen" -- you found a bug */
|
#define REG_ASSERT 15 /* "can't happen" -- you found a bug */
|
||||||
#define REG_INVARG 16 /* invalid argument to regex function */
|
#define REG_INVARG 16 /* invalid argument to regex function */
|
||||||
#define REG_MIXED 17 /* character widths of regex and string
|
#define REG_MIXED 17 /* character widths of regex and string differ */
|
||||||
* differ */
|
#define REG_BADOPT 18 /* invalid embedded option */
|
||||||
#define REG_BADOPT 18 /* invalid embedded option */
|
|
||||||
/* two specials for debugging and testing */
|
/* two specials for debugging and testing */
|
||||||
#define REG_ATOI 101 /* convert error-code name to number */
|
#define REG_ATOI 101 /* convert error-code name to number */
|
||||||
#define REG_ITOA 102 /* convert error-code number to name */
|
#define REG_ITOA 102 /* convert error-code number to name */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* the prototypes for exported functions
|
* the prototypes, as possibly munched by regfwd
|
||||||
*/
|
*/
|
||||||
extern int wx_regcomp(regex_t *, const wx_wchar *, size_t, int);
|
/* =====^!^===== begin forwards =====^!^===== */
|
||||||
extern int regcomp(regex_t *, const wx_wchar *, int);
|
/* automatically gathered by fwd; do not hand-edit */
|
||||||
extern int wx_regexec(regex_t *, const wx_wchar *, size_t, rm_detail_t *, size_t, regmatch_t[], int);
|
/* === regproto.h === */
|
||||||
extern int regexec(regex_t *, const wx_wchar *, size_t, regmatch_t[], int);
|
#ifndef __REG_NOCHAR
|
||||||
extern void regfree(regex_t *);
|
int re_comp _ANSI_ARGS_((regex_t *, __REG_CONST char *, size_t, int));
|
||||||
extern size_t regerror(int, const regex_t *, char *, size_t);
|
#endif
|
||||||
extern void wx_regfree(regex_t *);
|
#ifndef __REG_NOFRONT
|
||||||
extern size_t wx_regerror(int, const regex_t *, char *, size_t);
|
int regcomp _ANSI_ARGS_((regex_t *, __REG_CONST char *, int));
|
||||||
|
#endif
|
||||||
|
#ifdef __REG_WIDE_T
|
||||||
|
int __REG_WIDE_COMPILE _ANSI_ARGS_((regex_t *, __REG_CONST __REG_WIDE_T *, size_t, int));
|
||||||
|
#endif
|
||||||
|
#ifndef __REG_NOCHAR
|
||||||
|
int re_exec _ANSI_ARGS_((regex_t *, __REG_CONST char *, size_t, rm_detail_t *, size_t, regmatch_t [], int));
|
||||||
|
#endif
|
||||||
|
#ifndef __REG_NOFRONT
|
||||||
|
int regexec _ANSI_ARGS_((regex_t *, __REG_CONST char *, size_t, regmatch_t [], int));
|
||||||
|
#endif
|
||||||
|
#ifdef __REG_WIDE_T
|
||||||
|
int __REG_WIDE_EXEC _ANSI_ARGS_((regex_t *, __REG_CONST __REG_WIDE_T *, size_t, rm_detail_t *, size_t, regmatch_t [], int));
|
||||||
|
#endif
|
||||||
|
re_void regfree _ANSI_ARGS_((regex_t *));
|
||||||
|
extern size_t regerror _ANSI_ARGS_((int, __REG_CONST regex_t *, char *, size_t));
|
||||||
|
/* automatically gathered by fwd; do not hand-edit */
|
||||||
|
/* =====^!^===== end forwards =====^!^===== */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* more C++ voodoo
|
||||||
|
*/
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* _REGEX_H_ */
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* regfree - free an RE
|
* regfree - free an RE
|
||||||
*
|
*
|
||||||
* Copyright (c) 1998, 1999 Henry Spencer. All rights reserved.
|
* Copyright (c) 1998, 1999 Henry Spencer. All rights reserved.
|
||||||
*
|
*
|
||||||
* Development of this software was funded, in part, by Cray Research Inc.,
|
* Development of this software was funded, in part, by Cray Research Inc.,
|
||||||
* UUNET Communications Services Inc., Sun Microsystems Inc., and Scriptics
|
* UUNET Communications Services Inc., Sun Microsystems Inc., and Scriptics
|
||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Internal interface definitions, etc., for the reg package
|
* Internal interface definitions, etc., for the reg package
|
||||||
*
|
*
|
||||||
* Copyright (c) 1998, 1999 Henry Spencer. All rights reserved.
|
* Copyright (c) 1998, 1999 Henry Spencer. All rights reserved.
|
||||||
*
|
*
|
||||||
* Development of this software was funded, in part, by Cray Research Inc.,
|
* Development of this software was funded, in part, by Cray Research Inc.,
|
||||||
* UUNET Communications Services Inc., Sun Microsystems Inc., and Scriptics
|
* UUNET Communications Services Inc., Sun Microsystems Inc., and Scriptics
|
||||||
@@ -26,8 +26,6 @@
|
|||||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
|
||||||
* $Id$
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@@ -45,43 +43,63 @@
|
|||||||
* Things that regcustom.h might override.
|
* Things that regcustom.h might override.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* standard header files (NULL is a reasonable indicator for them) */
|
||||||
|
#ifndef NULL
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <string.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
/* assertions */
|
/* assertions */
|
||||||
#ifndef __WXWINCE__
|
|
||||||
#ifndef assert
|
#ifndef assert
|
||||||
#ifndef REG_DEBUG
|
# ifndef REG_DEBUG
|
||||||
# ifndef NDEBUG
|
# define NDEBUG /* no assertions */
|
||||||
# define NDEBUG /* no assertions */
|
|
||||||
# endif
|
# endif
|
||||||
#endif
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#endif
|
#endif
|
||||||
#else
|
|
||||||
// To do: assertion on WinCE
|
|
||||||
#define assert(x)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* voids */
|
/* voids */
|
||||||
|
#ifndef VOID
|
||||||
|
#define VOID void /* for function return values */
|
||||||
|
#endif
|
||||||
#ifndef DISCARD
|
#ifndef DISCARD
|
||||||
#define DISCARD void /* for throwing values away */
|
#define DISCARD VOID /* for throwing values away */
|
||||||
|
#endif
|
||||||
|
#ifndef PVOID
|
||||||
|
#define PVOID VOID * /* generic pointer */
|
||||||
#endif
|
#endif
|
||||||
#ifndef VS
|
#ifndef VS
|
||||||
#define VS(x) ((void *)(x)) /* cast something to generic ptr */
|
#define VS(x) ((PVOID)(x)) /* cast something to generic ptr */
|
||||||
|
#endif
|
||||||
|
#ifndef NOPARMS
|
||||||
|
#define NOPARMS VOID /* for empty parm lists */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* const */
|
||||||
|
#ifndef CONST
|
||||||
|
#define CONST const /* for old compilers, might be empty */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* function-pointer declarator */
|
/* function-pointer declarator */
|
||||||
#ifndef FUNCPTR
|
#ifndef FUNCPTR
|
||||||
#define FUNCPTR(name, args) (*name) args
|
#if __STDC__ >= 1
|
||||||
|
#define FUNCPTR(name, args) (*name)args
|
||||||
|
#else
|
||||||
|
#define FUNCPTR(name, args) (*name)()
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* memory allocation */
|
/* memory allocation */
|
||||||
#ifndef MALLOC
|
#ifndef MALLOC
|
||||||
#define MALLOC(n) malloc(n)
|
#define MALLOC(n) malloc(n)
|
||||||
#endif
|
#endif
|
||||||
#ifndef REALLOC
|
#ifndef REALLOC
|
||||||
#define REALLOC(p, n) realloc(VS(p), n)
|
#define REALLOC(p, n) realloc(VS(p), n)
|
||||||
#endif
|
#endif
|
||||||
#ifndef FREE
|
#ifndef FREE
|
||||||
#define FREE(p) free(VS(p))
|
#define FREE(p) free(VS(p))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* want size of a char in bits, and max value in bounded quantifiers */
|
/* want size of a char in bits, and max value in bounded quantifiers */
|
||||||
@@ -89,7 +107,7 @@
|
|||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#endif
|
#endif
|
||||||
#ifndef _POSIX2_RE_DUP_MAX
|
#ifndef _POSIX2_RE_DUP_MAX
|
||||||
#define _POSIX2_RE_DUP_MAX 255 /* normally from <limits.h> */
|
#define _POSIX2_RE_DUP_MAX 255 /* normally from <limits.h> */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@@ -98,13 +116,13 @@
|
|||||||
* misc
|
* misc
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define NOTREACHED 0
|
#define NOTREACHED 0
|
||||||
#define xxx 1
|
#define xxx 1
|
||||||
|
|
||||||
#define DUPMAX _POSIX2_RE_DUP_MAX
|
#define DUPMAX _POSIX2_RE_DUP_MAX
|
||||||
#define INFINITY (DUPMAX+1)
|
#define INFINITY (DUPMAX+1)
|
||||||
|
|
||||||
#define REMAGIC 0xfed7 /* magic number for main struct */
|
#define REMAGIC 0xfed7 /* magic number for main struct */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -113,12 +131,12 @@
|
|||||||
*/
|
*/
|
||||||
#ifdef REG_DEBUG
|
#ifdef REG_DEBUG
|
||||||
/* FDEBUG does finite-state tracing */
|
/* FDEBUG does finite-state tracing */
|
||||||
#define FDEBUG(arglist) { if (v->eflags®_FTRACE) printf arglist; }
|
#define FDEBUG(arglist) { if (v->eflags®_FTRACE) printf arglist; }
|
||||||
/* MDEBUG does higher-level tracing */
|
/* MDEBUG does higher-level tracing */
|
||||||
#define MDEBUG(arglist) { if (v->eflags®_MTRACE) printf arglist; }
|
#define MDEBUG(arglist) { if (v->eflags®_MTRACE) printf arglist; }
|
||||||
#else
|
#else
|
||||||
#define FDEBUG(arglist) {}
|
#define FDEBUG(arglist) {}
|
||||||
#define MDEBUG(arglist) {}
|
#define MDEBUG(arglist) {}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@@ -126,25 +144,24 @@
|
|||||||
/*
|
/*
|
||||||
* bitmap manipulation
|
* bitmap manipulation
|
||||||
*/
|
*/
|
||||||
#define UBITS (CHAR_BIT * sizeof(unsigned))
|
#define UBITS (CHAR_BIT * sizeof(unsigned))
|
||||||
#define BSET(uv, sn) ((uv)[(sn)/UBITS] |= (unsigned)1 << ((sn)%UBITS))
|
#define BSET(uv, sn) ((uv)[(sn)/UBITS] |= (unsigned)1 << ((sn)%UBITS))
|
||||||
#define ISBSET(uv, sn) ((uv)[(sn)/UBITS] & ((unsigned)1 << ((sn)%UBITS)))
|
#define ISBSET(uv, sn) ((uv)[(sn)/UBITS] & ((unsigned)1 << ((sn)%UBITS)))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We dissect a chr into byts for colormap table indexing. Here we define
|
* We dissect a chr into byts for colormap table indexing. Here we define
|
||||||
* a byt, which will be the same as a byte on most machines... The exact
|
* a byt, which will be the same as a byte on most machines... The exact
|
||||||
* size of a byt is not critical, but about 8 bits is good, and extraction
|
* size of a byt is not critical, but about 8 bits is good, and extraction
|
||||||
* of 8-bit chunks is sometimes especially fast.
|
* of 8-bit chunks is sometimes especially fast.
|
||||||
*/
|
*/
|
||||||
#ifndef BYTBITS
|
#ifndef BYTBITS
|
||||||
#define BYTBITS 8 /* bits in a byt */
|
#define BYTBITS 8 /* bits in a byt */
|
||||||
#endif
|
#endif
|
||||||
#define BYTTAB (1<<BYTBITS) /* size of table with one entry per byt
|
#define BYTTAB (1<<BYTBITS) /* size of table with one entry per byt value */
|
||||||
* value */
|
#define BYTMASK (BYTTAB-1) /* bit mask for byt */
|
||||||
#define BYTMASK (BYTTAB-1) /* bit mask for byt */
|
#define NBYTS ((CHRBITS+BYTBITS-1)/BYTBITS)
|
||||||
#define NBYTS ((CHRBITS+BYTBITS-1)/BYTBITS)
|
|
||||||
/* the definition of GETCOLOR(), below, assumes NBYTS <= 4 */
|
/* the definition of GETCOLOR(), below, assumes NBYTS <= 4 */
|
||||||
|
|
||||||
|
|
||||||
@@ -153,86 +170,79 @@
|
|||||||
* As soon as possible, we map chrs into equivalence classes -- "colors" --
|
* As soon as possible, we map chrs into equivalence classes -- "colors" --
|
||||||
* which are of much more manageable number.
|
* which are of much more manageable number.
|
||||||
*/
|
*/
|
||||||
typedef short color; /* colors of characters */
|
typedef short color; /* colors of characters */
|
||||||
typedef int pcolor; /* what color promotes to */
|
typedef int pcolor; /* what color promotes to */
|
||||||
|
#define COLORLESS (-1) /* impossible color */
|
||||||
#define COLORLESS (-1) /* impossible color */
|
#define WHITE 0 /* default color, parent of all others */
|
||||||
#define WHITE 0 /* default color, parent of all others */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* A colormap is a tree -- more precisely, a DAG -- indexed at each level
|
* A colormap is a tree -- more precisely, a DAG -- indexed at each level
|
||||||
* by a byt of the chr, to map the chr to a color efficiently. Because
|
* by a byt of the chr, to map the chr to a color efficiently. Because
|
||||||
* lower sections of the tree can be shared, it can exploit the usual
|
* lower sections of the tree can be shared, it can exploit the usual
|
||||||
* sparseness of such a mapping table. The tree is always NBYTS levels
|
* sparseness of such a mapping table. The tree is always NBYTS levels
|
||||||
* deep (in the past it was shallower during construction but was "filled"
|
* deep (in the past it was shallower during construction but was "filled"
|
||||||
* to full depth at the end of that); areas that are unaltered as yet point
|
* to full depth at the end of that); areas that are unaltered as yet point
|
||||||
* to "fill blocks" which are entirely WHITE in color.
|
* to "fill blocks" which are entirely WHITE in color.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* the tree itself */
|
/* the tree itself */
|
||||||
struct colors
|
struct colors {
|
||||||
{
|
color ccolor[BYTTAB];
|
||||||
color ccolor[BYTTAB];
|
|
||||||
};
|
};
|
||||||
struct ptrs
|
struct ptrs {
|
||||||
{
|
|
||||||
union tree *pptr[BYTTAB];
|
union tree *pptr[BYTTAB];
|
||||||
};
|
};
|
||||||
union tree
|
union tree {
|
||||||
{
|
|
||||||
struct colors colors;
|
struct colors colors;
|
||||||
struct ptrs ptrs;
|
struct ptrs ptrs;
|
||||||
};
|
};
|
||||||
|
#define tcolor colors.ccolor
|
||||||
#define tcolor colors.ccolor
|
#define tptr ptrs.pptr
|
||||||
#define tptr ptrs.pptr
|
|
||||||
|
|
||||||
/* internal per-color structure for the color machinery */
|
/* internal per-color structure for the color machinery */
|
||||||
struct colordesc
|
struct colordesc {
|
||||||
{
|
uchr nchrs; /* number of chars of this color */
|
||||||
uchr nchrs; /* number of chars of this color */
|
color sub; /* open subcolor (if any); free chain ptr */
|
||||||
color sub; /* open subcolor (if any); free chain ptr */
|
# define NOSUB COLORLESS
|
||||||
#define NOSUB COLORLESS
|
struct arc *arcs; /* color chain */
|
||||||
struct arc *arcs; /* color chain */
|
int flags;
|
||||||
int flags;
|
# define FREECOL 01 /* currently free */
|
||||||
#define FREECOL 01 /* currently free */
|
# define PSEUDO 02 /* pseudocolor, no real chars */
|
||||||
#define PSEUDO 02 /* pseudocolor, no real chars */
|
# define UNUSEDCOLOR(cd) ((cd)->flags&FREECOL)
|
||||||
#define UNUSEDCOLOR(cd) ((cd)->flags&FREECOL)
|
union tree *block; /* block of solid color, if any */
|
||||||
union tree *block; /* block of solid color, if any */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* the color map itself */
|
/* the color map itself */
|
||||||
struct colormap
|
struct colormap {
|
||||||
{
|
int magic;
|
||||||
int magic;
|
# define CMMAGIC 0x876
|
||||||
#define CMMAGIC 0x876
|
struct vars *v; /* for compile error reporting */
|
||||||
struct vars *v; /* for compile error reporting */
|
size_t ncds; /* number of colordescs */
|
||||||
size_t ncds; /* number of colordescs */
|
size_t max; /* highest in use */
|
||||||
size_t max; /* highest in use */
|
color free; /* beginning of free chain (if non-0) */
|
||||||
color free; /* beginning of free chain (if non-0) */
|
|
||||||
struct colordesc *cd;
|
struct colordesc *cd;
|
||||||
#define CDEND(cm) (&(cm)->cd[(cm)->max + 1])
|
# define CDEND(cm) (&(cm)->cd[(cm)->max + 1])
|
||||||
#define NINLINECDS ((size_t)10)
|
# define NINLINECDS ((size_t)10)
|
||||||
struct colordesc cdspace[NINLINECDS];
|
struct colordesc cdspace[NINLINECDS];
|
||||||
union tree tree[NBYTS]; /* tree top, plus fill blocks */
|
union tree tree[NBYTS]; /* tree top, plus fill blocks */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* optimization magic to do fast chr->color mapping */
|
/* optimization magic to do fast chr->color mapping */
|
||||||
#define B0(c) ((c) & BYTMASK)
|
#define B0(c) ((c) & BYTMASK)
|
||||||
#define B1(c) (((c)>>BYTBITS) & BYTMASK)
|
#define B1(c) (((c)>>BYTBITS) & BYTMASK)
|
||||||
#define B2(c) (((c)>>(2*BYTBITS)) & BYTMASK)
|
#define B2(c) (((c)>>(2*BYTBITS)) & BYTMASK)
|
||||||
#define B3(c) (((c)>>(3*BYTBITS)) & BYTMASK)
|
#define B3(c) (((c)>>(3*BYTBITS)) & BYTMASK)
|
||||||
#if NBYTS == 1
|
#if NBYTS == 1
|
||||||
#define GETCOLOR(cm, c) ((cm)->tree->tcolor[B0(c)])
|
#define GETCOLOR(cm, c) ((cm)->tree->tcolor[B0(c)])
|
||||||
#endif
|
#endif
|
||||||
/* beware, for NBYTS>1, GETCOLOR() is unsafe -- 2nd arg used repeatedly */
|
/* beware, for NBYTS>1, GETCOLOR() is unsafe -- 2nd arg used repeatedly */
|
||||||
#if NBYTS == 2
|
#if NBYTS == 2
|
||||||
#define GETCOLOR(cm, c) ((cm)->tree->tptr[B1(c)]->tcolor[B0(c)])
|
#define GETCOLOR(cm, c) ((cm)->tree->tptr[B1(c)]->tcolor[B0(c)])
|
||||||
#endif
|
#endif
|
||||||
#if NBYTS == 4
|
#if NBYTS == 4
|
||||||
#define GETCOLOR(cm, c) ((cm)->tree->tptr[B3(c)]->tptr[B2(c)]->tptr[B1(c)]->tcolor[B0(c)])
|
#define GETCOLOR(cm, c) ((cm)->tree->tptr[B3(c)]->tptr[B2(c)]->tptr[B1(c)]->tcolor[B0(c)])
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@@ -241,23 +251,22 @@ struct colormap
|
|||||||
* Interface definitions for locale-interface functions in locale.c.
|
* Interface definitions for locale-interface functions in locale.c.
|
||||||
* Multi-character collating elements (MCCEs) cause most of the trouble.
|
* Multi-character collating elements (MCCEs) cause most of the trouble.
|
||||||
*/
|
*/
|
||||||
struct cvec
|
struct cvec {
|
||||||
{
|
int nchrs; /* number of chrs */
|
||||||
int nchrs; /* number of chrs */
|
int chrspace; /* number of chrs possible */
|
||||||
int chrspace; /* number of chrs possible */
|
chr *chrs; /* pointer to vector of chrs */
|
||||||
chr *chrs; /* pointer to vector of chrs */
|
int nranges; /* number of ranges (chr pairs) */
|
||||||
int nranges; /* number of ranges (chr pairs) */
|
int rangespace; /* number of chrs possible */
|
||||||
int rangespace; /* number of chrs possible */
|
chr *ranges; /* pointer to vector of chr pairs */
|
||||||
chr *ranges; /* pointer to vector of chr pairs */
|
int nmcces; /* number of MCCEs */
|
||||||
int nmcces; /* number of MCCEs */
|
int mccespace; /* number of MCCEs possible */
|
||||||
int mccespace; /* number of MCCEs possible */
|
int nmccechrs; /* number of chrs used for MCCEs */
|
||||||
int nmccechrs; /* number of chrs used for MCCEs */
|
chr *mcces[1]; /* pointers to 0-terminated MCCEs */
|
||||||
chr *mcces[1]; /* pointers to 0-terminated MCCEs */
|
/* and both batches of chrs are on the end */
|
||||||
/* and both batches of chrs are on the end */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* caution: this value cannot be changed easily */
|
/* caution: this value cannot be changed easily */
|
||||||
#define MAXMCCE 2 /* length of longest MCCE */
|
#define MAXMCCE 2 /* length of longest MCCE */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -269,59 +278,54 @@ struct cvec
|
|||||||
*/
|
*/
|
||||||
struct state;
|
struct state;
|
||||||
|
|
||||||
struct arc
|
struct arc {
|
||||||
{
|
int type;
|
||||||
int type;
|
# define ARCFREE '\0'
|
||||||
#define ARCFREE '\0'
|
color co;
|
||||||
color co;
|
struct state *from; /* where it's from (and contained within) */
|
||||||
struct state *from; /* where it's from (and contained within) */
|
struct state *to; /* where it's to */
|
||||||
struct state *to; /* where it's to */
|
struct arc *outchain; /* *from's outs chain or free chain */
|
||||||
struct arc *outchain; /* *from's outs chain or free chain */
|
# define freechain outchain
|
||||||
#define freechain outchain
|
struct arc *inchain; /* *to's ins chain */
|
||||||
struct arc *inchain; /* *to's ins chain */
|
struct arc *colorchain; /* color's arc chain */
|
||||||
struct arc *colorchain; /* color's arc chain */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct arcbatch
|
struct arcbatch { /* for bulk allocation of arcs */
|
||||||
{ /* for bulk allocation of arcs */
|
|
||||||
struct arcbatch *next;
|
struct arcbatch *next;
|
||||||
#define ABSIZE 10
|
# define ABSIZE 10
|
||||||
struct arc a[ABSIZE];
|
struct arc a[ABSIZE];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct state
|
struct state {
|
||||||
{
|
int no;
|
||||||
int no;
|
# define FREESTATE (-1)
|
||||||
#define FREESTATE (-1)
|
char flag; /* marks special states */
|
||||||
char flag; /* marks special states */
|
int nins; /* number of inarcs */
|
||||||
int nins; /* number of inarcs */
|
struct arc *ins; /* chain of inarcs */
|
||||||
struct arc *ins; /* chain of inarcs */
|
int nouts; /* number of outarcs */
|
||||||
int nouts; /* number of outarcs */
|
struct arc *outs; /* chain of outarcs */
|
||||||
struct arc *outs; /* chain of outarcs */
|
struct arc *free; /* chain of free arcs */
|
||||||
struct arc *free; /* chain of free arcs */
|
struct state *tmp; /* temporary for traversal algorithms */
|
||||||
struct state *tmp; /* temporary for traversal algorithms */
|
struct state *next; /* chain for traversing all */
|
||||||
struct state *next; /* chain for traversing all */
|
struct state *prev; /* back chain */
|
||||||
struct state *prev; /* back chain */
|
struct arcbatch oas; /* first arcbatch, avoid malloc in easy case */
|
||||||
struct arcbatch oas; /* first arcbatch, avoid malloc in easy
|
int noas; /* number of arcs used in first arcbatch */
|
||||||
* case */
|
|
||||||
int noas; /* number of arcs used in first arcbatch */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct nfa
|
struct nfa {
|
||||||
{
|
struct state *pre; /* pre-initial state */
|
||||||
struct state *pre; /* pre-initial state */
|
struct state *init; /* initial state */
|
||||||
struct state *init; /* initial state */
|
struct state *final; /* final state */
|
||||||
struct state *final; /* final state */
|
struct state *post; /* post-final state */
|
||||||
struct state *post; /* post-final state */
|
int nstates; /* for numbering states */
|
||||||
int nstates; /* for numbering states */
|
struct state *states; /* state-chain header */
|
||||||
struct state *states; /* state-chain header */
|
struct state *slast; /* tail of the chain */
|
||||||
struct state *slast; /* tail of the chain */
|
struct state *free; /* free list */
|
||||||
struct state *free; /* free list */
|
struct colormap *cm; /* the color map */
|
||||||
struct colormap *cm; /* the color map */
|
color bos[2]; /* colors, if any, assigned to BOS and BOL */
|
||||||
color bos[2]; /* colors, if any, assigned to BOS and BOL */
|
color eos[2]; /* colors, if any, assigned to EOS and EOL */
|
||||||
color eos[2]; /* colors, if any, assigned to EOS and EOL */
|
struct vars *v; /* simplifies compile error reporting */
|
||||||
struct vars *v; /* simplifies compile error reporting */
|
struct nfa *parent; /* parent NFA, if any */
|
||||||
struct nfa *parent; /* parent NFA, if any */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -329,64 +333,58 @@ struct nfa
|
|||||||
/*
|
/*
|
||||||
* definitions for compacted NFA
|
* definitions for compacted NFA
|
||||||
*/
|
*/
|
||||||
struct carc
|
struct carc {
|
||||||
{
|
color co; /* COLORLESS is list terminator */
|
||||||
color co; /* COLORLESS is list terminator */
|
int to; /* state number */
|
||||||
int to; /* state number */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct cnfa
|
struct cnfa {
|
||||||
{
|
int nstates; /* number of states */
|
||||||
int nstates; /* number of states */
|
int ncolors; /* number of colors */
|
||||||
int ncolors; /* number of colors */
|
int flags;
|
||||||
int flags;
|
# define HASLACONS 01 /* uses lookahead constraints */
|
||||||
#define HASLACONS 01 /* uses lookahead constraints */
|
int pre; /* setup state number */
|
||||||
int pre; /* setup state number */
|
int post; /* teardown state number */
|
||||||
int post; /* teardown state number */
|
color bos[2]; /* colors, if any, assigned to BOS and BOL */
|
||||||
color bos[2]; /* colors, if any, assigned to BOS and BOL */
|
color eos[2]; /* colors, if any, assigned to EOS and EOL */
|
||||||
color eos[2]; /* colors, if any, assigned to EOS and EOL */
|
struct carc **states; /* vector of pointers to outarc lists */
|
||||||
struct carc **states; /* vector of pointers to outarc lists */
|
struct carc *arcs; /* the area for the lists */
|
||||||
struct carc *arcs; /* the area for the lists */
|
|
||||||
};
|
};
|
||||||
|
#define ZAPCNFA(cnfa) ((cnfa).nstates = 0)
|
||||||
#define ZAPCNFA(cnfa) ((cnfa).nstates = 0)
|
#define NULLCNFA(cnfa) ((cnfa).nstates == 0)
|
||||||
#define NULLCNFA(cnfa) ((cnfa).nstates == 0)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* subexpression tree
|
* subexpression tree
|
||||||
*/
|
*/
|
||||||
struct subre
|
struct subre {
|
||||||
{
|
char op; /* '|', '.' (concat), 'b' (backref), '(', '=' */
|
||||||
char op; /* '|', '.' (concat), 'b' (backref), '(',
|
char flags;
|
||||||
* '=' */
|
# define LONGER 01 /* prefers longer match */
|
||||||
char flags;
|
# define SHORTER 02 /* prefers shorter match */
|
||||||
#define LONGER 01 /* prefers longer match */
|
# define MIXED 04 /* mixed preference below */
|
||||||
#define SHORTER 02 /* prefers shorter match */
|
# define CAP 010 /* capturing parens below */
|
||||||
#define MIXED 04 /* mixed preference below */
|
# define BACKR 020 /* back reference below */
|
||||||
#define CAP 010 /* capturing parens below */
|
# define INUSE 0100 /* in use in final tree */
|
||||||
#define BACKR 020 /* back reference below */
|
# define LOCAL 03 /* bits which may not propagate up */
|
||||||
#define INUSE 0100 /* in use in final tree */
|
# define LMIX(f) ((f)<<2) /* LONGER -> MIXED */
|
||||||
#define LOCAL 03 /* bits which may not propagate up */
|
# define SMIX(f) ((f)<<1) /* SHORTER -> MIXED */
|
||||||
#define LMIX(f) ((f)<<2) /* LONGER -> MIXED */
|
# define UP(f) (((f)&~LOCAL) | (LMIX(f) & SMIX(f) & MIXED))
|
||||||
#define SMIX(f) ((f)<<1) /* SHORTER -> MIXED */
|
# define MESSY(f) ((f)&(MIXED|CAP|BACKR))
|
||||||
#define UP(f) (((f)&~LOCAL) | (LMIX(f) & SMIX(f) & MIXED))
|
# define PREF(f) ((f)&LOCAL)
|
||||||
#define MESSY(f) ((f)&(MIXED|CAP|BACKR))
|
# define PREF2(f1, f2) ((PREF(f1) != 0) ? PREF(f1) : PREF(f2))
|
||||||
#define PREF(f) ((f)&LOCAL)
|
# define COMBINE(f1, f2) (UP((f1)|(f2)) | PREF2(f1, f2))
|
||||||
#define PREF2(f1, f2) ((PREF(f1) != 0) ? PREF(f1) : PREF(f2))
|
short retry; /* index into retry memory */
|
||||||
#define COMBINE(f1, f2) (UP((f1)|(f2)) | PREF2(f1, f2))
|
int subno; /* subexpression number (for 'b' and '(') */
|
||||||
short retry; /* index into retry memory */
|
short min; /* min repetitions, for backref only */
|
||||||
int subno; /* subexpression number (for 'b' and '(') */
|
short max; /* max repetitions, for backref only */
|
||||||
short min; /* min repetitions, for backref only */
|
struct subre *left; /* left child, if any (also freelist chain) */
|
||||||
short max; /* max repetitions, for backref only */
|
struct subre *right; /* right child, if any */
|
||||||
struct subre *left; /* left child, if any (also freelist
|
struct state *begin; /* outarcs from here... */
|
||||||
* chain) */
|
struct state *end; /* ...ending in inarcs here */
|
||||||
struct subre *right; /* right child, if any */
|
struct cnfa cnfa; /* compacted NFA, if any */
|
||||||
struct state *begin; /* outarcs from here... */
|
struct subre *chain; /* for bookkeeping and error cleanup */
|
||||||
struct state *end; /* ...ending in inarcs here */
|
|
||||||
struct cnfa cnfa; /* compacted NFA, if any */
|
|
||||||
struct subre *chain; /* for bookkeeping and error cleanup */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -395,9 +393,8 @@ struct subre
|
|||||||
* table of function pointers for generic manipulation functions
|
* table of function pointers for generic manipulation functions
|
||||||
* A regex_t's re_fns points to one of these.
|
* A regex_t's re_fns points to one of these.
|
||||||
*/
|
*/
|
||||||
struct fns
|
struct fns {
|
||||||
{
|
VOID FUNCPTR(free, (regex_t *));
|
||||||
void FUNCPTR(free, (regex_t *));
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -405,18 +402,17 @@ struct fns
|
|||||||
/*
|
/*
|
||||||
* the insides of a regex_t, hidden behind a void *
|
* the insides of a regex_t, hidden behind a void *
|
||||||
*/
|
*/
|
||||||
struct guts
|
struct guts {
|
||||||
{
|
int magic;
|
||||||
int magic;
|
# define GUTSMAGIC 0xfed9
|
||||||
#define GUTSMAGIC 0xfed9
|
int cflags; /* copy of compile flags */
|
||||||
int cflags; /* copy of compile flags */
|
long info; /* copy of re_info */
|
||||||
long info; /* copy of re_info */
|
size_t nsub; /* copy of re_nsub */
|
||||||
size_t nsub; /* copy of re_nsub */
|
|
||||||
struct subre *tree;
|
struct subre *tree;
|
||||||
struct cnfa search; /* for fast preliminary search */
|
struct cnfa search; /* for fast preliminary search */
|
||||||
int ntree;
|
int ntree;
|
||||||
struct colormap cmap;
|
struct colormap cmap;
|
||||||
int FUNCPTR(compare, (const chr *, const chr *, size_t));
|
int FUNCPTR(compare, (CONST chr *, CONST chr *, size_t));
|
||||||
struct subre *lacons; /* lookahead-constraint vector */
|
struct subre *lacons; /* lookahead-constraint vector */
|
||||||
int nlacons; /* size of lacons */
|
int nlacons; /* size of lacons */
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user