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:
@@ -28,7 +28,6 @@
|
|||||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $Header$
|
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* Note that there are some incestuous relationships between this code and
|
* Note that there are some incestuous relationships between this code and
|
||||||
@@ -43,11 +42,13 @@
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* initcm - set up new colormap
|
- initcm - set up new colormap
|
||||||
|
^ static VOID initcm(struct vars *, struct colormap *);
|
||||||
*/
|
*/
|
||||||
static void
|
static VOID
|
||||||
initcm(struct vars * v,
|
initcm(v, cm)
|
||||||
struct colormap * cm)
|
struct vars *v;
|
||||||
|
struct colormap *cm;
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int j;
|
int j;
|
||||||
@@ -70,24 +71,25 @@ initcm(struct vars * v,
|
|||||||
cd->nchrs = CHR_MAX - CHR_MIN + 1;
|
cd->nchrs = CHR_MAX - CHR_MIN + 1;
|
||||||
|
|
||||||
/* upper levels of tree */
|
/* upper levels of tree */
|
||||||
for (t = &cm->tree[0], j = NBYTS - 1; j > 0; t = nextt, j--)
|
for (t = &cm->tree[0], j = NBYTS-1; j > 0; t = nextt, j--) {
|
||||||
{
|
|
||||||
nextt = t + 1;
|
nextt = t + 1;
|
||||||
for (i = BYTTAB - 1; i >= 0; i--)
|
for (i = BYTTAB-1; i >= 0; i--)
|
||||||
t->tptr[i] = nextt;
|
t->tptr[i] = nextt;
|
||||||
}
|
}
|
||||||
/* bottom level is solid white */
|
/* bottom level is solid white */
|
||||||
t = &cm->tree[NBYTS - 1];
|
t = &cm->tree[NBYTS-1];
|
||||||
for (i = BYTTAB - 1; i >= 0; i--)
|
for (i = BYTTAB-1; i >= 0; i--)
|
||||||
t->tcolor[i] = WHITE;
|
t->tcolor[i] = WHITE;
|
||||||
cd->block = t;
|
cd->block = t;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* freecm - free dynamically-allocated things in a colormap
|
- freecm - free dynamically-allocated things in a colormap
|
||||||
|
^ static VOID freecm(struct colormap *);
|
||||||
*/
|
*/
|
||||||
static void
|
static VOID
|
||||||
freecm(struct colormap * cm)
|
freecm(cm)
|
||||||
|
struct colormap *cm;
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
union tree *cb;
|
union tree *cb;
|
||||||
@@ -96,8 +98,7 @@ freecm(struct colormap * cm)
|
|||||||
if (NBYTS > 1)
|
if (NBYTS > 1)
|
||||||
cmtreefree(cm, cm->tree, 0);
|
cmtreefree(cm, cm->tree, 0);
|
||||||
for (i = 1; i <= cm->max; i++) /* skip WHITE */
|
for (i = 1; i <= cm->max; i++) /* skip WHITE */
|
||||||
if (!UNUSEDCOLOR(&cm->cd[i]))
|
if (!UNUSEDCOLOR(&cm->cd[i])) {
|
||||||
{
|
|
||||||
cb = cm->cd[i].block;
|
cb = cm->cd[i].block;
|
||||||
if (cb != NULL)
|
if (cb != NULL)
|
||||||
FREE(cb);
|
FREE(cb);
|
||||||
@@ -107,32 +108,29 @@ freecm(struct colormap * cm)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* cmtreefree - free a non-terminal part of a colormap tree
|
- cmtreefree - free a non-terminal part of a colormap tree
|
||||||
|
^ static VOID cmtreefree(struct colormap *, union tree *, int);
|
||||||
*/
|
*/
|
||||||
static void
|
static VOID
|
||||||
cmtreefree(struct colormap * cm,
|
cmtreefree(cm, tree, level)
|
||||||
union tree * tree,
|
struct colormap *cm;
|
||||||
int level) /* level number (top == 0) of this block */
|
union tree *tree;
|
||||||
|
int level; /* level number (top == 0) of this block */
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
union tree *t;
|
union tree *t;
|
||||||
union tree *fillt = &cm->tree[level + 1];
|
union tree *fillt = &cm->tree[level+1];
|
||||||
union tree *cb;
|
union tree *cb;
|
||||||
|
|
||||||
assert(level < NBYTS - 1); /* this level has pointers */
|
assert(level < NBYTS-1); /* this level has pointers */
|
||||||
for (i = BYTTAB - 1; i >= 0; i--)
|
for (i = BYTTAB-1; i >= 0; i--) {
|
||||||
{
|
|
||||||
t = tree->tptr[i];
|
t = tree->tptr[i];
|
||||||
assert(t != NULL);
|
assert(t != NULL);
|
||||||
if (t != fillt)
|
if (t != fillt) {
|
||||||
{
|
if (level < NBYTS-2) { /* more pointer blocks below */
|
||||||
if (level < NBYTS - 2)
|
cmtreefree(cm, t, level+1);
|
||||||
{ /* more pointer blocks below */
|
|
||||||
cmtreefree(cm, t, level + 1);
|
|
||||||
FREE(t);
|
FREE(t);
|
||||||
}
|
} else { /* color block below */
|
||||||
else
|
|
||||||
{ /* color block below */
|
|
||||||
cb = cm->cd[t->tcolor[0]].block;
|
cb = cm->cd[t->tcolor[0]].block;
|
||||||
if (t != cb) /* not a solid block */
|
if (t != cb) /* not a solid block */
|
||||||
FREE(t);
|
FREE(t);
|
||||||
@@ -142,12 +140,14 @@ cmtreefree(struct colormap * cm,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* setcolor - set the color of a character in a colormap
|
- setcolor - set the color of a character in a colormap
|
||||||
|
^ static color setcolor(struct colormap *, pchr, pcolor);
|
||||||
*/
|
*/
|
||||||
static color /* previous color */
|
static color /* previous color */
|
||||||
setcolor(struct colormap * cm,
|
setcolor(cm, c, co)
|
||||||
chr c,
|
struct colormap *cm;
|
||||||
pcolor co)
|
pchr c;
|
||||||
|
pcolor co;
|
||||||
{
|
{
|
||||||
uchr uc = c;
|
uchr uc = c;
|
||||||
int shift;
|
int shift;
|
||||||
@@ -167,30 +167,27 @@ setcolor(struct colormap * cm,
|
|||||||
|
|
||||||
t = cm->tree;
|
t = cm->tree;
|
||||||
for (level = 0, shift = BYTBITS * (NBYTS - 1); shift > 0;
|
for (level = 0, shift = BYTBITS * (NBYTS - 1); shift > 0;
|
||||||
level++, shift -= BYTBITS)
|
level++, shift -= BYTBITS) {
|
||||||
{
|
|
||||||
b = (uc >> shift) & BYTMASK;
|
b = (uc >> shift) & BYTMASK;
|
||||||
lastt = t;
|
lastt = t;
|
||||||
t = lastt->tptr[b];
|
t = lastt->tptr[b];
|
||||||
assert(t != NULL);
|
assert(t != NULL);
|
||||||
fillt = &cm->tree[level + 1];
|
fillt = &cm->tree[level+1];
|
||||||
bottom = (shift <= BYTBITS) ? 1 : 0;
|
bottom = (shift <= BYTBITS) ? 1 : 0;
|
||||||
cb = (bottom) ? cm->cd[t->tcolor[0]].block : fillt;
|
cb = (bottom) ? cm->cd[t->tcolor[0]].block : fillt;
|
||||||
if (t == fillt || t == cb)
|
if (t == fillt || t == cb) { /* must allocate a new block */
|
||||||
{ /* must allocate a new block */
|
newt = (union tree *)MALLOC((bottom) ?
|
||||||
newt = (union tree *) MALLOC((bottom) ?
|
|
||||||
sizeof(struct colors) : sizeof(struct ptrs));
|
sizeof(struct colors) : sizeof(struct ptrs));
|
||||||
if (newt == NULL)
|
if (newt == NULL) {
|
||||||
{
|
|
||||||
CERR(REG_ESPACE);
|
CERR(REG_ESPACE);
|
||||||
return COLORLESS;
|
return COLORLESS;
|
||||||
}
|
}
|
||||||
if (bottom)
|
if (bottom)
|
||||||
memcpy(VS(newt->tcolor), VS(t->tcolor),
|
memcpy(VS(newt->tcolor), VS(t->tcolor),
|
||||||
BYTTAB * sizeof(color));
|
BYTTAB*sizeof(color));
|
||||||
else
|
else
|
||||||
memcpy(VS(newt->tptr), VS(t->tptr),
|
memcpy(VS(newt->tptr), VS(t->tptr),
|
||||||
BYTTAB * sizeof(union tree *));
|
BYTTAB*sizeof(union tree *));
|
||||||
t = newt;
|
t = newt;
|
||||||
lastt->tptr[b] = t;
|
lastt->tptr[b] = t;
|
||||||
}
|
}
|
||||||
@@ -198,28 +195,32 @@ setcolor(struct colormap * cm,
|
|||||||
|
|
||||||
b = uc & BYTMASK;
|
b = uc & BYTMASK;
|
||||||
prev = t->tcolor[b];
|
prev = t->tcolor[b];
|
||||||
t->tcolor[b] = (color) co;
|
t->tcolor[b] = (color)co;
|
||||||
return prev;
|
return prev;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* maxcolor - report largest color number in use
|
- maxcolor - report largest color number in use
|
||||||
|
^ static color maxcolor(struct colormap *);
|
||||||
*/
|
*/
|
||||||
static color
|
static color
|
||||||
maxcolor(struct colormap * cm)
|
maxcolor(cm)
|
||||||
|
struct colormap *cm;
|
||||||
{
|
{
|
||||||
if (CISERR())
|
if (CISERR())
|
||||||
return COLORLESS;
|
return COLORLESS;
|
||||||
|
|
||||||
return (color) cm->max;
|
return (color)cm->max;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* newcolor - find a new color (must be subject of setcolor at once)
|
- newcolor - find a new color (must be subject of setcolor at once)
|
||||||
* Beware: may relocate the colordescs.
|
* Beware: may relocate the colordescs.
|
||||||
|
^ static color newcolor(struct colormap *);
|
||||||
*/
|
*/
|
||||||
static color /* COLORLESS for error */
|
static color /* COLORLESS for error */
|
||||||
newcolor(struct colormap * cm)
|
newcolor(cm)
|
||||||
|
struct colormap *cm;
|
||||||
{
|
{
|
||||||
struct colordesc *cd;
|
struct colordesc *cd;
|
||||||
struct colordesc *new;
|
struct colordesc *new;
|
||||||
@@ -228,37 +229,29 @@ newcolor(struct colormap * cm)
|
|||||||
if (CISERR())
|
if (CISERR())
|
||||||
return COLORLESS;
|
return COLORLESS;
|
||||||
|
|
||||||
if (cm->free != 0)
|
if (cm->free != 0) {
|
||||||
{
|
|
||||||
assert(cm->free > 0);
|
assert(cm->free > 0);
|
||||||
assert((size_t) cm->free < cm->ncds);
|
assert((size_t)cm->free < cm->ncds);
|
||||||
cd = &cm->cd[cm->free];
|
cd = &cm->cd[cm->free];
|
||||||
assert(UNUSEDCOLOR(cd));
|
assert(UNUSEDCOLOR(cd));
|
||||||
assert(cd->arcs == NULL);
|
assert(cd->arcs == NULL);
|
||||||
cm->free = cd->sub;
|
cm->free = cd->sub;
|
||||||
}
|
} else if (cm->max < cm->ncds - 1) {
|
||||||
else if (cm->max < cm->ncds - 1)
|
|
||||||
{
|
|
||||||
cm->max++;
|
cm->max++;
|
||||||
cd = &cm->cd[cm->max];
|
cd = &cm->cd[cm->max];
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
/* oops, must allocate more */
|
/* oops, must allocate more */
|
||||||
n = cm->ncds * 2;
|
n = cm->ncds * 2;
|
||||||
if (cm->cd == cm->cdspace)
|
if (cm->cd == cm->cdspace) {
|
||||||
{
|
new = (struct colordesc *)MALLOC(n *
|
||||||
new = (struct colordesc *) MALLOC(n *
|
|
||||||
sizeof(struct colordesc));
|
sizeof(struct colordesc));
|
||||||
if (new != NULL)
|
if (new != NULL)
|
||||||
memcpy(VS(new), VS(cm->cdspace), cm->ncds *
|
memcpy(VS(new), VS(cm->cdspace), cm->ncds *
|
||||||
sizeof(struct colordesc));
|
sizeof(struct colordesc));
|
||||||
}
|
} else
|
||||||
else
|
new = (struct colordesc *)REALLOC(cm->cd,
|
||||||
new = (struct colordesc *) REALLOC(cm->cd,
|
|
||||||
n * sizeof(struct colordesc));
|
n * sizeof(struct colordesc));
|
||||||
if (new == NULL)
|
if (new == NULL) {
|
||||||
{
|
|
||||||
CERR(REG_ESPACE);
|
CERR(REG_ESPACE);
|
||||||
return COLORLESS;
|
return COLORLESS;
|
||||||
}
|
}
|
||||||
@@ -275,19 +268,20 @@ newcolor(struct colormap * cm)
|
|||||||
cd->flags = 0;
|
cd->flags = 0;
|
||||||
cd->block = NULL;
|
cd->block = NULL;
|
||||||
|
|
||||||
return (color) (cd - cm->cd);
|
return (color)(cd - cm->cd);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* freecolor - free a color (must have no arcs or subcolor)
|
- freecolor - free a color (must have no arcs or subcolor)
|
||||||
|
^ static VOID freecolor(struct colormap *, pcolor);
|
||||||
*/
|
*/
|
||||||
static void
|
static VOID
|
||||||
freecolor(struct colormap * cm,
|
freecolor(cm, co)
|
||||||
pcolor co)
|
struct colormap *cm;
|
||||||
|
pcolor co;
|
||||||
{
|
{
|
||||||
struct colordesc *cd = &cm->cd[co];
|
struct colordesc *cd = &cm->cd[co];
|
||||||
color pco,
|
color pco, nco; /* for freelist scan */
|
||||||
nco; /* for freelist scan */
|
|
||||||
|
|
||||||
assert(co >= 0);
|
assert(co >= 0);
|
||||||
if (co == WHITE)
|
if (co == WHITE)
|
||||||
@@ -297,51 +291,45 @@ freecolor(struct colormap * cm,
|
|||||||
assert(cd->sub == NOSUB);
|
assert(cd->sub == NOSUB);
|
||||||
assert(cd->nchrs == 0);
|
assert(cd->nchrs == 0);
|
||||||
cd->flags = FREECOL;
|
cd->flags = FREECOL;
|
||||||
if (cd->block != NULL)
|
if (cd->block != NULL) {
|
||||||
{
|
|
||||||
FREE(cd->block);
|
FREE(cd->block);
|
||||||
cd->block = NULL; /* just paranoia */
|
cd->block = NULL; /* just paranoia */
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((size_t) co == cm->max)
|
if ((size_t)co == cm->max) {
|
||||||
{
|
|
||||||
while (cm->max > WHITE && UNUSEDCOLOR(&cm->cd[cm->max]))
|
while (cm->max > WHITE && UNUSEDCOLOR(&cm->cd[cm->max]))
|
||||||
cm->max--;
|
cm->max--;
|
||||||
assert(cm->free >= 0);
|
assert(cm->free >= 0);
|
||||||
while ((size_t) cm->free > cm->max)
|
while ((size_t)cm->free > cm->max)
|
||||||
cm->free = cm->cd[cm->free].sub;
|
cm->free = cm->cd[cm->free].sub;
|
||||||
if (cm->free > 0)
|
if (cm->free > 0) {
|
||||||
{
|
|
||||||
assert(cm->free < cm->max);
|
assert(cm->free < cm->max);
|
||||||
pco = cm->free;
|
pco = cm->free;
|
||||||
nco = cm->cd[pco].sub;
|
nco = cm->cd[pco].sub;
|
||||||
while (nco > 0)
|
while (nco > 0)
|
||||||
if ((size_t) nco > cm->max)
|
if ((size_t)nco > cm->max) {
|
||||||
{
|
|
||||||
/* take this one out of freelist */
|
/* take this one out of freelist */
|
||||||
nco = cm->cd[nco].sub;
|
nco = cm->cd[nco].sub;
|
||||||
cm->cd[pco].sub = nco;
|
cm->cd[pco].sub = nco;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
assert(nco < cm->max);
|
assert(nco < cm->max);
|
||||||
pco = nco;
|
pco = nco;
|
||||||
nco = cm->cd[pco].sub;
|
nco = cm->cd[pco].sub;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
cd->sub = cm->free;
|
cd->sub = cm->free;
|
||||||
cm->free = (color) (cd - cm->cd);
|
cm->free = (color)(cd - cm->cd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* pseudocolor - allocate a false color, to be managed by other means
|
- pseudocolor - allocate a false color, to be managed by other means
|
||||||
|
^ static color pseudocolor(struct colormap *);
|
||||||
*/
|
*/
|
||||||
static color
|
static color
|
||||||
pseudocolor(struct colormap * cm)
|
pseudocolor(cm)
|
||||||
|
struct colormap *cm;
|
||||||
{
|
{
|
||||||
color co;
|
color co;
|
||||||
|
|
||||||
@@ -354,10 +342,13 @@ pseudocolor(struct colormap * cm)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* subcolor - allocate a new subcolor (if necessary) to this chr
|
- subcolor - allocate a new subcolor (if necessary) to this chr
|
||||||
|
^ static color subcolor(struct colormap *, pchr c);
|
||||||
*/
|
*/
|
||||||
static color
|
static color
|
||||||
subcolor(struct colormap * cm, chr c)
|
subcolor(cm, c)
|
||||||
|
struct colormap *cm;
|
||||||
|
pchr c;
|
||||||
{
|
{
|
||||||
color co; /* current color of c */
|
color co; /* current color of c */
|
||||||
color sco; /* new subcolor */
|
color sco; /* new subcolor */
|
||||||
@@ -377,22 +368,22 @@ subcolor(struct colormap * cm, chr c)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* newsub - allocate a new subcolor (if necessary) for a color
|
- newsub - allocate a new subcolor (if necessary) for a color
|
||||||
|
^ static color newsub(struct colormap *, pcolor);
|
||||||
*/
|
*/
|
||||||
static color
|
static color
|
||||||
newsub(struct colormap * cm,
|
newsub(cm, co)
|
||||||
pcolor co)
|
struct colormap *cm;
|
||||||
|
pcolor co;
|
||||||
{
|
{
|
||||||
color sco; /* new subcolor */
|
color sco; /* new subcolor */
|
||||||
|
|
||||||
sco = cm->cd[co].sub;
|
sco = cm->cd[co].sub;
|
||||||
if (sco == NOSUB)
|
if (sco == NOSUB) { /* color has no open subcolor */
|
||||||
{ /* color has no open subcolor */
|
|
||||||
if (cm->cd[co].nchrs == 1) /* optimization */
|
if (cm->cd[co].nchrs == 1) /* optimization */
|
||||||
return co;
|
return co;
|
||||||
sco = newcolor(cm); /* must create subcolor */
|
sco = newcolor(cm); /* must create subcolor */
|
||||||
if (sco == COLORLESS)
|
if (sco == COLORLESS) {
|
||||||
{
|
|
||||||
assert(CISERR());
|
assert(CISERR());
|
||||||
return COLORLESS;
|
return COLORLESS;
|
||||||
}
|
}
|
||||||
@@ -405,14 +396,17 @@ newsub(struct colormap * cm,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* subrange - allocate new subcolors to this range of chrs, fill in arcs
|
- subrange - allocate new subcolors to this range of chrs, fill in arcs
|
||||||
|
^ static VOID subrange(struct vars *, pchr, pchr, struct state *,
|
||||||
|
^ struct state *);
|
||||||
*/
|
*/
|
||||||
static void
|
static VOID
|
||||||
subrange(struct vars * v,
|
subrange(v, from, to, lp, rp)
|
||||||
chr from,
|
struct vars *v;
|
||||||
chr to,
|
pchr from;
|
||||||
struct state * lp,
|
pchr to;
|
||||||
struct state * rp)
|
struct state *lp;
|
||||||
|
struct state *rp;
|
||||||
{
|
{
|
||||||
uchr uf;
|
uchr uf;
|
||||||
int i;
|
int i;
|
||||||
@@ -420,8 +414,8 @@ subrange(struct vars * v,
|
|||||||
assert(from <= to);
|
assert(from <= to);
|
||||||
|
|
||||||
/* first, align "from" on a tree-block boundary */
|
/* first, align "from" on a tree-block boundary */
|
||||||
uf = (uchr) from;
|
uf = (uchr)from;
|
||||||
i = (int) (((uf + BYTTAB - 1) & (uchr) ~BYTMASK) - uf);
|
i = (int)( ((uf + BYTTAB-1) & (uchr)~BYTMASK) - uf );
|
||||||
for (; from <= to && i > 0; i--, from++)
|
for (; from <= to && i > 0; i--, from++)
|
||||||
newarc(v->nfa, PLAIN, subcolor(v->cm, from), lp, rp);
|
newarc(v->nfa, PLAIN, subcolor(v->cm, from), lp, rp);
|
||||||
if (from > to) /* didn't reach a boundary */
|
if (from > to) /* didn't reach a boundary */
|
||||||
@@ -437,13 +431,15 @@ subrange(struct vars * v,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* subblock - allocate new subcolors for one tree block of chrs, fill in arcs
|
- subblock - allocate new subcolors for one tree block of chrs, fill in arcs
|
||||||
|
^ static VOID subblock(struct vars *, pchr, struct state *, struct state *);
|
||||||
*/
|
*/
|
||||||
static void
|
static VOID
|
||||||
subblock(struct vars * v,
|
subblock(v, start, lp, rp)
|
||||||
chr start, /* first of BYTTAB chrs */
|
struct vars *v;
|
||||||
struct state * lp,
|
pchr start; /* first of BYTTAB chrs */
|
||||||
struct state * rp)
|
struct state *lp;
|
||||||
|
struct state *rp;
|
||||||
{
|
{
|
||||||
uchr uc = start;
|
uchr uc = start;
|
||||||
struct colormap *cm = v->cm;
|
struct colormap *cm = v->cm;
|
||||||
@@ -466,23 +462,20 @@ subblock(struct vars * v,
|
|||||||
t = cm->tree;
|
t = cm->tree;
|
||||||
fillt = NULL;
|
fillt = NULL;
|
||||||
for (level = 0, shift = BYTBITS * (NBYTS - 1); shift > 0;
|
for (level = 0, shift = BYTBITS * (NBYTS - 1); shift > 0;
|
||||||
level++, shift -= BYTBITS)
|
level++, shift -= BYTBITS) {
|
||||||
{
|
|
||||||
b = (uc >> shift) & BYTMASK;
|
b = (uc >> shift) & BYTMASK;
|
||||||
lastt = t;
|
lastt = t;
|
||||||
t = lastt->tptr[b];
|
t = lastt->tptr[b];
|
||||||
assert(t != NULL);
|
assert(t != NULL);
|
||||||
fillt = &cm->tree[level + 1];
|
fillt = &cm->tree[level+1];
|
||||||
if (t == fillt && shift > BYTBITS)
|
if (t == fillt && shift > BYTBITS) { /* need new ptr block */
|
||||||
{ /* need new ptr block */
|
t = (union tree *)MALLOC(sizeof(struct ptrs));
|
||||||
t = (union tree *) MALLOC(sizeof(struct ptrs));
|
if (t == NULL) {
|
||||||
if (t == NULL)
|
|
||||||
{
|
|
||||||
CERR(REG_ESPACE);
|
CERR(REG_ESPACE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
memcpy(VS(t->tptr), VS(fillt->tptr),
|
memcpy(VS(t->tptr), VS(fillt->tptr),
|
||||||
BYTTAB * sizeof(union tree *));
|
BYTTAB*sizeof(union tree *));
|
||||||
lastt->tptr[b] = t;
|
lastt->tptr[b] = t;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -490,16 +483,13 @@ subblock(struct vars * v,
|
|||||||
/* special cases: fill block or solid block */
|
/* special cases: fill block or solid block */
|
||||||
co = t->tcolor[0];
|
co = t->tcolor[0];
|
||||||
cb = cm->cd[co].block;
|
cb = cm->cd[co].block;
|
||||||
if (t == fillt || t == cb)
|
if (t == fillt || t == cb) {
|
||||||
{
|
|
||||||
/* either way, we want a subcolor solid block */
|
/* either way, we want a subcolor solid block */
|
||||||
sco = newsub(cm, co);
|
sco = newsub(cm, co);
|
||||||
t = cm->cd[sco].block;
|
t = cm->cd[sco].block;
|
||||||
if (t == NULL)
|
if (t == NULL) { /* must set it up */
|
||||||
{ /* must set it up */
|
t = (union tree *)MALLOC(sizeof(struct colors));
|
||||||
t = (union tree *) MALLOC(sizeof(struct colors));
|
if (t == NULL) {
|
||||||
if (t == NULL)
|
|
||||||
{
|
|
||||||
CERR(REG_ESPACE);
|
CERR(REG_ESPACE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -517,14 +507,12 @@ subblock(struct vars * v,
|
|||||||
|
|
||||||
/* general case, a mixed block to be altered */
|
/* general case, a mixed block to be altered */
|
||||||
i = 0;
|
i = 0;
|
||||||
while (i < BYTTAB)
|
while (i < BYTTAB) {
|
||||||
{
|
|
||||||
co = t->tcolor[i];
|
co = t->tcolor[i];
|
||||||
sco = newsub(cm, co);
|
sco = newsub(cm, co);
|
||||||
newarc(v->nfa, PLAIN, sco, lp, rp);
|
newarc(v->nfa, PLAIN, sco, lp, rp);
|
||||||
previ = i;
|
previ = i;
|
||||||
do
|
do {
|
||||||
{
|
|
||||||
t->tcolor[i++] = sco;
|
t->tcolor[i++] = sco;
|
||||||
} while (i < BYTTAB && t->tcolor[i] == co);
|
} while (i < BYTTAB && t->tcolor[i] == co);
|
||||||
ndone = i - previ;
|
ndone = i - previ;
|
||||||
@@ -534,11 +522,13 @@ subblock(struct vars * v,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* okcolors - promote subcolors to full colors
|
- okcolors - promote subcolors to full colors
|
||||||
|
^ static VOID okcolors(struct nfa *, struct colormap *);
|
||||||
*/
|
*/
|
||||||
static void
|
static VOID
|
||||||
okcolors(struct nfa * nfa,
|
okcolors(nfa, cm)
|
||||||
struct colormap * cm)
|
struct nfa *nfa;
|
||||||
|
struct colormap *cm;
|
||||||
{
|
{
|
||||||
struct colordesc *cd;
|
struct colordesc *cd;
|
||||||
struct colordesc *end = CDEND(cm);
|
struct colordesc *end = CDEND(cm);
|
||||||
@@ -547,27 +537,20 @@ okcolors(struct nfa * nfa,
|
|||||||
color co;
|
color co;
|
||||||
color sco;
|
color sco;
|
||||||
|
|
||||||
for (cd = cm->cd, co = 0; cd < end; cd++, co++)
|
for (cd = cm->cd, co = 0; cd < end; cd++, co++) {
|
||||||
{
|
|
||||||
sco = cd->sub;
|
sco = cd->sub;
|
||||||
if (UNUSEDCOLOR(cd) || sco == NOSUB)
|
if (UNUSEDCOLOR(cd) || sco == NOSUB) {
|
||||||
{
|
|
||||||
/* has no subcolor, no further action */
|
/* has no subcolor, no further action */
|
||||||
}
|
} else if (sco == co) {
|
||||||
else if (sco == co)
|
|
||||||
{
|
|
||||||
/* is subcolor, let parent deal with it */
|
/* is subcolor, let parent deal with it */
|
||||||
}
|
} else if (cd->nchrs == 0) {
|
||||||
else if (cd->nchrs == 0)
|
|
||||||
{
|
|
||||||
/* parent empty, its arcs change color to subcolor */
|
/* parent empty, its arcs change color to subcolor */
|
||||||
cd->sub = NOSUB;
|
cd->sub = NOSUB;
|
||||||
scd = &cm->cd[sco];
|
scd = &cm->cd[sco];
|
||||||
assert(scd->nchrs > 0);
|
assert(scd->nchrs > 0);
|
||||||
assert(scd->sub == sco);
|
assert(scd->sub == sco);
|
||||||
scd->sub = NOSUB;
|
scd->sub = NOSUB;
|
||||||
while ((a = cd->arcs) != NULL)
|
while ((a = cd->arcs) != NULL) {
|
||||||
{
|
|
||||||
assert(a->co == co);
|
assert(a->co == co);
|
||||||
/* uncolorchain(cm, a); */
|
/* uncolorchain(cm, a); */
|
||||||
cd->arcs = a->colorchain;
|
cd->arcs = a->colorchain;
|
||||||
@@ -577,17 +560,14 @@ okcolors(struct nfa * nfa,
|
|||||||
scd->arcs = a;
|
scd->arcs = a;
|
||||||
}
|
}
|
||||||
freecolor(cm, co);
|
freecolor(cm, co);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
/* parent's arcs must gain parallel subcolor arcs */
|
/* parent's arcs must gain parallel subcolor arcs */
|
||||||
cd->sub = NOSUB;
|
cd->sub = NOSUB;
|
||||||
scd = &cm->cd[sco];
|
scd = &cm->cd[sco];
|
||||||
assert(scd->nchrs > 0);
|
assert(scd->nchrs > 0);
|
||||||
assert(scd->sub == sco);
|
assert(scd->sub == sco);
|
||||||
scd->sub = NOSUB;
|
scd->sub = NOSUB;
|
||||||
for (a = cd->arcs; a != NULL; a = a->colorchain)
|
for (a = cd->arcs; a != NULL; a = a->colorchain) {
|
||||||
{
|
|
||||||
assert(a->co == co);
|
assert(a->co == co);
|
||||||
newarc(nfa, a->type, sco, a->from, a->to);
|
newarc(nfa, a->type, sco, a->from, a->to);
|
||||||
}
|
}
|
||||||
@@ -596,11 +576,13 @@ okcolors(struct nfa * nfa,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* colorchain - add this arc to the color chain of its color
|
- colorchain - add this arc to the color chain of its color
|
||||||
|
^ static VOID colorchain(struct colormap *, struct arc *);
|
||||||
*/
|
*/
|
||||||
static void
|
static VOID
|
||||||
colorchain(struct colormap * cm,
|
colorchain(cm, a)
|
||||||
struct arc * a)
|
struct colormap *cm;
|
||||||
|
struct arc *a;
|
||||||
{
|
{
|
||||||
struct colordesc *cd = &cm->cd[a->co];
|
struct colordesc *cd = &cm->cd[a->co];
|
||||||
|
|
||||||
@@ -609,11 +591,13 @@ colorchain(struct colormap * cm,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* uncolorchain - delete this arc from the color chain of its color
|
- uncolorchain - delete this arc from the color chain of its color
|
||||||
|
^ static VOID uncolorchain(struct colormap *, struct arc *);
|
||||||
*/
|
*/
|
||||||
static void
|
static VOID
|
||||||
uncolorchain(struct colormap * cm,
|
uncolorchain(cm, a)
|
||||||
struct arc * a)
|
struct colormap *cm;
|
||||||
|
struct arc *a;
|
||||||
{
|
{
|
||||||
struct colordesc *cd = &cm->cd[a->co];
|
struct colordesc *cd = &cm->cd[a->co];
|
||||||
struct arc *aa;
|
struct arc *aa;
|
||||||
@@ -621,8 +605,7 @@ uncolorchain(struct colormap * cm,
|
|||||||
aa = cd->arcs;
|
aa = cd->arcs;
|
||||||
if (aa == a) /* easy case */
|
if (aa == a) /* easy case */
|
||||||
cd->arcs = a->colorchain;
|
cd->arcs = a->colorchain;
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
for (; aa != NULL && aa->colorchain != a; aa = aa->colorchain)
|
for (; aa != NULL && aa->colorchain != a; aa = aa->colorchain)
|
||||||
continue;
|
continue;
|
||||||
assert(aa != NULL);
|
assert(aa != NULL);
|
||||||
@@ -632,11 +615,13 @@ uncolorchain(struct colormap * cm,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* singleton - is this character in its own color?
|
- singleton - is this character in its own color?
|
||||||
|
^ static int singleton(struct colormap *, pchr c);
|
||||||
*/
|
*/
|
||||||
static int /* predicate */
|
static int /* predicate */
|
||||||
singleton(struct colormap * cm,
|
singleton(cm, c)
|
||||||
chr c)
|
struct colormap *cm;
|
||||||
|
pchr c;
|
||||||
{
|
{
|
||||||
color co; /* color of c */
|
color co; /* color of c */
|
||||||
|
|
||||||
@@ -647,15 +632,18 @@ singleton(struct colormap * cm,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* rainbow - add arcs of all full colors (but one) between specified states
|
- rainbow - add arcs of all full colors (but one) between specified states
|
||||||
|
^ static VOID rainbow(struct nfa *, struct colormap *, int, pcolor,
|
||||||
|
^ struct state *, struct state *);
|
||||||
*/
|
*/
|
||||||
static void
|
static VOID
|
||||||
rainbow(struct nfa * nfa,
|
rainbow(nfa, cm, type, but, from, to)
|
||||||
struct colormap * cm,
|
struct nfa *nfa;
|
||||||
int type,
|
struct colormap *cm;
|
||||||
pcolor but, /* COLORLESS if no exceptions */
|
int type;
|
||||||
struct state * from,
|
pcolor but; /* COLORLESS if no exceptions */
|
||||||
struct state * to)
|
struct state *from;
|
||||||
|
struct state *to;
|
||||||
{
|
{
|
||||||
struct colordesc *cd;
|
struct colordesc *cd;
|
||||||
struct colordesc *end = CDEND(cm);
|
struct colordesc *end = CDEND(cm);
|
||||||
@@ -663,23 +651,24 @@ rainbow(struct nfa * nfa,
|
|||||||
|
|
||||||
for (cd = cm->cd, co = 0; cd < end && !CISERR(); cd++, co++)
|
for (cd = cm->cd, co = 0; cd < end && !CISERR(); cd++, co++)
|
||||||
if (!UNUSEDCOLOR(cd) && cd->sub != co && co != but &&
|
if (!UNUSEDCOLOR(cd) && cd->sub != co && co != but &&
|
||||||
!(cd->flags & PSEUDO))
|
!(cd->flags&PSEUDO))
|
||||||
newarc(nfa, type, co, from, to);
|
newarc(nfa, type, co, from, to);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* colorcomplement - add arcs of complementary colors
|
- colorcomplement - add arcs of complementary colors
|
||||||
*
|
|
||||||
* The calling sequence ought to be reconciled with cloneouts().
|
* The calling sequence ought to be reconciled with cloneouts().
|
||||||
|
^ static VOID colorcomplement(struct nfa *, struct colormap *, int,
|
||||||
|
^ struct state *, struct state *, struct state *);
|
||||||
*/
|
*/
|
||||||
static void
|
static VOID
|
||||||
colorcomplement(struct nfa * nfa,
|
colorcomplement(nfa, cm, type, of, from, to)
|
||||||
struct colormap * cm,
|
struct nfa *nfa;
|
||||||
int type,
|
struct colormap *cm;
|
||||||
struct state * of, /* complements of this guy's PLAIN
|
int type;
|
||||||
* outarcs */
|
struct state *of; /* complements of this guy's PLAIN outarcs */
|
||||||
struct state * from,
|
struct state *from;
|
||||||
struct state * to)
|
struct state *to;
|
||||||
{
|
{
|
||||||
struct colordesc *cd;
|
struct colordesc *cd;
|
||||||
struct colordesc *end = CDEND(cm);
|
struct colordesc *end = CDEND(cm);
|
||||||
@@ -687,20 +676,26 @@ colorcomplement(struct nfa * nfa,
|
|||||||
|
|
||||||
assert(of != from);
|
assert(of != from);
|
||||||
for (cd = cm->cd, co = 0; cd < end && !CISERR(); cd++, co++)
|
for (cd = cm->cd, co = 0; cd < end && !CISERR(); cd++, co++)
|
||||||
if (!UNUSEDCOLOR(cd) && !(cd->flags & PSEUDO))
|
if (!UNUSEDCOLOR(cd) && !(cd->flags&PSEUDO))
|
||||||
if (findarc(of, PLAIN, co) == NULL)
|
if (findarc(of, PLAIN, co) == NULL)
|
||||||
newarc(nfa, type, co, from, to);
|
newarc(nfa, type, co, from, to);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef REG_DEBUG
|
#ifdef REG_DEBUG
|
||||||
|
/*
|
||||||
|
^ #ifdef REG_DEBUG
|
||||||
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* dumpcolors - debugging output
|
- dumpcolors - debugging output
|
||||||
|
^ static VOID dumpcolors(struct colormap *, FILE *);
|
||||||
*/
|
*/
|
||||||
static void
|
static VOID
|
||||||
dumpcolors(struct colormap * cm,
|
dumpcolors(cm, f)
|
||||||
FILE *f)
|
struct colormap *cm;
|
||||||
|
FILE *f;
|
||||||
{
|
{
|
||||||
struct colordesc *cd;
|
struct colordesc *cd;
|
||||||
struct colordesc *end;
|
struct colordesc *end;
|
||||||
@@ -708,19 +703,18 @@ dumpcolors(struct colormap * cm,
|
|||||||
chr c;
|
chr c;
|
||||||
char *has;
|
char *has;
|
||||||
|
|
||||||
fprintf(f, "max %ld\n", (long) cm->max);
|
fprintf(f, "max %ld\n", (long)cm->max);
|
||||||
if (NBYTS > 1)
|
if (NBYTS > 1)
|
||||||
fillcheck(cm, cm->tree, 0, f);
|
fillcheck(cm, cm->tree, 0, f);
|
||||||
end = CDEND(cm);
|
end = CDEND(cm);
|
||||||
for (cd = cm->cd + 1, co = 1; cd < end; cd++, co++) /* skip 0 */
|
for (cd = cm->cd + 1, co = 1; cd < end; cd++, co++) /* skip 0 */
|
||||||
if (!UNUSEDCOLOR(cd))
|
if (!UNUSEDCOLOR(cd)) {
|
||||||
{
|
|
||||||
assert(cd->nchrs > 0);
|
assert(cd->nchrs > 0);
|
||||||
has = (cd->block != NULL) ? "#" : "";
|
has = (cd->block != NULL) ? "#" : "";
|
||||||
if (cd->flags & PSEUDO)
|
if (cd->flags&PSEUDO)
|
||||||
fprintf(f, "#%2ld%s(ps): ", (long) co, has);
|
fprintf(f, "#%2ld%s(ps): ", (long)co, has);
|
||||||
else
|
else
|
||||||
fprintf(f, "#%2ld%s(%2d): ", (long) co,
|
fprintf(f, "#%2ld%s(%2d): ", (long)co,
|
||||||
has, cd->nchrs);
|
has, cd->nchrs);
|
||||||
/* it's hard to do this more efficiently */
|
/* it's hard to do this more efficiently */
|
||||||
for (c = CHR_MIN; c < CHR_MAX; c++)
|
for (c = CHR_MIN; c < CHR_MAX; c++)
|
||||||
@@ -734,51 +728,51 @@ dumpcolors(struct colormap * cm,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* fillcheck - check proper filling of a tree
|
- fillcheck - check proper filling of a tree
|
||||||
|
^ static VOID fillcheck(struct colormap *, union tree *, int, FILE *);
|
||||||
*/
|
*/
|
||||||
static void
|
static VOID
|
||||||
fillcheck(struct colormap * cm,
|
fillcheck(cm, tree, level, f)
|
||||||
union tree * tree,
|
struct colormap *cm;
|
||||||
int level, /* level number (top == 0) of this block */
|
union tree *tree;
|
||||||
FILE *f)
|
int level; /* level number (top == 0) of this block */
|
||||||
|
FILE *f;
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
union tree *t;
|
union tree *t;
|
||||||
union tree *fillt = &cm->tree[level + 1];
|
union tree *fillt = &cm->tree[level+1];
|
||||||
|
|
||||||
assert(level < NBYTS - 1); /* this level has pointers */
|
assert(level < NBYTS-1); /* this level has pointers */
|
||||||
for (i = BYTTAB - 1; i >= 0; i--)
|
for (i = BYTTAB-1; i >= 0; i--) {
|
||||||
{
|
|
||||||
t = tree->tptr[i];
|
t = tree->tptr[i];
|
||||||
if (t == NULL)
|
if (t == NULL)
|
||||||
fprintf(f, "NULL found in filled tree!\n");
|
fprintf(f, "NULL found in filled tree!\n");
|
||||||
else if (t == fillt)
|
else if (t == fillt)
|
||||||
{
|
{}
|
||||||
}
|
else if (level < NBYTS-2) /* more pointer blocks below */
|
||||||
else if (level < NBYTS - 2) /* more pointer blocks below */
|
fillcheck(cm, t, level+1, f);
|
||||||
fillcheck(cm, t, level + 1, f);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* dumpchr - print a chr
|
- dumpchr - print a chr
|
||||||
*
|
|
||||||
* Kind of char-centric but works well enough for debug use.
|
* Kind of char-centric but works well enough for debug use.
|
||||||
|
^ static VOID dumpchr(pchr, FILE *);
|
||||||
*/
|
*/
|
||||||
static void
|
static VOID
|
||||||
dumpchr(chr c,
|
dumpchr(c, f)
|
||||||
FILE *f)
|
pchr c;
|
||||||
|
FILE *f;
|
||||||
{
|
{
|
||||||
#if wxUSE_UNICODE
|
|
||||||
fprintf(f, "Debugging not implemented in unicode mode");
|
|
||||||
#else
|
|
||||||
if (c == '\\')
|
if (c == '\\')
|
||||||
fprintf(f, "\\\\");
|
fprintf(f, "\\\\");
|
||||||
else if (c > ' ' && c <= '~')
|
else if (c > ' ' && c <= '~')
|
||||||
putc((char) c, f);
|
putc((char)c, f);
|
||||||
else
|
else
|
||||||
fprintf(f, "\\u%04lx", (long) c);
|
fprintf(f, "\\u%04lx", (long)c);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* REG_DEBUG */
|
/*
|
||||||
|
^ #endif
|
||||||
|
*/
|
||||||
|
#endif /* ifdef REG_DEBUG */
|
||||||
|
@@ -28,162 +28,181 @@
|
|||||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $Header$
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* newcvec - allocate a new cvec
|
- newcvec - allocate a new cvec
|
||||||
|
^ static struct cvec *newcvec(int, int, int);
|
||||||
*/
|
*/
|
||||||
static struct cvec *
|
static struct cvec *
|
||||||
newcvec(int nchrs, /* to hold this many chrs... */
|
newcvec(nchrs, nranges, nmcces)
|
||||||
int nranges, /* ... and this many ranges... */
|
int nchrs; /* to hold this many chrs... */
|
||||||
int nmcces) /* ... and this many MCCEs */
|
int nranges; /* ... and this many ranges... */
|
||||||
|
int nmcces; /* ... and this many MCCEs */
|
||||||
{
|
{
|
||||||
size_t n;
|
size_t n;
|
||||||
size_t nc;
|
size_t nc;
|
||||||
struct cvec *cv;
|
struct cvec *cv;
|
||||||
|
|
||||||
nc = (size_t) nchrs + (size_t) nmcces *(MAXMCCE + 1) + (size_t) nranges *2;
|
nc = (size_t)nchrs + (size_t)nmcces*(MAXMCCE+1) + (size_t)nranges*2;
|
||||||
|
n = sizeof(struct cvec) + (size_t)(nmcces-1)*sizeof(chr *)
|
||||||
n = sizeof(struct cvec) + (size_t) (nmcces - 1) * sizeof(chr *)
|
+ nc*sizeof(chr);
|
||||||
+ nc * sizeof(chr);
|
cv = (struct cvec *)MALLOC(n);
|
||||||
cv = (struct cvec *) MALLOC(n);
|
if (cv == NULL) {
|
||||||
if (cv == NULL)
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
cv->chrspace = nchrs;
|
cv->chrspace = nchrs;
|
||||||
cv->chrs = (chr *) &cv->mcces[nmcces]; /* chrs just after MCCE
|
cv->chrs = (chr *)&cv->mcces[nmcces]; /* chrs just after MCCE ptrs */
|
||||||
* ptrs */
|
|
||||||
cv->mccespace = nmcces;
|
cv->mccespace = nmcces;
|
||||||
cv->ranges = cv->chrs + nchrs + nmcces * (MAXMCCE + 1);
|
cv->ranges = cv->chrs + nchrs + nmcces*(MAXMCCE+1);
|
||||||
cv->rangespace = nranges;
|
cv->rangespace = nranges;
|
||||||
return clearcvec(cv);
|
return clearcvec(cv);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* clearcvec - clear a possibly-new cvec
|
- clearcvec - clear a possibly-new cvec
|
||||||
* Returns pointer as convenience.
|
* Returns pointer as convenience.
|
||||||
|
^ static struct cvec *clearcvec(struct cvec *);
|
||||||
*/
|
*/
|
||||||
static struct cvec *
|
static struct cvec *
|
||||||
clearcvec(struct cvec * cv)
|
clearcvec(cv)
|
||||||
|
struct cvec *cv; /* character vector */
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
assert(cv != NULL);
|
assert(cv != NULL);
|
||||||
cv->nchrs = 0;
|
cv->nchrs = 0;
|
||||||
assert(cv->chrs == (chr *) &cv->mcces[cv->mccespace]);
|
assert(cv->chrs == (chr *)&cv->mcces[cv->mccespace]);
|
||||||
cv->nmcces = 0;
|
cv->nmcces = 0;
|
||||||
cv->nmccechrs = 0;
|
cv->nmccechrs = 0;
|
||||||
cv->nranges = 0;
|
cv->nranges = 0;
|
||||||
for (i = 0; i < cv->mccespace; i++)
|
for (i = 0; i < cv->mccespace; i++) {
|
||||||
cv->mcces[i] = NULL;
|
cv->mcces[i] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
return cv;
|
return cv;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* addchr - add a chr to a cvec
|
- addchr - add a chr to a cvec
|
||||||
|
^ static VOID addchr(struct cvec *, pchr);
|
||||||
*/
|
*/
|
||||||
static void
|
static VOID
|
||||||
addchr(struct cvec * cv, /* character vector */
|
addchr(cv, c)
|
||||||
chr c) /* character to add */
|
struct cvec *cv; /* character vector */
|
||||||
|
pchr c; /* character to add */
|
||||||
{
|
{
|
||||||
assert(cv->nchrs < cv->chrspace - cv->nmccechrs);
|
assert(cv->nchrs < cv->chrspace - cv->nmccechrs);
|
||||||
cv->chrs[cv->nchrs++] = (chr) c;
|
cv->chrs[cv->nchrs++] = (chr)c;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* addrange - add a range to a cvec
|
- addrange - add a range to a cvec
|
||||||
|
^ static VOID addrange(struct cvec *, pchr, pchr);
|
||||||
*/
|
*/
|
||||||
static void
|
static VOID
|
||||||
addrange(struct cvec * cv, /* character vector */
|
addrange(cv, from, to)
|
||||||
chr from, /* first character of range */
|
struct cvec *cv; /* character vector */
|
||||||
chr to) /* last character of range */
|
pchr from; /* first character of range */
|
||||||
|
pchr to; /* last character of range */
|
||||||
{
|
{
|
||||||
assert(cv->nranges < cv->rangespace);
|
assert(cv->nranges < cv->rangespace);
|
||||||
cv->ranges[cv->nranges * 2] = (chr) from;
|
cv->ranges[cv->nranges*2] = (chr)from;
|
||||||
cv->ranges[cv->nranges * 2 + 1] = (chr) to;
|
cv->ranges[cv->nranges*2 + 1] = (chr)to;
|
||||||
cv->nranges++;
|
cv->nranges++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* addmcce - add an MCCE to a cvec
|
- addmcce - add an MCCE to a cvec
|
||||||
|
^ static VOID addmcce(struct cvec *, chr *, chr *);
|
||||||
*/
|
*/
|
||||||
static void
|
static VOID
|
||||||
addmcce(struct cvec * cv, /* character vector */
|
addmcce(cv, startp, endp)
|
||||||
chr *startp, /* beginning of text */
|
struct cvec *cv; /* character vector */
|
||||||
chr *endp) /* just past end of text */
|
chr *startp; /* beginning of text */
|
||||||
|
chr *endp; /* just past end of text */
|
||||||
{
|
{
|
||||||
int len;
|
int len;
|
||||||
int i;
|
int i;
|
||||||
chr *s;
|
chr *s;
|
||||||
chr *d;
|
chr *d;
|
||||||
|
|
||||||
if (startp == NULL && endp == NULL)
|
if (startp == NULL && endp == NULL) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
len = endp - startp;
|
len = endp - startp;
|
||||||
assert(len > 0);
|
assert(len > 0);
|
||||||
assert(cv->nchrs + len < cv->chrspace - cv->nmccechrs);
|
assert(cv->nchrs + len < cv->chrspace - cv->nmccechrs);
|
||||||
assert(cv->nmcces < cv->mccespace);
|
assert(cv->nmcces < cv->mccespace);
|
||||||
d = &cv->chrs[cv->chrspace - cv->nmccechrs - len - 1];
|
d = &cv->chrs[cv->chrspace - cv->nmccechrs - len - 1];
|
||||||
cv->mcces[cv->nmcces++] = d;
|
cv->mcces[cv->nmcces++] = d;
|
||||||
for (s = startp, i = len; i > 0; s++, i--)
|
for (s = startp, i = len; i > 0; s++, i--) {
|
||||||
*d++ = *s;
|
*d++ = *s;
|
||||||
|
}
|
||||||
*d++ = 0; /* endmarker */
|
*d++ = 0; /* endmarker */
|
||||||
assert(d == &cv->chrs[cv->chrspace - cv->nmccechrs]);
|
assert(d == &cv->chrs[cv->chrspace - cv->nmccechrs]);
|
||||||
cv->nmccechrs += len + 1;
|
cv->nmccechrs += len + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* haschr - does a cvec contain this chr?
|
- haschr - does a cvec contain this chr?
|
||||||
|
^ static int haschr(struct cvec *, pchr);
|
||||||
*/
|
*/
|
||||||
static int /* predicate */
|
static int /* predicate */
|
||||||
haschr(struct cvec * cv, /* character vector */
|
haschr(cv, c)
|
||||||
chr c) /* character to test for */
|
struct cvec *cv; /* character vector */
|
||||||
|
pchr c; /* character to test for */
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
chr *p;
|
chr *p;
|
||||||
|
|
||||||
for (p = cv->chrs, i = cv->nchrs; i > 0; p++, i--)
|
for (p = cv->chrs, i = cv->nchrs; i > 0; p++, i--) {
|
||||||
{
|
if (*p == c) {
|
||||||
if (*p == c)
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
for (p = cv->ranges, i = cv->nranges; i > 0; p += 2, i--)
|
}
|
||||||
{
|
for (p = cv->ranges, i = cv->nranges; i > 0; p += 2, i--) {
|
||||||
if ((*p <= c) && (c <= *(p + 1)))
|
if ((*p <= c) && (c <= *(p+1))) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* getcvec - get a cvec, remembering it as v->cv
|
- getcvec - get a cvec, remembering it as v->cv
|
||||||
|
^ static struct cvec *getcvec(struct vars *, int, int, int);
|
||||||
*/
|
*/
|
||||||
static struct cvec *
|
static struct cvec *
|
||||||
getcvec(struct vars * v, /* context */
|
getcvec(v, nchrs, nranges, nmcces)
|
||||||
int nchrs, /* to hold this many chrs... */
|
struct vars *v; /* context */
|
||||||
int nranges, /* ... and this many ranges... */
|
int nchrs; /* to hold this many chrs... */
|
||||||
int nmcces) /* ... and this many MCCEs */
|
int nranges; /* ... and this many ranges... */
|
||||||
|
int nmcces; /* ... and this many MCCEs */
|
||||||
{
|
{
|
||||||
if (v->cv != NULL && nchrs <= v->cv->chrspace &&
|
if (v->cv != NULL && nchrs <= v->cv->chrspace &&
|
||||||
nranges <= v->cv->rangespace && nmcces <= v->cv->mccespace)
|
nranges <= v->cv->rangespace && nmcces <= v->cv->mccespace) {
|
||||||
return clearcvec(v->cv);
|
return clearcvec(v->cv);
|
||||||
|
}
|
||||||
|
|
||||||
if (v->cv != NULL)
|
if (v->cv != NULL) {
|
||||||
freecvec(v->cv);
|
freecvec(v->cv);
|
||||||
|
}
|
||||||
v->cv = newcvec(nchrs, nranges, nmcces);
|
v->cv = newcvec(nchrs, nranges, nmcces);
|
||||||
if (v->cv == NULL)
|
if (v->cv == NULL) {
|
||||||
ERR(REG_ESPACE);
|
ERR(REG_ESPACE);
|
||||||
|
}
|
||||||
|
|
||||||
return v->cv;
|
return v->cv;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* freecvec - free a cvec
|
- freecvec - free a cvec
|
||||||
|
^ static VOID freecvec(struct cvec *);
|
||||||
*/
|
*/
|
||||||
static void
|
static VOID
|
||||||
freecvec(struct cvec * cv)
|
freecvec(cv)
|
||||||
|
struct cvec *cv; /* character vector */
|
||||||
{
|
{
|
||||||
FREE(cv);
|
FREE(cv);
|
||||||
}
|
}
|
||||||
|
@@ -28,8 +28,6 @@
|
|||||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $Header$
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* scanning macros (know about v) */
|
/* scanning macros (know about v) */
|
||||||
@@ -64,27 +62,24 @@
|
|||||||
#define ENDOF(array) ((array) + sizeof(array)/sizeof(chr))
|
#define ENDOF(array) ((array) + sizeof(array)/sizeof(chr))
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* lexstart - set up lexical stuff, scan leading options
|
- lexstart - set up lexical stuff, scan leading options
|
||||||
|
^ static VOID lexstart(struct vars *);
|
||||||
*/
|
*/
|
||||||
static void
|
static VOID
|
||||||
lexstart(struct vars * v)
|
lexstart(v)
|
||||||
|
struct vars *v;
|
||||||
{
|
{
|
||||||
prefixes(v); /* may turn on new type bits etc. */
|
prefixes(v); /* may turn on new type bits etc. */
|
||||||
NOERR();
|
NOERR();
|
||||||
|
|
||||||
if (v->cflags & REG_QUOTE)
|
if (v->cflags®_QUOTE) {
|
||||||
{
|
assert(!(v->cflags&(REG_ADVANCED|REG_EXPANDED|REG_NEWLINE)));
|
||||||
assert(!(v->cflags & (REG_ADVANCED | REG_EXPANDED | REG_NEWLINE)));
|
|
||||||
INTOCON(L_Q);
|
INTOCON(L_Q);
|
||||||
}
|
} else if (v->cflags®_EXTENDED) {
|
||||||
else if (v->cflags & REG_EXTENDED)
|
assert(!(v->cflags®_QUOTE));
|
||||||
{
|
|
||||||
assert(!(v->cflags & REG_QUOTE));
|
|
||||||
INTOCON(L_ERE);
|
INTOCON(L_ERE);
|
||||||
}
|
} else {
|
||||||
else
|
assert(!(v->cflags&(REG_QUOTE|REG_ADVF)));
|
||||||
{
|
|
||||||
assert(!(v->cflags & (REG_QUOTE | REG_ADVF)));
|
|
||||||
INTOCON(L_BRE);
|
INTOCON(L_BRE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,19 +88,20 @@ lexstart(struct vars * v)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* prefixes - implement various special prefixes
|
- prefixes - implement various special prefixes
|
||||||
|
^ static VOID prefixes(struct vars *);
|
||||||
*/
|
*/
|
||||||
static void
|
static VOID
|
||||||
prefixes(struct vars * v)
|
prefixes(v)
|
||||||
|
struct vars *v;
|
||||||
{
|
{
|
||||||
/* literal string doesn't get any of this stuff */
|
/* literal string doesn't get any of this stuff */
|
||||||
if (v->cflags & REG_QUOTE)
|
if (v->cflags®_QUOTE)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* initial "***" gets special things */
|
/* initial "***" gets special things */
|
||||||
if (HAVE(4) && NEXT3('*', '*', '*'))
|
if (HAVE(4) && NEXT3('*', '*', '*'))
|
||||||
switch (*(v->now + 3))
|
switch (*(v->now + 3)) {
|
||||||
{
|
|
||||||
case CHR('?'): /* "***?" error, msg shows version */
|
case CHR('?'): /* "***?" error, msg shows version */
|
||||||
ERR(REG_BADPAT);
|
ERR(REG_BADPAT);
|
||||||
return; /* proceed no further */
|
return; /* proceed no further */
|
||||||
@@ -113,7 +109,7 @@ prefixes(struct vars * v)
|
|||||||
case CHR('='): /* "***=" shifts to literal string */
|
case CHR('='): /* "***=" shifts to literal string */
|
||||||
NOTE(REG_UNONPOSIX);
|
NOTE(REG_UNONPOSIX);
|
||||||
v->cflags |= REG_QUOTE;
|
v->cflags |= REG_QUOTE;
|
||||||
v->cflags &= ~(REG_ADVANCED | REG_EXPANDED | REG_NEWLINE);
|
v->cflags &= ~(REG_ADVANCED|REG_EXPANDED|REG_NEWLINE);
|
||||||
v->now += 4;
|
v->now += 4;
|
||||||
return; /* and there can be no more prefixes */
|
return; /* and there can be no more prefixes */
|
||||||
break;
|
break;
|
||||||
@@ -129,26 +125,24 @@ prefixes(struct vars * v)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* BREs and EREs don't get embedded options */
|
/* BREs and EREs don't get embedded options */
|
||||||
if ((v->cflags & REG_ADVANCED) != REG_ADVANCED)
|
if ((v->cflags®_ADVANCED) != REG_ADVANCED)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* embedded options (AREs only) */
|
/* embedded options (AREs only) */
|
||||||
if (HAVE(3) && NEXT2('(', '?') && iscalpha(*(v->now + 2)))
|
if (HAVE(3) && NEXT2('(', '?') && iscalpha(*(v->now + 2))) {
|
||||||
{
|
|
||||||
NOTE(REG_UNONPOSIX);
|
NOTE(REG_UNONPOSIX);
|
||||||
v->now += 2;
|
v->now += 2;
|
||||||
for (; !ATEOS() && iscalpha(*v->now); v->now++)
|
for (; !ATEOS() && iscalpha(*v->now); v->now++)
|
||||||
switch (*v->now)
|
switch (*v->now) {
|
||||||
{
|
|
||||||
case CHR('b'): /* BREs (but why???) */
|
case CHR('b'): /* BREs (but why???) */
|
||||||
v->cflags &= ~(REG_ADVANCED | REG_QUOTE);
|
v->cflags &= ~(REG_ADVANCED|REG_QUOTE);
|
||||||
break;
|
break;
|
||||||
case CHR('c'): /* case sensitive */
|
case CHR('c'): /* case sensitive */
|
||||||
v->cflags &= ~REG_ICASE;
|
v->cflags &= ~REG_ICASE;
|
||||||
break;
|
break;
|
||||||
case CHR('e'): /* plain EREs */
|
case CHR('e'): /* plain EREs */
|
||||||
v->cflags |= REG_EXTENDED;
|
v->cflags |= REG_EXTENDED;
|
||||||
v->cflags &= ~(REG_ADVF | REG_QUOTE);
|
v->cflags &= ~(REG_ADVF|REG_QUOTE);
|
||||||
break;
|
break;
|
||||||
case CHR('i'): /* case insensitive */
|
case CHR('i'): /* case insensitive */
|
||||||
v->cflags |= REG_ICASE;
|
v->cflags |= REG_ICASE;
|
||||||
@@ -182,27 +176,27 @@ prefixes(struct vars * v)
|
|||||||
ERR(REG_BADOPT);
|
ERR(REG_BADOPT);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!NEXT1(')'))
|
if (!NEXT1(')')) {
|
||||||
{
|
|
||||||
ERR(REG_BADOPT);
|
ERR(REG_BADOPT);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
v->now++;
|
v->now++;
|
||||||
if (v->cflags & REG_QUOTE)
|
if (v->cflags®_QUOTE)
|
||||||
v->cflags &= ~(REG_EXPANDED | REG_NEWLINE);
|
v->cflags &= ~(REG_EXPANDED|REG_NEWLINE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* lexnest - "call a subroutine", interpolating string at the lexical level
|
- lexnest - "call a subroutine", interpolating string at the lexical level
|
||||||
*
|
|
||||||
* Note, this is not a very general facility. There are a number of
|
* Note, this is not a very general facility. There are a number of
|
||||||
* implicit assumptions about what sorts of strings can be subroutines.
|
* implicit assumptions about what sorts of strings can be subroutines.
|
||||||
|
^ static VOID lexnest(struct vars *, chr *, chr *);
|
||||||
*/
|
*/
|
||||||
static void
|
static VOID
|
||||||
lexnest(struct vars * v,
|
lexnest(v, beginp, endp)
|
||||||
chr *beginp, /* start of interpolation */
|
struct vars *v;
|
||||||
chr *endp) /* one past end of interpolation */
|
chr *beginp; /* start of interpolation */
|
||||||
|
chr *endp; /* one past end of interpolation */
|
||||||
{
|
{
|
||||||
assert(v->savenow == NULL); /* only one level of nesting */
|
assert(v->savenow == NULL); /* only one level of nesting */
|
||||||
v->savenow = v->now;
|
v->savenow = v->now;
|
||||||
@@ -261,20 +255,24 @@ static chr brbackw[] = { /* \w within brackets */
|
|||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* lexword - interpolate a bracket expression for word characters
|
- lexword - interpolate a bracket expression for word characters
|
||||||
* Possibly ought to inquire whether there is a "word" character class.
|
* Possibly ought to inquire whether there is a "word" character class.
|
||||||
|
^ static VOID lexword(struct vars *);
|
||||||
*/
|
*/
|
||||||
static void
|
static VOID
|
||||||
lexword(struct vars * v)
|
lexword(v)
|
||||||
|
struct vars *v;
|
||||||
{
|
{
|
||||||
lexnest(v, backw, ENDOF(backw));
|
lexnest(v, backw, ENDOF(backw));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* next - get next token
|
- next - get next token
|
||||||
|
^ static int next(struct vars *);
|
||||||
*/
|
*/
|
||||||
static int /* 1 normal, 0 failure */
|
static int /* 1 normal, 0 failure */
|
||||||
next(struct vars * v)
|
next(v)
|
||||||
|
struct vars *v;
|
||||||
{
|
{
|
||||||
chr c;
|
chr c;
|
||||||
|
|
||||||
@@ -286,24 +284,21 @@ next(struct vars * v)
|
|||||||
v->lasttype = v->nexttype;
|
v->lasttype = v->nexttype;
|
||||||
|
|
||||||
/* REG_BOSONLY */
|
/* REG_BOSONLY */
|
||||||
if (v->nexttype == EMPTY && (v->cflags & REG_BOSONLY))
|
if (v->nexttype == EMPTY && (v->cflags®_BOSONLY)) {
|
||||||
{
|
|
||||||
/* at start of a REG_BOSONLY RE */
|
/* at start of a REG_BOSONLY RE */
|
||||||
RETV(SBEGIN, 0); /* same as \A */
|
RETV(SBEGIN, 0); /* same as \A */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if we're nested and we've hit end, return to outer level */
|
/* if we're nested and we've hit end, return to outer level */
|
||||||
if (v->savenow != NULL && ATEOS())
|
if (v->savenow != NULL && ATEOS()) {
|
||||||
{
|
|
||||||
v->now = v->savenow;
|
v->now = v->savenow;
|
||||||
v->stop = v->savestop;
|
v->stop = v->savestop;
|
||||||
v->savenow = v->savestop = NULL;
|
v->savenow = v->savestop = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* skip white space etc. if appropriate (not in literal or []) */
|
/* skip white space etc. if appropriate (not in literal or []) */
|
||||||
if (v->cflags & REG_EXPANDED)
|
if (v->cflags®_EXPANDED)
|
||||||
switch (v->lexcon)
|
switch (v->lexcon) {
|
||||||
{
|
|
||||||
case L_ERE:
|
case L_ERE:
|
||||||
case L_BRE:
|
case L_BRE:
|
||||||
case L_EBND:
|
case L_EBND:
|
||||||
@@ -313,10 +308,8 @@ next(struct vars * v)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* handle EOS, depending on context */
|
/* handle EOS, depending on context */
|
||||||
if (ATEOS())
|
if (ATEOS()) {
|
||||||
{
|
switch (v->lexcon) {
|
||||||
switch (v->lexcon)
|
|
||||||
{
|
|
||||||
case L_ERE:
|
case L_ERE:
|
||||||
case L_BRE:
|
case L_BRE:
|
||||||
case L_Q:
|
case L_Q:
|
||||||
@@ -340,8 +333,7 @@ next(struct vars * v)
|
|||||||
c = *v->now++;
|
c = *v->now++;
|
||||||
|
|
||||||
/* deal with the easy contexts, punt EREs to code below */
|
/* deal with the easy contexts, punt EREs to code below */
|
||||||
switch (v->lexcon)
|
switch (v->lexcon) {
|
||||||
{
|
|
||||||
case L_BRE: /* punt BREs to separate function */
|
case L_BRE: /* punt BREs to separate function */
|
||||||
return brenext(v, c);
|
return brenext(v, c);
|
||||||
break;
|
break;
|
||||||
@@ -352,46 +344,33 @@ next(struct vars * v)
|
|||||||
break;
|
break;
|
||||||
case L_BBND: /* bounds are fairly simple */
|
case L_BBND: /* bounds are fairly simple */
|
||||||
case L_EBND:
|
case L_EBND:
|
||||||
switch (c)
|
switch (c) {
|
||||||
{
|
case CHR('0'): case CHR('1'): case CHR('2'): case CHR('3'):
|
||||||
case CHR('0'):
|
case CHR('4'): case CHR('5'): case CHR('6'): case CHR('7'):
|
||||||
case CHR('1'):
|
case CHR('8'): case CHR('9'):
|
||||||
case CHR('2'):
|
RETV(DIGIT, (chr)DIGITVAL(c));
|
||||||
case CHR('3'):
|
|
||||||
case CHR('4'):
|
|
||||||
case CHR('5'):
|
|
||||||
case CHR('6'):
|
|
||||||
case CHR('7'):
|
|
||||||
case CHR('8'):
|
|
||||||
case CHR('9'):
|
|
||||||
RETV(DIGIT, (chr) DIGITVAL(c));
|
|
||||||
break;
|
break;
|
||||||
case CHR(','):
|
case CHR(','):
|
||||||
RET(',');
|
RET(',');
|
||||||
break;
|
break;
|
||||||
case CHR('}'): /* ERE bound ends with } */
|
case CHR('}'): /* ERE bound ends with } */
|
||||||
if (INCON(L_EBND))
|
if (INCON(L_EBND)) {
|
||||||
{
|
|
||||||
INTOCON(L_ERE);
|
INTOCON(L_ERE);
|
||||||
if ((v->cflags & REG_ADVF) && NEXT1('?'))
|
if ((v->cflags®_ADVF) && NEXT1('?')) {
|
||||||
{
|
|
||||||
v->now++;
|
v->now++;
|
||||||
NOTE(REG_UNONPOSIX);
|
NOTE(REG_UNONPOSIX);
|
||||||
RETV('}', 0);
|
RETV('}', 0);
|
||||||
}
|
}
|
||||||
RETV('}', 1);
|
RETV('}', 1);
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
FAILW(REG_BADBR);
|
FAILW(REG_BADBR);
|
||||||
break;
|
break;
|
||||||
case CHR('\\'): /* BRE bound ends with \} */
|
case CHR('\\'): /* BRE bound ends with \} */
|
||||||
if (INCON(L_BBND) && NEXT1('}'))
|
if (INCON(L_BBND) && NEXT1('}')) {
|
||||||
{
|
|
||||||
v->now++;
|
v->now++;
|
||||||
INTOCON(L_BRE);
|
INTOCON(L_BRE);
|
||||||
RET('}');
|
RET('}');
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
FAILW(REG_BADBR);
|
FAILW(REG_BADBR);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -401,34 +380,30 @@ next(struct vars * v)
|
|||||||
assert(NOTREACHED);
|
assert(NOTREACHED);
|
||||||
break;
|
break;
|
||||||
case L_BRACK: /* brackets are not too hard */
|
case L_BRACK: /* brackets are not too hard */
|
||||||
switch (c)
|
switch (c) {
|
||||||
{
|
|
||||||
case CHR(']'):
|
case CHR(']'):
|
||||||
if (LASTTYPE('['))
|
if (LASTTYPE('['))
|
||||||
RETV(PLAIN, c);
|
RETV(PLAIN, c);
|
||||||
else
|
else {
|
||||||
{
|
INTOCON((v->cflags®_EXTENDED) ?
|
||||||
INTOCON((v->cflags & REG_EXTENDED) ?
|
|
||||||
L_ERE : L_BRE);
|
L_ERE : L_BRE);
|
||||||
RET(']');
|
RET(']');
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CHR('\\'):
|
case CHR('\\'):
|
||||||
NOTE(REG_UBBS);
|
NOTE(REG_UBBS);
|
||||||
if (!(v->cflags & REG_ADVF))
|
if (!(v->cflags®_ADVF))
|
||||||
RETV(PLAIN, c);
|
RETV(PLAIN, c);
|
||||||
NOTE(REG_UNONPOSIX);
|
NOTE(REG_UNONPOSIX);
|
||||||
if (ATEOS())
|
if (ATEOS())
|
||||||
FAILW(REG_EESCAPE);
|
FAILW(REG_EESCAPE);
|
||||||
(DISCARD) lexescape(v);
|
(DISCARD)lexescape(v);
|
||||||
switch (v->nexttype)
|
switch (v->nexttype) { /* not all escapes okay here */
|
||||||
{ /* not all escapes okay here */
|
|
||||||
case PLAIN:
|
case PLAIN:
|
||||||
return 1;
|
return 1;
|
||||||
break;
|
break;
|
||||||
case CCLASS:
|
case CCLASS:
|
||||||
switch (v->nextvalue)
|
switch (v->nextvalue) {
|
||||||
{
|
|
||||||
case 'd':
|
case 'd':
|
||||||
lexnest(v, brbackd, ENDOF(brbackd));
|
lexnest(v, brbackd, ENDOF(brbackd));
|
||||||
break;
|
break;
|
||||||
@@ -459,8 +434,7 @@ next(struct vars * v)
|
|||||||
case CHR('['):
|
case CHR('['):
|
||||||
if (ATEOS())
|
if (ATEOS())
|
||||||
FAILW(REG_EBRACK);
|
FAILW(REG_EBRACK);
|
||||||
switch (*v->now++)
|
switch (*v->now++) {
|
||||||
{
|
|
||||||
case CHR('.'):
|
case CHR('.'):
|
||||||
INTOCON(L_CEL);
|
INTOCON(L_CEL);
|
||||||
/* might or might not be locale-specific */
|
/* might or might not be locale-specific */
|
||||||
@@ -490,33 +464,27 @@ next(struct vars * v)
|
|||||||
assert(NOTREACHED);
|
assert(NOTREACHED);
|
||||||
break;
|
break;
|
||||||
case L_CEL: /* collating elements are easy */
|
case L_CEL: /* collating elements are easy */
|
||||||
if (c == CHR('.') && NEXT1(']'))
|
if (c == CHR('.') && NEXT1(']')) {
|
||||||
{
|
|
||||||
v->now++;
|
v->now++;
|
||||||
INTOCON(L_BRACK);
|
INTOCON(L_BRACK);
|
||||||
RETV(END, '.');
|
RETV(END, '.');
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
RETV(PLAIN, c);
|
RETV(PLAIN, c);
|
||||||
break;
|
break;
|
||||||
case L_ECL: /* ditto equivalence classes */
|
case L_ECL: /* ditto equivalence classes */
|
||||||
if (c == CHR('=') && NEXT1(']'))
|
if (c == CHR('=') && NEXT1(']')) {
|
||||||
{
|
|
||||||
v->now++;
|
v->now++;
|
||||||
INTOCON(L_BRACK);
|
INTOCON(L_BRACK);
|
||||||
RETV(END, '=');
|
RETV(END, '=');
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
RETV(PLAIN, c);
|
RETV(PLAIN, c);
|
||||||
break;
|
break;
|
||||||
case L_CCL: /* ditto character classes */
|
case L_CCL: /* ditto character classes */
|
||||||
if (c == CHR(':') && NEXT1(']'))
|
if (c == CHR(':') && NEXT1(']')) {
|
||||||
{
|
|
||||||
v->now++;
|
v->now++;
|
||||||
INTOCON(L_BRACK);
|
INTOCON(L_BRACK);
|
||||||
RETV(END, ':');
|
RETV(END, ':');
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
RETV(PLAIN, c);
|
RETV(PLAIN, c);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -528,14 +496,12 @@ next(struct vars * v)
|
|||||||
assert(INCON(L_ERE));
|
assert(INCON(L_ERE));
|
||||||
|
|
||||||
/* deal with EREs and AREs, except for backslashes */
|
/* deal with EREs and AREs, except for backslashes */
|
||||||
switch (c)
|
switch (c) {
|
||||||
{
|
|
||||||
case CHR('|'):
|
case CHR('|'):
|
||||||
RET('|');
|
RET('|');
|
||||||
break;
|
break;
|
||||||
case CHR('*'):
|
case CHR('*'):
|
||||||
if ((v->cflags & REG_ADVF) && NEXT1('?'))
|
if ((v->cflags®_ADVF) && NEXT1('?')) {
|
||||||
{
|
|
||||||
v->now++;
|
v->now++;
|
||||||
NOTE(REG_UNONPOSIX);
|
NOTE(REG_UNONPOSIX);
|
||||||
RETV('*', 0);
|
RETV('*', 0);
|
||||||
@@ -543,8 +509,7 @@ next(struct vars * v)
|
|||||||
RETV('*', 1);
|
RETV('*', 1);
|
||||||
break;
|
break;
|
||||||
case CHR('+'):
|
case CHR('+'):
|
||||||
if ((v->cflags & REG_ADVF) && NEXT1('?'))
|
if ((v->cflags®_ADVF) && NEXT1('?')) {
|
||||||
{
|
|
||||||
v->now++;
|
v->now++;
|
||||||
NOTE(REG_UNONPOSIX);
|
NOTE(REG_UNONPOSIX);
|
||||||
RETV('+', 0);
|
RETV('+', 0);
|
||||||
@@ -552,8 +517,7 @@ next(struct vars * v)
|
|||||||
RETV('+', 1);
|
RETV('+', 1);
|
||||||
break;
|
break;
|
||||||
case CHR('?'):
|
case CHR('?'):
|
||||||
if ((v->cflags & REG_ADVF) && NEXT1('?'))
|
if ((v->cflags®_ADVF) && NEXT1('?')) {
|
||||||
{
|
|
||||||
v->now++;
|
v->now++;
|
||||||
NOTE(REG_UNONPOSIX);
|
NOTE(REG_UNONPOSIX);
|
||||||
RETV('?', 0);
|
RETV('?', 0);
|
||||||
@@ -561,16 +525,13 @@ next(struct vars * v)
|
|||||||
RETV('?', 1);
|
RETV('?', 1);
|
||||||
break;
|
break;
|
||||||
case CHR('{'): /* bounds start or plain character */
|
case CHR('{'): /* bounds start or plain character */
|
||||||
if (v->cflags & REG_EXPANDED)
|
if (v->cflags®_EXPANDED)
|
||||||
skip(v);
|
skip(v);
|
||||||
if (ATEOS() || !iscdigit(*v->now))
|
if (ATEOS() || !iscdigit(*v->now)) {
|
||||||
{
|
|
||||||
NOTE(REG_UBRACES);
|
NOTE(REG_UBRACES);
|
||||||
NOTE(REG_UUNSPEC);
|
NOTE(REG_UUNSPEC);
|
||||||
RETV(PLAIN, c);
|
RETV(PLAIN, c);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
NOTE(REG_UBOUNDS);
|
NOTE(REG_UBOUNDS);
|
||||||
INTOCON(L_EBND);
|
INTOCON(L_EBND);
|
||||||
RET('{');
|
RET('{');
|
||||||
@@ -578,12 +539,10 @@ next(struct vars * v)
|
|||||||
assert(NOTREACHED);
|
assert(NOTREACHED);
|
||||||
break;
|
break;
|
||||||
case CHR('('): /* parenthesis, or advanced extension */
|
case CHR('('): /* parenthesis, or advanced extension */
|
||||||
if ((v->cflags & REG_ADVF) && NEXT1('?'))
|
if ((v->cflags®_ADVF) && NEXT1('?')) {
|
||||||
{
|
|
||||||
NOTE(REG_UNONPOSIX);
|
NOTE(REG_UNONPOSIX);
|
||||||
v->now++;
|
v->now++;
|
||||||
switch (*v->now++)
|
switch (*v->now++) {
|
||||||
{
|
|
||||||
case CHR(':'): /* non-capturing paren */
|
case CHR(':'): /* non-capturing paren */
|
||||||
RETV('(', 0);
|
RETV('(', 0);
|
||||||
break;
|
break;
|
||||||
@@ -609,33 +568,32 @@ next(struct vars * v)
|
|||||||
}
|
}
|
||||||
assert(NOTREACHED);
|
assert(NOTREACHED);
|
||||||
}
|
}
|
||||||
if (v->cflags & REG_NOSUB)
|
if (v->cflags®_NOSUB)
|
||||||
RETV('(', 0); /* all parens non-capturing */
|
RETV('(', 0); /* all parens non-capturing */
|
||||||
else
|
else
|
||||||
RETV('(', 1);
|
RETV('(', 1);
|
||||||
break;
|
break;
|
||||||
case CHR(')'):
|
case CHR(')'):
|
||||||
if (LASTTYPE('('))
|
if (LASTTYPE('(')) {
|
||||||
NOTE(REG_UUNSPEC);
|
NOTE(REG_UUNSPEC);
|
||||||
|
}
|
||||||
RETV(')', c);
|
RETV(')', c);
|
||||||
break;
|
break;
|
||||||
case CHR('['): /* easy except for [[:<:]] and [[:>:]] */
|
case CHR('['): /* easy except for [[:<:]] and [[:>:]] */
|
||||||
if (HAVE(6) && *(v->now + 0) == CHR('[') &&
|
if (HAVE(6) && *(v->now+0) == CHR('[') &&
|
||||||
*(v->now + 1) == CHR(':') &&
|
*(v->now+1) == CHR(':') &&
|
||||||
(*(v->now + 2) == CHR('<') ||
|
(*(v->now+2) == CHR('<') ||
|
||||||
*(v->now + 2) == CHR('>')) &&
|
*(v->now+2) == CHR('>')) &&
|
||||||
*(v->now + 3) == CHR(':') &&
|
*(v->now+3) == CHR(':') &&
|
||||||
*(v->now + 4) == CHR(']') &&
|
*(v->now+4) == CHR(']') &&
|
||||||
*(v->now + 5) == CHR(']'))
|
*(v->now+5) == CHR(']')) {
|
||||||
{
|
c = *(v->now+2);
|
||||||
c = *(v->now + 2);
|
|
||||||
v->now += 6;
|
v->now += 6;
|
||||||
NOTE(REG_UNONPOSIX);
|
NOTE(REG_UNONPOSIX);
|
||||||
RET((c == CHR('<')) ? '<' : '>');
|
RET((c == CHR('<')) ? '<' : '>');
|
||||||
}
|
}
|
||||||
INTOCON(L_BRACK);
|
INTOCON(L_BRACK);
|
||||||
if (NEXT1('^'))
|
if (NEXT1('^')) {
|
||||||
{
|
|
||||||
v->now++;
|
v->now++;
|
||||||
RETV('[', 0);
|
RETV('[', 0);
|
||||||
}
|
}
|
||||||
@@ -661,40 +619,24 @@ next(struct vars * v)
|
|||||||
|
|
||||||
/* ERE/ARE backslash handling; backslash already eaten */
|
/* ERE/ARE backslash handling; backslash already eaten */
|
||||||
assert(!ATEOS());
|
assert(!ATEOS());
|
||||||
if (!(v->cflags & REG_ADVF))
|
if (!(v->cflags®_ADVF)) { /* only AREs have non-trivial escapes */
|
||||||
{ /* only AREs have non-trivial escapes */
|
if (iscalnum(*v->now)) {
|
||||||
if (iscalnum(*v->now))
|
|
||||||
{
|
|
||||||
NOTE(REG_UBSALNUM);
|
NOTE(REG_UBSALNUM);
|
||||||
NOTE(REG_UUNSPEC);
|
NOTE(REG_UUNSPEC);
|
||||||
}
|
}
|
||||||
RETV(PLAIN, *v->now++);
|
RETV(PLAIN, *v->now++);
|
||||||
}
|
}
|
||||||
(DISCARD) lexescape(v);
|
(DISCARD)lexescape(v);
|
||||||
if (ISERR())
|
if (ISERR())
|
||||||
FAILW(REG_EESCAPE);
|
FAILW(REG_EESCAPE);
|
||||||
if (v->nexttype == CCLASS)
|
if (v->nexttype == CCLASS) { /* fudge at lexical level */
|
||||||
{ /* fudge at lexical level */
|
switch (v->nextvalue) {
|
||||||
switch (v->nextvalue)
|
case 'd': lexnest(v, backd, ENDOF(backd)); break;
|
||||||
{
|
case 'D': lexnest(v, backD, ENDOF(backD)); break;
|
||||||
case 'd':
|
case 's': lexnest(v, backs, ENDOF(backs)); break;
|
||||||
lexnest(v, backd, ENDOF(backd));
|
case 'S': lexnest(v, backS, ENDOF(backS)); break;
|
||||||
break;
|
case 'w': lexnest(v, backw, ENDOF(backw)); break;
|
||||||
case 'D':
|
case 'W': lexnest(v, backW, ENDOF(backW)); break;
|
||||||
lexnest(v, backD, ENDOF(backD));
|
|
||||||
break;
|
|
||||||
case 's':
|
|
||||||
lexnest(v, backs, ENDOF(backs));
|
|
||||||
break;
|
|
||||||
case 'S':
|
|
||||||
lexnest(v, backS, ENDOF(backS));
|
|
||||||
break;
|
|
||||||
case 'w':
|
|
||||||
lexnest(v, backw, ENDOF(backw));
|
|
||||||
break;
|
|
||||||
case 'W':
|
|
||||||
lexnest(v, backW, ENDOF(backW));
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
assert(NOTREACHED);
|
assert(NOTREACHED);
|
||||||
FAILW(REG_ASSERT);
|
FAILW(REG_ASSERT);
|
||||||
@@ -709,12 +651,13 @@ next(struct vars * v)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* lexescape - parse an ARE backslash escape (backslash already eaten)
|
- lexescape - parse an ARE backslash escape (backslash already eaten)
|
||||||
* Note slightly nonstandard use of the CCLASS type code.
|
* Note slightly nonstandard use of the CCLASS type code.
|
||||||
|
^ static int lexescape(struct vars *);
|
||||||
*/
|
*/
|
||||||
static int /* not actually used, but convenient for
|
static int /* not actually used, but convenient for RETV */
|
||||||
* RETV */
|
lexescape(v)
|
||||||
lexescape(struct vars * v)
|
struct vars *v;
|
||||||
{
|
{
|
||||||
chr c;
|
chr c;
|
||||||
static chr alert[] = {
|
static chr alert[] = {
|
||||||
@@ -725,7 +668,7 @@ lexescape(struct vars * v)
|
|||||||
};
|
};
|
||||||
chr *save;
|
chr *save;
|
||||||
|
|
||||||
assert(v->cflags & REG_ADVF);
|
assert(v->cflags®_ADVF);
|
||||||
|
|
||||||
assert(!ATEOS());
|
assert(!ATEOS());
|
||||||
c = *v->now++;
|
c = *v->now++;
|
||||||
@@ -733,8 +676,7 @@ lexescape(struct vars * v)
|
|||||||
RETV(PLAIN, c);
|
RETV(PLAIN, c);
|
||||||
|
|
||||||
NOTE(REG_UNONPOSIX);
|
NOTE(REG_UNONPOSIX);
|
||||||
switch (c)
|
switch (c) {
|
||||||
{
|
|
||||||
case CHR('a'):
|
case CHR('a'):
|
||||||
RETV(PLAIN, chrnamed(v, alert, ENDOF(alert), CHR('\007')));
|
RETV(PLAIN, chrnamed(v, alert, ENDOF(alert), CHR('\007')));
|
||||||
break;
|
break;
|
||||||
@@ -751,7 +693,7 @@ lexescape(struct vars * v)
|
|||||||
NOTE(REG_UUNPORT);
|
NOTE(REG_UUNPORT);
|
||||||
if (ATEOS())
|
if (ATEOS())
|
||||||
FAILW(REG_EESCAPE);
|
FAILW(REG_EESCAPE);
|
||||||
RETV(PLAIN, (chr) (*v->now++ & 037));
|
RETV(PLAIN, (chr)(*v->now++ & 037));
|
||||||
break;
|
break;
|
||||||
case CHR('d'):
|
case CHR('d'):
|
||||||
NOTE(REG_ULOCALE);
|
NOTE(REG_ULOCALE);
|
||||||
@@ -816,8 +758,7 @@ lexescape(struct vars * v)
|
|||||||
break;
|
break;
|
||||||
case CHR('x'):
|
case CHR('x'):
|
||||||
NOTE(REG_UUNPORT);
|
NOTE(REG_UUNPORT);
|
||||||
c = lexdigits(v, 16, 1, 255); /* REs >255 long outside
|
c = lexdigits(v, 16, 1, 255); /* REs >255 long outside spec */
|
||||||
* spec */
|
|
||||||
if (ISERR())
|
if (ISERR())
|
||||||
FAILW(REG_EESCAPE);
|
FAILW(REG_EESCAPE);
|
||||||
RETV(PLAIN, c);
|
RETV(PLAIN, c);
|
||||||
@@ -833,26 +774,18 @@ lexescape(struct vars * v)
|
|||||||
case CHR('Z'):
|
case CHR('Z'):
|
||||||
RETV(SEND, 0);
|
RETV(SEND, 0);
|
||||||
break;
|
break;
|
||||||
case CHR('1'):
|
case CHR('1'): case CHR('2'): case CHR('3'): case CHR('4'):
|
||||||
case CHR('2'):
|
case CHR('5'): case CHR('6'): case CHR('7'): case CHR('8'):
|
||||||
case CHR('3'):
|
|
||||||
case CHR('4'):
|
|
||||||
case CHR('5'):
|
|
||||||
case CHR('6'):
|
|
||||||
case CHR('7'):
|
|
||||||
case CHR('8'):
|
|
||||||
case CHR('9'):
|
case CHR('9'):
|
||||||
save = v->now;
|
save = v->now;
|
||||||
v->now--; /* put first digit back */
|
v->now--; /* put first digit back */
|
||||||
c = lexdigits(v, 10, 1, 255); /* REs >255 long outside
|
c = lexdigits(v, 10, 1, 255); /* REs >255 long outside spec */
|
||||||
* spec */
|
|
||||||
if (ISERR())
|
if (ISERR())
|
||||||
FAILW(REG_EESCAPE);
|
FAILW(REG_EESCAPE);
|
||||||
/* ugly heuristic (first test is "exactly 1 digit?") */
|
/* ugly heuristic (first test is "exactly 1 digit?") */
|
||||||
if (v->now - save == 0 || (int) c <= v->nsubexp)
|
if (v->now - save == 0 || (int)c <= v->nsubexp) {
|
||||||
{
|
|
||||||
NOTE(REG_UBACKREF);
|
NOTE(REG_UBACKREF);
|
||||||
RETV(BACKREF, (chr) c);
|
RETV(BACKREF, (chr)c);
|
||||||
}
|
}
|
||||||
/* oops, doesn't look like it's a backref after all... */
|
/* oops, doesn't look like it's a backref after all... */
|
||||||
v->now = save;
|
v->now = save;
|
||||||
@@ -874,119 +807,91 @@ lexescape(struct vars * v)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* lexdigits - slurp up digits and return chr value
|
- lexdigits - slurp up digits and return chr value
|
||||||
|
^ static chr lexdigits(struct vars *, int, int, int);
|
||||||
*/
|
*/
|
||||||
static chr /* chr value; errors signalled via ERR */
|
static chr /* chr value; errors signalled via ERR */
|
||||||
lexdigits(struct vars * v,
|
lexdigits(v, base, minlen, maxlen)
|
||||||
int base,
|
struct vars *v;
|
||||||
int minlen,
|
int base;
|
||||||
int maxlen)
|
int minlen;
|
||||||
|
int maxlen;
|
||||||
{
|
{
|
||||||
uchr n; /* unsigned to avoid overflow misbehavior */
|
uchr n; /* unsigned to avoid overflow misbehavior */
|
||||||
int len;
|
int len;
|
||||||
chr c;
|
chr c;
|
||||||
int d;
|
int d;
|
||||||
const uchr ub = (uchr) base;
|
CONST uchr ub = (uchr) base;
|
||||||
|
|
||||||
n = 0;
|
n = 0;
|
||||||
for (len = 0; len < maxlen && !ATEOS(); len++)
|
for (len = 0; len < maxlen && !ATEOS(); len++) {
|
||||||
{
|
|
||||||
c = *v->now++;
|
c = *v->now++;
|
||||||
switch (c)
|
switch (c) {
|
||||||
{
|
case CHR('0'): case CHR('1'): case CHR('2'): case CHR('3'):
|
||||||
case CHR('0'):
|
case CHR('4'): case CHR('5'): case CHR('6'): case CHR('7'):
|
||||||
case CHR('1'):
|
case CHR('8'): case CHR('9'):
|
||||||
case CHR('2'):
|
|
||||||
case CHR('3'):
|
|
||||||
case CHR('4'):
|
|
||||||
case CHR('5'):
|
|
||||||
case CHR('6'):
|
|
||||||
case CHR('7'):
|
|
||||||
case CHR('8'):
|
|
||||||
case CHR('9'):
|
|
||||||
d = DIGITVAL(c);
|
d = DIGITVAL(c);
|
||||||
break;
|
break;
|
||||||
case CHR('a'):
|
case CHR('a'): case CHR('A'): d = 10; break;
|
||||||
case CHR('A'):
|
case CHR('b'): case CHR('B'): d = 11; break;
|
||||||
d = 10;
|
case CHR('c'): case CHR('C'): d = 12; break;
|
||||||
break;
|
case CHR('d'): case CHR('D'): d = 13; break;
|
||||||
case CHR('b'):
|
case CHR('e'): case CHR('E'): d = 14; break;
|
||||||
case CHR('B'):
|
case CHR('f'): case CHR('F'): d = 15; break;
|
||||||
d = 11;
|
|
||||||
break;
|
|
||||||
case CHR('c'):
|
|
||||||
case CHR('C'):
|
|
||||||
d = 12;
|
|
||||||
break;
|
|
||||||
case CHR('d'):
|
|
||||||
case CHR('D'):
|
|
||||||
d = 13;
|
|
||||||
break;
|
|
||||||
case CHR('e'):
|
|
||||||
case CHR('E'):
|
|
||||||
d = 14;
|
|
||||||
break;
|
|
||||||
case CHR('f'):
|
|
||||||
case CHR('F'):
|
|
||||||
d = 15;
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
v->now--; /* oops, not a digit at all */
|
v->now--; /* oops, not a digit at all */
|
||||||
d = -1;
|
d = -1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (d >= base)
|
if (d >= base) { /* not a plausible digit */
|
||||||
{ /* not a plausible digit */
|
|
||||||
v->now--;
|
v->now--;
|
||||||
d = -1;
|
d = -1;
|
||||||
}
|
}
|
||||||
if (d < 0)
|
if (d < 0)
|
||||||
break; /* NOTE BREAK OUT */
|
break; /* NOTE BREAK OUT */
|
||||||
n = n * ub + (uchr) d;
|
n = n*ub + (uchr)d;
|
||||||
}
|
}
|
||||||
if (len < minlen)
|
if (len < minlen)
|
||||||
ERR(REG_EESCAPE);
|
ERR(REG_EESCAPE);
|
||||||
|
|
||||||
return (chr) n;
|
return (chr)n;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* brenext - get next BRE token
|
- brenext - get next BRE token
|
||||||
*
|
|
||||||
* This is much like EREs except for all the stupid backslashes and the
|
* This is much like EREs except for all the stupid backslashes and the
|
||||||
* context-dependency of some things.
|
* context-dependency of some things.
|
||||||
|
^ static int brenext(struct vars *, pchr);
|
||||||
*/
|
*/
|
||||||
static int /* 1 normal, 0 failure */
|
static int /* 1 normal, 0 failure */
|
||||||
brenext(struct vars * v,
|
brenext(v, pc)
|
||||||
chr pc)
|
struct vars *v;
|
||||||
|
pchr pc;
|
||||||
{
|
{
|
||||||
chr c = (chr) pc;
|
chr c = (chr)pc;
|
||||||
|
|
||||||
switch (c)
|
switch (c) {
|
||||||
{
|
|
||||||
case CHR('*'):
|
case CHR('*'):
|
||||||
if (LASTTYPE(EMPTY) || LASTTYPE('(') || LASTTYPE('^'))
|
if (LASTTYPE(EMPTY) || LASTTYPE('(') || LASTTYPE('^'))
|
||||||
RETV(PLAIN, c);
|
RETV(PLAIN, c);
|
||||||
RET('*');
|
RET('*');
|
||||||
break;
|
break;
|
||||||
case CHR('['):
|
case CHR('['):
|
||||||
if (HAVE(6) && *(v->now + 0) == CHR('[') &&
|
if (HAVE(6) && *(v->now+0) == CHR('[') &&
|
||||||
*(v->now + 1) == CHR(':') &&
|
*(v->now+1) == CHR(':') &&
|
||||||
(*(v->now + 2) == CHR('<') ||
|
(*(v->now+2) == CHR('<') ||
|
||||||
*(v->now + 2) == CHR('>')) &&
|
*(v->now+2) == CHR('>')) &&
|
||||||
*(v->now + 3) == CHR(':') &&
|
*(v->now+3) == CHR(':') &&
|
||||||
*(v->now + 4) == CHR(']') &&
|
*(v->now+4) == CHR(']') &&
|
||||||
*(v->now + 5) == CHR(']'))
|
*(v->now+5) == CHR(']')) {
|
||||||
{
|
c = *(v->now+2);
|
||||||
c = *(v->now + 2);
|
|
||||||
v->now += 6;
|
v->now += 6;
|
||||||
NOTE(REG_UNONPOSIX);
|
NOTE(REG_UNONPOSIX);
|
||||||
RET((c == CHR('<')) ? '<' : '>');
|
RET((c == CHR('<')) ? '<' : '>');
|
||||||
}
|
}
|
||||||
INTOCON(L_BRACK);
|
INTOCON(L_BRACK);
|
||||||
if (NEXT1('^'))
|
if (NEXT1('^')) {
|
||||||
{
|
|
||||||
v->now++;
|
v->now++;
|
||||||
RETV('[', 0);
|
RETV('[', 0);
|
||||||
}
|
}
|
||||||
@@ -998,20 +903,18 @@ brenext(struct vars * v,
|
|||||||
case CHR('^'):
|
case CHR('^'):
|
||||||
if (LASTTYPE(EMPTY))
|
if (LASTTYPE(EMPTY))
|
||||||
RET('^');
|
RET('^');
|
||||||
if (LASTTYPE('('))
|
if (LASTTYPE('(')) {
|
||||||
{
|
|
||||||
NOTE(REG_UUNSPEC);
|
NOTE(REG_UUNSPEC);
|
||||||
RET('^');
|
RET('^');
|
||||||
}
|
}
|
||||||
RETV(PLAIN, c);
|
RETV(PLAIN, c);
|
||||||
break;
|
break;
|
||||||
case CHR('$'):
|
case CHR('$'):
|
||||||
if (v->cflags & REG_EXPANDED)
|
if (v->cflags®_EXPANDED)
|
||||||
skip(v);
|
skip(v);
|
||||||
if (ATEOS())
|
if (ATEOS())
|
||||||
RET('$');
|
RET('$');
|
||||||
if (NEXT2('\\', ')'))
|
if (NEXT2('\\', ')')) {
|
||||||
{
|
|
||||||
NOTE(REG_UUNSPEC);
|
NOTE(REG_UUNSPEC);
|
||||||
RET('$');
|
RET('$');
|
||||||
}
|
}
|
||||||
@@ -1030,8 +933,7 @@ brenext(struct vars * v,
|
|||||||
FAILW(REG_EESCAPE);
|
FAILW(REG_EESCAPE);
|
||||||
|
|
||||||
c = *v->now++;
|
c = *v->now++;
|
||||||
switch (c)
|
switch (c) {
|
||||||
{
|
|
||||||
case CHR('{'):
|
case CHR('{'):
|
||||||
INTOCON(L_BBND);
|
INTOCON(L_BBND);
|
||||||
NOTE(REG_UBOUNDS);
|
NOTE(REG_UBOUNDS);
|
||||||
@@ -1051,21 +953,14 @@ brenext(struct vars * v,
|
|||||||
NOTE(REG_UNONPOSIX);
|
NOTE(REG_UNONPOSIX);
|
||||||
RET('>');
|
RET('>');
|
||||||
break;
|
break;
|
||||||
case CHR('1'):
|
case CHR('1'): case CHR('2'): case CHR('3'): case CHR('4'):
|
||||||
case CHR('2'):
|
case CHR('5'): case CHR('6'): case CHR('7'): case CHR('8'):
|
||||||
case CHR('3'):
|
|
||||||
case CHR('4'):
|
|
||||||
case CHR('5'):
|
|
||||||
case CHR('6'):
|
|
||||||
case CHR('7'):
|
|
||||||
case CHR('8'):
|
|
||||||
case CHR('9'):
|
case CHR('9'):
|
||||||
NOTE(REG_UBACKREF);
|
NOTE(REG_UBACKREF);
|
||||||
RETV(BACKREF, (chr) DIGITVAL(c));
|
RETV(BACKREF, (chr)DIGITVAL(c));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (iscalnum(c))
|
if (iscalnum(c)) {
|
||||||
{
|
|
||||||
NOTE(REG_UBSALNUM);
|
NOTE(REG_UBSALNUM);
|
||||||
NOTE(REG_UUNSPEC);
|
NOTE(REG_UUNSPEC);
|
||||||
}
|
}
|
||||||
@@ -1077,17 +972,18 @@ brenext(struct vars * v,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* skip - skip white space and comments in expanded form
|
- skip - skip white space and comments in expanded form
|
||||||
|
^ static VOID skip(struct vars *);
|
||||||
*/
|
*/
|
||||||
static void
|
static VOID
|
||||||
skip(struct vars * v)
|
skip(v)
|
||||||
|
struct vars *v;
|
||||||
{
|
{
|
||||||
chr *start = v->now;
|
chr *start = v->now;
|
||||||
|
|
||||||
assert(v->cflags & REG_EXPANDED);
|
assert(v->cflags®_EXPANDED);
|
||||||
|
|
||||||
for (;;)
|
for (;;) {
|
||||||
{
|
|
||||||
while (!ATEOS() && iscspace(*v->now))
|
while (!ATEOS() && iscspace(*v->now))
|
||||||
v->now++;
|
v->now++;
|
||||||
if (ATEOS() || *v->now != CHR('#'))
|
if (ATEOS() || *v->now != CHR('#'))
|
||||||
@@ -1103,27 +999,46 @@ skip(struct vars * v)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* newline - return the chr for a newline
|
- newline - return the chr for a newline
|
||||||
*
|
|
||||||
* This helps confine use of CHR to this source file.
|
* This helps confine use of CHR to this source file.
|
||||||
|
^ static chr newline(NOPARMS);
|
||||||
*/
|
*/
|
||||||
static chr
|
static chr
|
||||||
newline(void)
|
newline()
|
||||||
{
|
{
|
||||||
return CHR('\n');
|
return CHR('\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* chrnamed - return the chr known by a given (chr string) name
|
- ch - return the chr sequence for regc_locale.c's fake collating element ch
|
||||||
*
|
* This helps confine use of CHR to this source file. Beware that the caller
|
||||||
|
* knows how long the sequence is.
|
||||||
|
^ #ifdef REG_DEBUG
|
||||||
|
^ static chr *ch(NOPARMS);
|
||||||
|
^ #endif
|
||||||
|
*/
|
||||||
|
#ifdef REG_DEBUG
|
||||||
|
static chr *
|
||||||
|
ch()
|
||||||
|
{
|
||||||
|
static chr chstr[] = { CHR('c'), CHR('h'), CHR('\0') };
|
||||||
|
|
||||||
|
return chstr;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
- chrnamed - return the chr known by a given (chr string) name
|
||||||
* The code is a bit clumsy, but this routine gets only such specialized
|
* The code is a bit clumsy, but this routine gets only such specialized
|
||||||
* use that it hardly matters.
|
* use that it hardly matters.
|
||||||
|
^ static chr chrnamed(struct vars *, chr *, chr *, pchr);
|
||||||
*/
|
*/
|
||||||
static chr
|
static chr
|
||||||
chrnamed(struct vars * v,
|
chrnamed(v, startp, endp, lastresort)
|
||||||
chr *startp, /* start of name */
|
struct vars *v;
|
||||||
chr *endp, /* just past end of name */
|
chr *startp; /* start of name */
|
||||||
chr lastresort) /* what to return if name lookup fails */
|
chr *endp; /* just past end of name */
|
||||||
|
pchr lastresort; /* what to return if name lookup fails */
|
||||||
{
|
{
|
||||||
celt c;
|
celt c;
|
||||||
int errsave;
|
int errsave;
|
||||||
@@ -1137,10 +1052,10 @@ chrnamed(struct vars * v,
|
|||||||
v->err = errsave;
|
v->err = errsave;
|
||||||
|
|
||||||
if (e != 0)
|
if (e != 0)
|
||||||
return (chr) lastresort;
|
return (chr)lastresort;
|
||||||
|
|
||||||
cv = range(v, c, c, 0);
|
cv = range(v, c, c, 0);
|
||||||
if (cv->nchrs == 0)
|
if (cv->nchrs == 0)
|
||||||
return (chr) lastresort;
|
return (chr)lastresort;
|
||||||
return cv->chrs[0];
|
return cv->chrs[0];
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
1209
src/regex/regcomp.c
1209
src/regex/regcomp.c
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,3 @@
|
|||||||
#ifndef _REGEX_CUSTOM_H_
|
|
||||||
#define _REGEX_CUSTOM_H_
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1998, 1999 Henry Spencer. All rights reserved.
|
* Copyright (c) 1998, 1999 Henry Spencer. All rights reserved.
|
||||||
*
|
*
|
||||||
@@ -27,72 +24,97 @@
|
|||||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
|
||||||
* $Id$
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* headers if any */
|
/* headers if any */
|
||||||
|
#include "tclInt.h"
|
||||||
/* FreeBSD, Watcom and DMars require this, CW doesn't have nor need it. */
|
|
||||||
/* Others also don't seem to need it. If you have an error related to */
|
|
||||||
/* (not) including <sys/types.h> please report details to */
|
|
||||||
/* wx-dev@lists.wxwindows.org */
|
|
||||||
#if defined(__UNIX__) || defined(__WATCOMC__) || defined(__DIGITALMARS__)
|
|
||||||
# include <sys/types.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <ctype.h>
|
|
||||||
#include <limits.h>
|
|
||||||
|
|
||||||
#include "wx/wxchar.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* wx_wchar == wxChar
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#define wx_wchar wxChar
|
|
||||||
|
|
||||||
/* overrides for regguts.h definitions, if any */
|
/* overrides for regguts.h definitions, if any */
|
||||||
#define FUNCPTR(name, args) (*name) args
|
#define FUNCPTR(name, args) (*name) _ANSI_ARGS_(args)
|
||||||
#define MALLOC(n) malloc(n)
|
#define MALLOC(n) ckalloc(n)
|
||||||
#define FREE(p) free(VS(p))
|
#define FREE(p) ckfree(VS(p))
|
||||||
#define REALLOC(p,n) realloc(VS(p),n)
|
#define REALLOC(p,n) ckrealloc(VS(p),n)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Do not insert extras between the "begin" and "end" lines -- this
|
||||||
|
* chunk is automatically extracted to be fitted into regex.h.
|
||||||
|
*/
|
||||||
|
/* --- begin --- */
|
||||||
|
/* ensure certain things don't sneak in from system headers */
|
||||||
|
#ifdef __REG_WIDE_T
|
||||||
|
#undef __REG_WIDE_T
|
||||||
|
#endif
|
||||||
|
#ifdef __REG_WIDE_COMPILE
|
||||||
|
#undef __REG_WIDE_COMPILE
|
||||||
|
#endif
|
||||||
|
#ifdef __REG_WIDE_EXEC
|
||||||
|
#undef __REG_WIDE_EXEC
|
||||||
|
#endif
|
||||||
|
#ifdef __REG_REGOFF_T
|
||||||
|
#undef __REG_REGOFF_T
|
||||||
|
#endif
|
||||||
|
#ifdef __REG_VOID_T
|
||||||
|
#undef __REG_VOID_T
|
||||||
|
#endif
|
||||||
|
#ifdef __REG_CONST
|
||||||
|
#undef __REG_CONST
|
||||||
|
#endif
|
||||||
|
#ifdef __REG_NOFRONT
|
||||||
|
#undef __REG_NOFRONT
|
||||||
|
#endif
|
||||||
|
#ifdef __REG_NOCHAR
|
||||||
|
#undef __REG_NOCHAR
|
||||||
|
#endif
|
||||||
|
/* interface types */
|
||||||
|
#define __REG_WIDE_T Tcl_UniChar
|
||||||
|
#define __REG_REGOFF_T long /* not really right, but good enough... */
|
||||||
|
#define __REG_VOID_T VOID
|
||||||
|
#define __REG_CONST CONST
|
||||||
|
/* names and declarations */
|
||||||
|
#define __REG_WIDE_COMPILE TclReComp
|
||||||
|
#define __REG_WIDE_EXEC TclReExec
|
||||||
|
#define __REG_NOFRONT /* don't want regcomp() and regexec() */
|
||||||
|
#define __REG_NOCHAR /* or the char versions */
|
||||||
|
#define regfree TclReFree
|
||||||
|
#define regerror TclReError
|
||||||
|
/* --- end --- */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* internal character type and related */
|
/* internal character type and related */
|
||||||
typedef wx_wchar chr; /* the type itself */
|
typedef Tcl_UniChar chr; /* the type itself */
|
||||||
typedef unsigned long uchr; /* unsigned type that will hold a chr */
|
typedef int pchr; /* what it promotes to */
|
||||||
typedef long celt; /* type to hold chr, MCCE number, or
|
typedef unsigned uchr; /* unsigned type that will hold a chr */
|
||||||
* NOCELT */
|
typedef int celt; /* type to hold chr, MCCE number, or NOCELT */
|
||||||
|
#define NOCELT (-1) /* celt value which is not valid chr or MCCE */
|
||||||
#define NOCELT (-1) /* celt value which is not valid chr or
|
#define CHR(c) (UCHAR(c)) /* turn char literal into chr literal */
|
||||||
* MCCE */
|
|
||||||
#define CHR(c) ((unsigned char) (c)) /* turn char literal into chr
|
|
||||||
* literal */
|
|
||||||
#define DIGITVAL(c) ((c)-'0') /* turn chr digit into its value */
|
#define DIGITVAL(c) ((c)-'0') /* turn chr digit into its value */
|
||||||
|
#if TCL_UTF_MAX > 3
|
||||||
#if wxUSE_WCHAR_T
|
#define CHRBITS 32 /* bits in a chr; must not use sizeof */
|
||||||
# define CHRBITS (SIZEOF_WCHAR_T << 3) /* bits in a chr; must not use sizeof */
|
#define CHR_MIN 0x00000000 /* smallest and largest chr; the value */
|
||||||
# define CHR_MAX ((1 << CHRBITS) - 1)
|
#define CHR_MAX 0xffffffff /* CHR_MAX-CHR_MIN+1 should fit in uchr */
|
||||||
# define CHR_MIN 0x00000000 /* smallest and largest chr; the value */
|
#else
|
||||||
#else /*ANSI*/
|
#define CHRBITS 16 /* bits in a chr; must not use sizeof */
|
||||||
# define CHRBITS 8
|
#define CHR_MIN 0x0000 /* smallest and largest chr; the value */
|
||||||
# define CHR_MAX 0xFF
|
#define CHR_MAX 0xffff /* CHR_MAX-CHR_MIN+1 should fit in uchr */
|
||||||
# define CHR_MIN 0x00
|
#endif
|
||||||
#endif /*wxUSE_WCHAR_T*/
|
|
||||||
|
|
||||||
/* functions operating on chr */
|
/* functions operating on chr */
|
||||||
#define iscalnum(x) wx_isalnum(x)
|
#define iscalnum(x) Tcl_UniCharIsAlnum(x)
|
||||||
#define iscalpha(x) wx_isalpha(x)
|
#define iscalpha(x) Tcl_UniCharIsAlpha(x)
|
||||||
#define iscdigit(x) wx_isdigit(x)
|
#define iscdigit(x) Tcl_UniCharIsDigit(x)
|
||||||
#define iscspace(x) wx_isspace(x)
|
#define iscspace(x) Tcl_UniCharIsSpace(x)
|
||||||
|
|
||||||
extern int wx_strlen(const wx_wchar* szString);
|
/* name the external functions */
|
||||||
|
#define compile TclReComp
|
||||||
|
#define exec TclReExec
|
||||||
|
|
||||||
|
/* enable/disable debugging code (by whether REG_DEBUG is defined or not) */
|
||||||
|
#if 0 /* no debug unless requested by makefile */
|
||||||
|
#define REG_DEBUG /* */
|
||||||
|
#endif
|
||||||
|
|
||||||
/* and pick up the standard header */
|
/* and pick up the standard header */
|
||||||
#include "regex.h"
|
#include "regex.h"
|
||||||
|
|
||||||
#endif /* _REGEX_CUSTOM_H_ */
|
|
||||||
|
@@ -28,19 +28,19 @@
|
|||||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $Header$
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* longest - longest-preferred matching engine
|
- longest - longest-preferred matching engine
|
||||||
|
^ static chr *longest(struct vars *, struct dfa *, chr *, chr *, int *);
|
||||||
*/
|
*/
|
||||||
static chr * /* endpoint, or NULL */
|
static chr * /* endpoint, or NULL */
|
||||||
longest(struct vars * v, /* used only for debug and exec flags */
|
longest(v, d, start, stop, hitstopp)
|
||||||
struct dfa * d,
|
struct vars *v; /* used only for debug and exec flags */
|
||||||
chr *start, /* where the match should start */
|
struct dfa *d;
|
||||||
chr *stop, /* match must end at or before here */
|
chr *start; /* where the match should start */
|
||||||
int *hitstopp) /* record whether hit v->stop, if non-NULL */
|
chr *stop; /* match must end at or before here */
|
||||||
|
int *hitstopp; /* record whether hit v->stop, if non-NULL */
|
||||||
{
|
{
|
||||||
chr *cp;
|
chr *cp;
|
||||||
chr *realstop = (stop == v->stop) ? stop : stop + 1;
|
chr *realstop = (stop == v->stop) ? stop : stop + 1;
|
||||||
@@ -59,15 +59,12 @@ longest(struct vars * v, /* used only for debug and exec flags */
|
|||||||
|
|
||||||
/* startup */
|
/* startup */
|
||||||
FDEBUG(("+++ startup +++\n"));
|
FDEBUG(("+++ startup +++\n"));
|
||||||
if (cp == v->start)
|
if (cp == v->start) {
|
||||||
{
|
co = d->cnfa->bos[(v->eflags®_NOTBOL) ? 0 : 1];
|
||||||
co = d->cnfa->bos[(v->eflags & REG_NOTBOL) ? 0 : 1];
|
FDEBUG(("color %ld\n", (long)co));
|
||||||
FDEBUG(("color %ld\n", (long) co));
|
} else {
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
co = GETCOLOR(cm, *(cp - 1));
|
co = GETCOLOR(cm, *(cp - 1));
|
||||||
FDEBUG(("char %c, color %ld\n", (char) *(cp - 1), (long) co));
|
FDEBUG(("char %c, color %ld\n", (char)*(cp-1), (long)co));
|
||||||
}
|
}
|
||||||
css = miss(v, d, css, co, cp, start);
|
css = miss(v, d, css, co, cp, start);
|
||||||
if (css == NULL)
|
if (css == NULL)
|
||||||
@@ -75,16 +72,14 @@ longest(struct vars * v, /* used only for debug and exec flags */
|
|||||||
css->lastseen = cp;
|
css->lastseen = cp;
|
||||||
|
|
||||||
/* main loop */
|
/* main loop */
|
||||||
if (v->eflags & REG_FTRACE)
|
if (v->eflags®_FTRACE)
|
||||||
while (cp < realstop)
|
while (cp < realstop) {
|
||||||
{
|
|
||||||
FDEBUG(("+++ at c%d +++\n", css - d->ssets));
|
FDEBUG(("+++ at c%d +++\n", css - d->ssets));
|
||||||
co = GETCOLOR(cm, *cp);
|
co = GETCOLOR(cm, *cp);
|
||||||
FDEBUG(("char %c, color %ld\n", (char) *cp, (long) co));
|
FDEBUG(("char %c, color %ld\n", (char)*cp, (long)co));
|
||||||
ss = css->outs[co];
|
ss = css->outs[co];
|
||||||
if (ss == NULL)
|
if (ss == NULL) {
|
||||||
{
|
ss = miss(v, d, css, co, cp+1, start);
|
||||||
ss = miss(v, d, css, co, cp + 1, start);
|
|
||||||
if (ss == NULL)
|
if (ss == NULL)
|
||||||
break; /* NOTE BREAK OUT */
|
break; /* NOTE BREAK OUT */
|
||||||
}
|
}
|
||||||
@@ -93,13 +88,11 @@ longest(struct vars * v, /* used only for debug and exec flags */
|
|||||||
css = ss;
|
css = ss;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
while (cp < realstop)
|
while (cp < realstop) {
|
||||||
{
|
|
||||||
co = GETCOLOR(cm, *cp);
|
co = GETCOLOR(cm, *cp);
|
||||||
ss = css->outs[co];
|
ss = css->outs[co];
|
||||||
if (ss == NULL)
|
if (ss == NULL) {
|
||||||
{
|
ss = miss(v, d, css, co, cp+1, start);
|
||||||
ss = miss(v, d, css, co, cp + 1, start);
|
|
||||||
if (ss == NULL)
|
if (ss == NULL)
|
||||||
break; /* NOTE BREAK OUT */
|
break; /* NOTE BREAK OUT */
|
||||||
}
|
}
|
||||||
@@ -110,15 +103,14 @@ longest(struct vars * v, /* used only for debug and exec flags */
|
|||||||
|
|
||||||
/* shutdown */
|
/* shutdown */
|
||||||
FDEBUG(("+++ shutdown at c%d +++\n", css - d->ssets));
|
FDEBUG(("+++ shutdown at c%d +++\n", css - d->ssets));
|
||||||
if (cp == v->stop && stop == v->stop)
|
if (cp == v->stop && stop == v->stop) {
|
||||||
{
|
|
||||||
if (hitstopp != NULL)
|
if (hitstopp != NULL)
|
||||||
*hitstopp = 1;
|
*hitstopp = 1;
|
||||||
co = d->cnfa->eos[(v->eflags & REG_NOTEOL) ? 0 : 1];
|
co = d->cnfa->eos[(v->eflags®_NOTEOL) ? 0 : 1];
|
||||||
FDEBUG(("color %ld\n", (long) co));
|
FDEBUG(("color %ld\n", (long)co));
|
||||||
ss = miss(v, d, css, co, cp, start);
|
ss = miss(v, d, css, co, cp, start);
|
||||||
/* special case: match ended at eol? */
|
/* special case: match ended at eol? */
|
||||||
if (ss != NULL && (ss->flags & POSTSTATE))
|
if (ss != NULL && (ss->flags&POSTSTATE))
|
||||||
return cp;
|
return cp;
|
||||||
else if (ss != NULL)
|
else if (ss != NULL)
|
||||||
ss->lastseen = cp; /* to be tidy */
|
ss->lastseen = cp; /* to be tidy */
|
||||||
@@ -127,7 +119,7 @@ longest(struct vars * v, /* used only for debug and exec flags */
|
|||||||
/* find last match, if any */
|
/* find last match, if any */
|
||||||
post = d->lastpost;
|
post = d->lastpost;
|
||||||
for (ss = d->ssets, i = d->nssused; i > 0; ss++, i--)
|
for (ss = d->ssets, i = d->nssused; i > 0; ss++, i--)
|
||||||
if ((ss->flags & POSTSTATE) && post != ss->lastseen &&
|
if ((ss->flags&POSTSTATE) && post != ss->lastseen &&
|
||||||
(post == NULL || post < ss->lastseen))
|
(post == NULL || post < ss->lastseen))
|
||||||
post = ss->lastseen;
|
post = ss->lastseen;
|
||||||
if (post != NULL) /* found one */
|
if (post != NULL) /* found one */
|
||||||
@@ -137,17 +129,19 @@ longest(struct vars * v, /* used only for debug and exec flags */
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* shortest - shortest-preferred matching engine
|
- shortest - shortest-preferred matching engine
|
||||||
|
^ static chr *shortest(struct vars *, struct dfa *, chr *, chr *, chr *,
|
||||||
|
^ chr **, int *);
|
||||||
*/
|
*/
|
||||||
static chr * /* endpoint, or NULL */
|
static chr * /* endpoint, or NULL */
|
||||||
shortest(struct vars * v,
|
shortest(v, d, start, min, max, coldp, hitstopp)
|
||||||
struct dfa * d,
|
struct vars *v;
|
||||||
chr *start, /* where the match should start */
|
struct dfa *d;
|
||||||
chr *min, /* match must end at or after here */
|
chr *start; /* where the match should start */
|
||||||
chr *max, /* match must end at or before here */
|
chr *min; /* match must end at or after here */
|
||||||
chr **coldp, /* store coldstart pointer here, if
|
chr *max; /* match must end at or before here */
|
||||||
* nonNULL */
|
chr **coldp; /* store coldstart pointer here, if nonNULL */
|
||||||
int *hitstopp) /* record whether hit v->stop, if non-NULL */
|
int *hitstopp; /* record whether hit v->stop, if non-NULL */
|
||||||
{
|
{
|
||||||
chr *cp;
|
chr *cp;
|
||||||
chr *realmin = (min == v->stop) ? min : min + 1;
|
chr *realmin = (min == v->stop) ? min : min + 1;
|
||||||
@@ -165,15 +159,12 @@ shortest(struct vars * v,
|
|||||||
|
|
||||||
/* startup */
|
/* startup */
|
||||||
FDEBUG(("--- startup ---\n"));
|
FDEBUG(("--- startup ---\n"));
|
||||||
if (cp == v->start)
|
if (cp == v->start) {
|
||||||
{
|
co = d->cnfa->bos[(v->eflags®_NOTBOL) ? 0 : 1];
|
||||||
co = d->cnfa->bos[(v->eflags & REG_NOTBOL) ? 0 : 1];
|
FDEBUG(("color %ld\n", (long)co));
|
||||||
FDEBUG(("color %ld\n", (long) co));
|
} else {
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
co = GETCOLOR(cm, *(cp - 1));
|
co = GETCOLOR(cm, *(cp - 1));
|
||||||
FDEBUG(("char %c, color %ld\n", (char) *(cp - 1), (long) co));
|
FDEBUG(("char %c, color %ld\n", (char)*(cp-1), (long)co));
|
||||||
}
|
}
|
||||||
css = miss(v, d, css, co, cp, start);
|
css = miss(v, d, css, co, cp, start);
|
||||||
if (css == NULL)
|
if (css == NULL)
|
||||||
@@ -182,77 +173,71 @@ shortest(struct vars * v,
|
|||||||
ss = css;
|
ss = css;
|
||||||
|
|
||||||
/* main loop */
|
/* main loop */
|
||||||
if (v->eflags & REG_FTRACE)
|
if (v->eflags®_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;
|
||||||
@@ -262,19 +247,22 @@ lastcold(struct vars * v,
|
|||||||
if (nopr == NULL)
|
if (nopr == NULL)
|
||||||
nopr = v->start;
|
nopr = v->start;
|
||||||
for (ss = d->ssets, i = d->nssused; i > 0; ss++, i--)
|
for (ss = d->ssets, i = d->nssused; i > 0; ss++, i--)
|
||||||
if ((ss->flags & NOPROGRESS) && nopr < ss->lastseen)
|
if ((ss->flags&NOPROGRESS) && nopr < ss->lastseen)
|
||||||
nopr = ss->lastseen;
|
nopr = ss->lastseen;
|
||||||
return nopr;
|
return nopr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* newdfa - set up a fresh DFA
|
- newdfa - set up a fresh DFA
|
||||||
|
^ static struct dfa *newdfa(struct vars *, struct cnfa *,
|
||||||
|
^ struct colormap *, struct smalldfa *);
|
||||||
*/
|
*/
|
||||||
static struct dfa *
|
static struct dfa *
|
||||||
newdfa(struct vars * v,
|
newdfa(v, cnfa, cm, small)
|
||||||
struct cnfa * cnfa,
|
struct vars *v;
|
||||||
struct colormap * cm,
|
struct cnfa *cnfa;
|
||||||
struct smalldfa * small) /* preallocated space, may be NULL */
|
struct colormap *cm;
|
||||||
|
struct smalldfa *small; /* preallocated space, may be NULL */
|
||||||
{
|
{
|
||||||
struct dfa *d;
|
struct dfa *d;
|
||||||
size_t nss = cnfa->nstates * 2;
|
size_t nss = cnfa->nstates * 2;
|
||||||
@@ -283,15 +271,12 @@ newdfa(struct vars * v,
|
|||||||
|
|
||||||
assert(cnfa != NULL && cnfa->nstates != 0);
|
assert(cnfa != NULL && cnfa->nstates != 0);
|
||||||
|
|
||||||
if (nss <= FEWSTATES && cnfa->ncolors <= FEWCOLORS)
|
if (nss <= FEWSTATES && cnfa->ncolors <= FEWCOLORS) {
|
||||||
{
|
|
||||||
assert(wordsper == 1);
|
assert(wordsper == 1);
|
||||||
if (small == NULL)
|
if (small == NULL) {
|
||||||
{
|
small = (struct smalldfa *)MALLOC(
|
||||||
small = (struct smalldfa *) MALLOC(
|
|
||||||
sizeof(struct smalldfa));
|
sizeof(struct smalldfa));
|
||||||
if (small == NULL)
|
if (small == NULL) {
|
||||||
{
|
|
||||||
ERR(REG_ESPACE);
|
ERR(REG_ESPACE);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -303,36 +288,32 @@ newdfa(struct vars * v,
|
|||||||
d->outsarea = small->outsarea;
|
d->outsarea = small->outsarea;
|
||||||
d->incarea = small->incarea;
|
d->incarea = small->incarea;
|
||||||
d->cptsmalloced = 0;
|
d->cptsmalloced = 0;
|
||||||
d->mallocarea = (smallwas == NULL) ? (char *) small : NULL;
|
d->mallocarea = (smallwas == NULL) ? (char *)small : NULL;
|
||||||
}
|
} else {
|
||||||
else
|
d = (struct dfa *)MALLOC(sizeof(struct dfa));
|
||||||
{
|
if (d == NULL) {
|
||||||
d = (struct dfa *) MALLOC(sizeof(struct dfa));
|
|
||||||
if (d == NULL)
|
|
||||||
{
|
|
||||||
ERR(REG_ESPACE);
|
ERR(REG_ESPACE);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
d->ssets = (struct sset *) MALLOC(nss * sizeof(struct sset));
|
d->ssets = (struct sset *)MALLOC(nss * sizeof(struct sset));
|
||||||
d->statesarea = (unsigned *) MALLOC((nss + WORK) * wordsper *
|
d->statesarea = (unsigned *)MALLOC((nss+WORK) * wordsper *
|
||||||
sizeof(unsigned));
|
sizeof(unsigned));
|
||||||
d->work = &d->statesarea[nss * wordsper];
|
d->work = &d->statesarea[nss * wordsper];
|
||||||
d->outsarea = (struct sset **) MALLOC(nss * cnfa->ncolors *
|
d->outsarea = (struct sset **)MALLOC(nss * cnfa->ncolors *
|
||||||
sizeof(struct sset *));
|
sizeof(struct sset *));
|
||||||
d->incarea = (struct arcp *) MALLOC(nss * cnfa->ncolors *
|
d->incarea = (struct arcp *)MALLOC(nss * cnfa->ncolors *
|
||||||
sizeof(struct arcp));
|
sizeof(struct arcp));
|
||||||
d->cptsmalloced = 1;
|
d->cptsmalloced = 1;
|
||||||
d->mallocarea = (char *) d;
|
d->mallocarea = (char *)d;
|
||||||
if (d->ssets == NULL || d->statesarea == NULL ||
|
if (d->ssets == NULL || d->statesarea == NULL ||
|
||||||
d->outsarea == NULL || d->incarea == NULL)
|
d->outsarea == NULL || d->incarea == NULL) {
|
||||||
{
|
|
||||||
freedfa(d);
|
freedfa(d);
|
||||||
ERR(REG_ESPACE);
|
ERR(REG_ESPACE);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
d->nssets = (v->eflags & REG_SMALL) ? 7 : nss;
|
d->nssets = (v->eflags®_SMALL) ? 7 : nss;
|
||||||
d->nssused = 0;
|
d->nssused = 0;
|
||||||
d->nstates = cnfa->nstates;
|
d->nstates = cnfa->nstates;
|
||||||
d->ncolors = cnfa->ncolors;
|
d->ncolors = cnfa->ncolors;
|
||||||
@@ -349,13 +330,14 @@ newdfa(struct vars * v,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* freedfa - free a DFA
|
- freedfa - free a DFA
|
||||||
|
^ static VOID freedfa(struct dfa *);
|
||||||
*/
|
*/
|
||||||
static void
|
static VOID
|
||||||
freedfa(struct dfa * d)
|
freedfa(d)
|
||||||
|
struct dfa *d;
|
||||||
{
|
{
|
||||||
if (d->cptsmalloced)
|
if (d->cptsmalloced) {
|
||||||
{
|
|
||||||
if (d->ssets != NULL)
|
if (d->ssets != NULL)
|
||||||
FREE(d->ssets);
|
FREE(d->ssets);
|
||||||
if (d->statesarea != NULL)
|
if (d->statesarea != NULL)
|
||||||
@@ -371,13 +353,14 @@ freedfa(struct dfa * d)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* hash - construct a hash code for a bitvector
|
- hash - construct a hash code for a bitvector
|
||||||
*
|
|
||||||
* There are probably better ways, but they're more expensive.
|
* There are probably better ways, but they're more expensive.
|
||||||
|
^ static unsigned hash(unsigned *, int);
|
||||||
*/
|
*/
|
||||||
static unsigned
|
static unsigned
|
||||||
hash(unsigned *uv,
|
hash(uv, n)
|
||||||
int n)
|
unsigned *uv;
|
||||||
|
int n;
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
unsigned h;
|
unsigned h;
|
||||||
@@ -389,28 +372,29 @@ hash(unsigned *uv,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* initialize - hand-craft a cache entry for startup, otherwise get ready
|
- initialize - hand-craft a cache entry for startup, otherwise get ready
|
||||||
|
^ static struct sset *initialize(struct vars *, struct dfa *, chr *);
|
||||||
*/
|
*/
|
||||||
static struct sset *
|
static struct sset *
|
||||||
initialize(struct vars * v, /* used only for debug flags */
|
initialize(v, d, start)
|
||||||
struct dfa * d,
|
struct vars *v; /* used only for debug flags */
|
||||||
chr *start)
|
struct dfa *d;
|
||||||
|
chr *start;
|
||||||
{
|
{
|
||||||
struct sset *ss;
|
struct sset *ss;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* is previous one still there? */
|
/* is previous one still there? */
|
||||||
if (d->nssused > 0 && (d->ssets[0].flags & STARTER))
|
if (d->nssused > 0 && (d->ssets[0].flags&STARTER))
|
||||||
ss = &d->ssets[0];
|
ss = &d->ssets[0];
|
||||||
else
|
else { /* no, must (re)build it */
|
||||||
{ /* no, must (re)build it */
|
|
||||||
ss = getvacant(v, d, start, start);
|
ss = getvacant(v, d, start, start);
|
||||||
for (i = 0; i < d->wordsper; i++)
|
for (i = 0; i < d->wordsper; i++)
|
||||||
ss->states[i] = 0;
|
ss->states[i] = 0;
|
||||||
BSET(ss->states, d->cnfa->pre);
|
BSET(ss->states, d->cnfa->pre);
|
||||||
ss->hash = HASH(ss->states, d->wordsper);
|
ss->hash = HASH(ss->states, d->wordsper);
|
||||||
assert(d->cnfa->pre != d->cnfa->post);
|
assert(d->cnfa->pre != d->cnfa->post);
|
||||||
ss->flags = STARTER | LOCKED | NOPROGRESS;
|
ss->flags = STARTER|LOCKED|NOPROGRESS;
|
||||||
/* lastseen dealt with below */
|
/* lastseen dealt with below */
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -423,15 +407,18 @@ initialize(struct vars * v, /* used only for debug flags */
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* miss - handle a cache miss
|
- miss - handle a cache miss
|
||||||
|
^ static struct sset *miss(struct vars *, struct dfa *, struct sset *,
|
||||||
|
^ pcolor, chr *, chr *);
|
||||||
*/
|
*/
|
||||||
static struct sset * /* NULL if goes to empty set */
|
static struct sset * /* NULL if goes to empty set */
|
||||||
miss(struct vars * v, /* used only for debug flags */
|
miss(v, d, css, co, cp, start)
|
||||||
struct dfa * d,
|
struct vars *v; /* used only for debug flags */
|
||||||
struct sset * css,
|
struct dfa *d;
|
||||||
pcolor co,
|
struct sset *css;
|
||||||
chr *cp, /* next chr */
|
pcolor co;
|
||||||
chr *start) /* where the attempt got started */
|
chr *cp; /* next chr */
|
||||||
|
chr *start; /* where the attempt got started */
|
||||||
{
|
{
|
||||||
struct cnfa *cnfa = d->cnfa;
|
struct cnfa *cnfa = d->cnfa;
|
||||||
int i;
|
int i;
|
||||||
@@ -445,8 +432,7 @@ miss(struct vars * v, /* used only for debug flags */
|
|||||||
int sawlacons;
|
int sawlacons;
|
||||||
|
|
||||||
/* for convenience, we can be called even if it might not be a miss */
|
/* for convenience, we can be called even if it might not be a miss */
|
||||||
if (css->outs[co] != NULL)
|
if (css->outs[co] != NULL) {
|
||||||
{
|
|
||||||
FDEBUG(("hit\n"));
|
FDEBUG(("hit\n"));
|
||||||
return css->outs[co];
|
return css->outs[co];
|
||||||
}
|
}
|
||||||
@@ -460,9 +446,8 @@ miss(struct vars * v, /* used only for debug flags */
|
|||||||
gotstate = 0;
|
gotstate = 0;
|
||||||
for (i = 0; i < d->nstates; i++)
|
for (i = 0; i < d->nstates; i++)
|
||||||
if (ISBSET(css->states, i))
|
if (ISBSET(css->states, i))
|
||||||
for (ca = cnfa->states[i] + 1; ca->co != COLORLESS; ca++)
|
for (ca = cnfa->states[i]+1; ca->co != COLORLESS; ca++)
|
||||||
if (ca->co == co)
|
if (ca->co == co) {
|
||||||
{
|
|
||||||
BSET(d->work, ca->to);
|
BSET(d->work, ca->to);
|
||||||
gotstate = 1;
|
gotstate = 1;
|
||||||
if (ca->to == cnfa->post)
|
if (ca->to == cnfa->post)
|
||||||
@@ -471,16 +456,14 @@ miss(struct vars * v, /* used only for debug flags */
|
|||||||
noprogress = 0;
|
noprogress = 0;
|
||||||
FDEBUG(("%d -> %d\n", i, ca->to));
|
FDEBUG(("%d -> %d\n", i, ca->to));
|
||||||
}
|
}
|
||||||
dolacons = (gotstate) ? (cnfa->flags & HASLACONS) : 0;
|
dolacons = (gotstate) ? (cnfa->flags&HASLACONS) : 0;
|
||||||
sawlacons = 0;
|
sawlacons = 0;
|
||||||
while (dolacons)
|
while (dolacons) { /* transitive closure */
|
||||||
{ /* transitive closure */
|
|
||||||
dolacons = 0;
|
dolacons = 0;
|
||||||
for (i = 0; i < d->nstates; i++)
|
for (i = 0; i < d->nstates; i++)
|
||||||
if (ISBSET(d->work, i))
|
if (ISBSET(d->work, i))
|
||||||
for (ca = cnfa->states[i] + 1; ca->co != COLORLESS;
|
for (ca = cnfa->states[i]+1; ca->co != COLORLESS;
|
||||||
ca++)
|
ca++) {
|
||||||
{
|
|
||||||
if (ca->co <= cnfa->ncolors)
|
if (ca->co <= cnfa->ncolors)
|
||||||
continue; /* NOTE CONTINUE */
|
continue; /* NOTE CONTINUE */
|
||||||
sawlacons = 1;
|
sawlacons = 1;
|
||||||
@@ -503,13 +486,11 @@ miss(struct vars * v, /* used only for debug flags */
|
|||||||
|
|
||||||
/* next, is that in the cache? */
|
/* next, is that in the cache? */
|
||||||
for (p = d->ssets, i = d->nssused; i > 0; p++, i--)
|
for (p = d->ssets, i = d->nssused; i > 0; p++, i--)
|
||||||
if (HIT(h, d->work, p, d->wordsper))
|
if (HIT(h, d->work, p, d->wordsper)) {
|
||||||
{
|
|
||||||
FDEBUG(("cached c%d\n", p - d->ssets));
|
FDEBUG(("cached c%d\n", p - d->ssets));
|
||||||
break; /* NOTE BREAK OUT */
|
break; /* NOTE BREAK OUT */
|
||||||
}
|
}
|
||||||
if (i == 0)
|
if (i == 0) { /* nope, need a new cache entry */
|
||||||
{ /* nope, need a new cache entry */
|
|
||||||
p = getvacant(v, d, cp, start);
|
p = getvacant(v, d, cp, start);
|
||||||
assert(p != css);
|
assert(p != css);
|
||||||
for (i = 0; i < d->wordsper; i++)
|
for (i = 0; i < d->wordsper; i++)
|
||||||
@@ -521,25 +502,26 @@ miss(struct vars * v, /* used only for debug flags */
|
|||||||
/* lastseen to be dealt with by caller */
|
/* lastseen to be dealt with by caller */
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!sawlacons)
|
if (!sawlacons) { /* lookahead conds. always cache miss */
|
||||||
{ /* lookahead conds. always cache miss */
|
|
||||||
FDEBUG(("c%d[%d]->c%d\n", css - d->ssets, co, p - d->ssets));
|
FDEBUG(("c%d[%d]->c%d\n", css - d->ssets, co, p - d->ssets));
|
||||||
css->outs[co] = p;
|
css->outs[co] = p;
|
||||||
css->inchain[co] = p->ins;
|
css->inchain[co] = p->ins;
|
||||||
p->ins.ss = css;
|
p->ins.ss = css;
|
||||||
p->ins.co = (color) co;
|
p->ins.co = (color)co;
|
||||||
}
|
}
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* lacon - lookahead-constraint checker for miss()
|
- lacon - lookahead-constraint checker for miss()
|
||||||
|
^ static int lacon(struct vars *, struct cnfa *, chr *, pcolor);
|
||||||
*/
|
*/
|
||||||
static int /* predicate: constraint satisfied? */
|
static int /* predicate: constraint satisfied? */
|
||||||
lacon(struct vars * v,
|
lacon(v, pcnfa, cp, co)
|
||||||
struct cnfa * pcnfa, /* parent cnfa */
|
struct vars *v;
|
||||||
chr *cp,
|
struct cnfa *pcnfa; /* parent cnfa */
|
||||||
pcolor co) /* "color" of the lookahead constraint */
|
chr *cp;
|
||||||
|
pcolor co; /* "color" of the lookahead constraint */
|
||||||
{
|
{
|
||||||
int n;
|
int n;
|
||||||
struct subre *sub;
|
struct subre *sub;
|
||||||
@@ -552,27 +534,28 @@ lacon(struct vars * v,
|
|||||||
FDEBUG(("=== testing lacon %d\n", n));
|
FDEBUG(("=== testing lacon %d\n", n));
|
||||||
sub = &v->g->lacons[n];
|
sub = &v->g->lacons[n];
|
||||||
d = newdfa(v, &sub->cnfa, &v->g->cmap, &sd);
|
d = newdfa(v, &sub->cnfa, &v->g->cmap, &sd);
|
||||||
if (d == NULL)
|
if (d == NULL) {
|
||||||
{
|
|
||||||
ERR(REG_ESPACE);
|
ERR(REG_ESPACE);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
end = longest(v, d, cp, v->stop, (int *) NULL);
|
end = longest(v, d, cp, v->stop, (int *)NULL);
|
||||||
freedfa(d);
|
freedfa(d);
|
||||||
FDEBUG(("=== lacon %d match %d\n", n, (end != NULL)));
|
FDEBUG(("=== lacon %d match %d\n", n, (end != NULL)));
|
||||||
return (sub->subno) ? (end != NULL) : (end == NULL);
|
return (sub->subno) ? (end != NULL) : (end == NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* getvacant - get a vacant state set
|
- getvacant - get a vacant state set
|
||||||
* This routine clears out the inarcs and outarcs, but does not otherwise
|
* This routine clears out the inarcs and outarcs, but does not otherwise
|
||||||
* clear the innards of the state set -- that's up to the caller.
|
* clear the innards of the state set -- that's up to the caller.
|
||||||
|
^ static struct sset *getvacant(struct vars *, struct dfa *, chr *, chr *);
|
||||||
*/
|
*/
|
||||||
static struct sset *
|
static struct sset *
|
||||||
getvacant(struct vars * v, /* used only for debug flags */
|
getvacant(v, d, cp, start)
|
||||||
struct dfa * d,
|
struct vars *v; /* used only for debug flags */
|
||||||
chr *cp,
|
struct dfa *d;
|
||||||
chr *start)
|
chr *cp;
|
||||||
|
chr *start;
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
struct sset *ss;
|
struct sset *ss;
|
||||||
@@ -582,14 +565,13 @@ getvacant(struct vars * v, /* used only for debug flags */
|
|||||||
color co;
|
color co;
|
||||||
|
|
||||||
ss = pickss(v, d, cp, start);
|
ss = pickss(v, d, cp, start);
|
||||||
assert(!(ss->flags & LOCKED));
|
assert(!(ss->flags&LOCKED));
|
||||||
|
|
||||||
/* clear out its inarcs, including self-referential ones */
|
/* clear out its inarcs, including self-referential ones */
|
||||||
ap = ss->ins;
|
ap = ss->ins;
|
||||||
while ((p = ap.ss) != NULL)
|
while ((p = ap.ss) != NULL) {
|
||||||
{
|
|
||||||
co = ap.co;
|
co = ap.co;
|
||||||
FDEBUG(("zapping c%d's %ld outarc\n", p - d->ssets, (long) co));
|
FDEBUG(("zapping c%d's %ld outarc\n", p - d->ssets, (long)co));
|
||||||
p->outs[co] = NULL;
|
p->outs[co] = NULL;
|
||||||
ap = p->inchain[co];
|
ap = p->inchain[co];
|
||||||
p->inchain[co].ss = NULL; /* paranoia */
|
p->inchain[co].ss = NULL; /* paranoia */
|
||||||
@@ -597,8 +579,7 @@ getvacant(struct vars * v, /* used only for debug flags */
|
|||||||
ss->ins.ss = NULL;
|
ss->ins.ss = NULL;
|
||||||
|
|
||||||
/* take it off the inarc chains of the ssets reached by its outarcs */
|
/* take it off the inarc chains of the ssets reached by its outarcs */
|
||||||
for (i = 0; i < d->ncolors; i++)
|
for (i = 0; i < d->ncolors; i++) {
|
||||||
{
|
|
||||||
p = ss->outs[i];
|
p = ss->outs[i];
|
||||||
assert(p != ss); /* not self-referential */
|
assert(p != ss); /* not self-referential */
|
||||||
if (p == NULL)
|
if (p == NULL)
|
||||||
@@ -606,8 +587,7 @@ getvacant(struct vars * v, /* used only for debug flags */
|
|||||||
FDEBUG(("del outarc %d from c%d's in chn\n", i, p - d->ssets));
|
FDEBUG(("del outarc %d from c%d's in chn\n", i, p - d->ssets));
|
||||||
if (p->ins.ss == ss && p->ins.co == i)
|
if (p->ins.ss == ss && p->ins.co == i)
|
||||||
p->ins = ss->inchain[i];
|
p->ins = ss->inchain[i];
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
assert(p->ins.ss != NULL);
|
assert(p->ins.ss != NULL);
|
||||||
for (ap = p->ins; ap.ss != NULL &&
|
for (ap = p->ins; ap.ss != NULL &&
|
||||||
!(ap.ss == ss && ap.co == i);
|
!(ap.ss == ss && ap.co == i);
|
||||||
@@ -621,12 +601,12 @@ getvacant(struct vars * v, /* used only for debug flags */
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* if ss was a success state, may need to remember location */
|
/* if ss was a success state, may need to remember location */
|
||||||
if ((ss->flags & POSTSTATE) && ss->lastseen != d->lastpost &&
|
if ((ss->flags&POSTSTATE) && ss->lastseen != d->lastpost &&
|
||||||
(d->lastpost == NULL || d->lastpost < ss->lastseen))
|
(d->lastpost == NULL || d->lastpost < ss->lastseen))
|
||||||
d->lastpost = ss->lastseen;
|
d->lastpost = ss->lastseen;
|
||||||
|
|
||||||
/* likewise for a no-progress state */
|
/* likewise for a no-progress state */
|
||||||
if ((ss->flags & NOPROGRESS) && ss->lastseen != d->lastnopr &&
|
if ((ss->flags&NOPROGRESS) && ss->lastseen != d->lastnopr &&
|
||||||
(d->lastnopr == NULL || d->lastnopr < ss->lastseen))
|
(d->lastnopr == NULL || d->lastnopr < ss->lastseen))
|
||||||
d->lastnopr = ss->lastseen;
|
d->lastnopr = ss->lastseen;
|
||||||
|
|
||||||
@@ -634,13 +614,15 @@ getvacant(struct vars * v, /* used only for debug flags */
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* pickss - pick the next stateset to be used
|
- pickss - pick the next stateset to be used
|
||||||
|
^ static struct sset *pickss(struct vars *, struct dfa *, chr *, chr *);
|
||||||
*/
|
*/
|
||||||
static struct sset *
|
static struct sset *
|
||||||
pickss(struct vars * v, /* used only for debug flags */
|
pickss(v, d, cp, start)
|
||||||
struct dfa * d,
|
struct vars *v; /* used only for debug flags */
|
||||||
chr *cp,
|
struct dfa *d;
|
||||||
chr *start)
|
chr *cp;
|
||||||
|
chr *start;
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
struct sset *ss;
|
struct sset *ss;
|
||||||
@@ -648,8 +630,7 @@ pickss(struct vars * v, /* used only for debug flags */
|
|||||||
chr *ancient;
|
chr *ancient;
|
||||||
|
|
||||||
/* shortcut for cases where cache isn't full */
|
/* shortcut for cases where cache isn't full */
|
||||||
if (d->nssused < d->nssets)
|
if (d->nssused < d->nssets) {
|
||||||
{
|
|
||||||
i = d->nssused;
|
i = d->nssused;
|
||||||
d->nssused++;
|
d->nssused++;
|
||||||
ss = &d->ssets[i];
|
ss = &d->ssets[i];
|
||||||
@@ -661,8 +642,7 @@ pickss(struct vars * v, /* used only for debug flags */
|
|||||||
ss->ins.co = WHITE; /* give it some value */
|
ss->ins.co = WHITE; /* give it some value */
|
||||||
ss->outs = &d->outsarea[i * d->ncolors];
|
ss->outs = &d->outsarea[i * d->ncolors];
|
||||||
ss->inchain = &d->incarea[i * d->ncolors];
|
ss->inchain = &d->incarea[i * d->ncolors];
|
||||||
for (i = 0; i < d->ncolors; i++)
|
for (i = 0; i < d->ncolors; i++) {
|
||||||
{
|
|
||||||
ss->outs[i] = NULL;
|
ss->outs[i] = NULL;
|
||||||
ss->inchain[i].ss = NULL;
|
ss->inchain[i].ss = NULL;
|
||||||
}
|
}
|
||||||
@@ -670,22 +650,20 @@ pickss(struct vars * v, /* used only for debug flags */
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* look for oldest, or old enough anyway */
|
/* look for oldest, or old enough anyway */
|
||||||
if (cp - start > d->nssets * 2 / 3) /* oldest 33% are expendable */
|
if (cp - start > d->nssets*2/3) /* oldest 33% are expendable */
|
||||||
ancient = cp - d->nssets * 2 / 3;
|
ancient = cp - d->nssets*2/3;
|
||||||
else
|
else
|
||||||
ancient = start;
|
ancient = start;
|
||||||
for (ss = d->search, end = &d->ssets[d->nssets]; ss < end; ss++)
|
for (ss = d->search, end = &d->ssets[d->nssets]; ss < end; ss++)
|
||||||
if ((ss->lastseen == NULL || ss->lastseen < ancient) &&
|
if ((ss->lastseen == NULL || ss->lastseen < ancient) &&
|
||||||
!(ss->flags & LOCKED))
|
!(ss->flags&LOCKED)) {
|
||||||
{
|
|
||||||
d->search = ss + 1;
|
d->search = ss + 1;
|
||||||
FDEBUG(("replacing c%d\n", ss - d->ssets));
|
FDEBUG(("replacing c%d\n", ss - d->ssets));
|
||||||
return ss;
|
return ss;
|
||||||
}
|
}
|
||||||
for (ss = d->ssets, end = d->search; ss < end; ss++)
|
for (ss = d->ssets, end = d->search; ss < end; ss++)
|
||||||
if ((ss->lastseen == NULL || ss->lastseen < ancient) &&
|
if ((ss->lastseen == NULL || ss->lastseen < ancient) &&
|
||||||
!(ss->flags & LOCKED))
|
!(ss->flags&LOCKED)) {
|
||||||
{
|
|
||||||
d->search = ss + 1;
|
d->search = ss + 1;
|
||||||
FDEBUG(("replacing c%d\n", ss - d->ssets));
|
FDEBUG(("replacing c%d\n", ss - d->ssets));
|
||||||
return ss;
|
return ss;
|
||||||
|
@@ -27,8 +27,6 @@
|
|||||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $Header: /projects/cvsroot/pgsql-server/src/backend/regex/regerror.c,v 1.26 2003/08/04 00:43:21 momjian Exp $
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "regguts.h"
|
#include "regguts.h"
|
||||||
@@ -37,45 +35,34 @@
|
|||||||
static char unk[] = "*** unknown regex error code 0x%x ***";
|
static char unk[] = "*** unknown regex error code 0x%x ***";
|
||||||
|
|
||||||
/* struct to map among codes, code names, and explanations */
|
/* struct to map among codes, code names, and explanations */
|
||||||
static struct rerr
|
static struct rerr {
|
||||||
{
|
|
||||||
int code;
|
int code;
|
||||||
char *name;
|
char *name;
|
||||||
char *explain;
|
char *explain;
|
||||||
} rerrs[] =
|
} rerrs[] = {
|
||||||
|
|
||||||
{
|
|
||||||
/* the actual table is built from regex.h */
|
/* the actual table is built from regex.h */
|
||||||
#include "regerrs.h"
|
# include "regerrs.h"
|
||||||
{
|
{ -1, "", "oops" }, /* explanation special-cased in code */
|
||||||
-1, "", "oops"
|
|
||||||
}, /* explanation special-cased in code */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
size_t
|
|
||||||
regerror(int errcode, /* error code, or REG_ATOI or REG_ITOA */
|
|
||||||
const regex_t *preg, /* associated regex_t (unused at present) */
|
|
||||||
char *errbuf, /* result buffer (unless errbuf_size==0) */
|
|
||||||
size_t errbuf_size) /* available space in errbuf, can be 0 */
|
|
||||||
{ return wx_regerror(errcode, preg, errbuf, errbuf_size); }
|
|
||||||
/*
|
/*
|
||||||
* pg_regerror - the interface to error numbers
|
- regerror - the interface to error numbers
|
||||||
*/
|
*/
|
||||||
/* ARGSUSED */
|
/* ARGSUSED */
|
||||||
size_t /* actual space needed (including NUL) */
|
size_t /* actual space needed (including NUL) */
|
||||||
wx_regerror(int errcode, /* error code, or REG_ATOI or REG_ITOA */
|
regerror(errcode, preg, errbuf, errbuf_size)
|
||||||
const regex_t *preg, /* associated regex_t (unused at present) */
|
int errcode; /* error code, or REG_ATOI or REG_ITOA */
|
||||||
char *errbuf, /* result buffer (unless errbuf_size==0) */
|
CONST regex_t *preg; /* associated regex_t (unused at present) */
|
||||||
size_t errbuf_size) /* available space in errbuf, can be 0 */
|
char *errbuf; /* result buffer (unless errbuf_size==0) */
|
||||||
|
size_t errbuf_size; /* available space in errbuf, can be 0 */
|
||||||
{
|
{
|
||||||
struct rerr *r;
|
struct rerr *r;
|
||||||
char *msg;
|
char *msg;
|
||||||
char convbuf[sizeof(unk) + 50]; /* 50 = plenty for int */
|
char convbuf[sizeof(unk)+50]; /* 50 = plenty for int */
|
||||||
size_t len;
|
size_t len;
|
||||||
int icode;
|
int icode;
|
||||||
|
|
||||||
switch (errcode)
|
switch (errcode) {
|
||||||
{
|
|
||||||
case REG_ATOI: /* convert name to number */
|
case REG_ATOI: /* convert name to number */
|
||||||
for (r = rerrs; r->code >= 0; r++)
|
for (r = rerrs; r->code >= 0; r++)
|
||||||
if (strcmp(r->name, errbuf) == 0)
|
if (strcmp(r->name, errbuf) == 0)
|
||||||
@@ -90,9 +77,8 @@ wx_regerror(int errcode, /* error code, or REG_ATOI or REG_ITOA */
|
|||||||
break;
|
break;
|
||||||
if (r->code >= 0)
|
if (r->code >= 0)
|
||||||
msg = r->name;
|
msg = r->name;
|
||||||
else
|
else { /* unknown; tell him the number */
|
||||||
{ /* unknown; tell him the number */
|
sprintf(convbuf, "REG_%u", (unsigned)icode);
|
||||||
sprintf(convbuf, "REG_%u", (unsigned) icode);
|
|
||||||
msg = convbuf;
|
msg = convbuf;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -102,8 +88,7 @@ wx_regerror(int errcode, /* error code, or REG_ATOI or REG_ITOA */
|
|||||||
break;
|
break;
|
||||||
if (r->code >= 0)
|
if (r->code >= 0)
|
||||||
msg = r->explain;
|
msg = r->explain;
|
||||||
else
|
else { /* unknown; say so */
|
||||||
{ /* unknown; say so */
|
|
||||||
sprintf(convbuf, unk, errcode);
|
sprintf(convbuf, unk, errcode);
|
||||||
msg = convbuf;
|
msg = convbuf;
|
||||||
}
|
}
|
||||||
@@ -111,14 +96,12 @@ wx_regerror(int errcode, /* error code, or REG_ATOI or REG_ITOA */
|
|||||||
}
|
}
|
||||||
|
|
||||||
len = strlen(msg) + 1; /* space needed, including NUL */
|
len = strlen(msg) + 1; /* space needed, including NUL */
|
||||||
if (errbuf_size > 0)
|
if (errbuf_size > 0) {
|
||||||
{
|
|
||||||
if (errbuf_size > len)
|
if (errbuf_size > len)
|
||||||
strcpy(errbuf, msg);
|
strcpy(errbuf, msg);
|
||||||
else
|
else { /* truncate to fit */
|
||||||
{ /* truncate to fit */
|
strncpy(errbuf, msg, errbuf_size-1);
|
||||||
memcpy(errbuf, msg, errbuf_size - 1); /*RN - was strncpy*/
|
errbuf[errbuf_size-1] = '\0';
|
||||||
errbuf[errbuf_size - 1] = '\0';
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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,6 +1,5 @@
|
|||||||
#ifndef _REGEX_H_
|
#ifndef _REGEX_H_
|
||||||
#define _REGEX_H_ /* never again */
|
#define _REGEX_H_ /* never again */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* regular expressions
|
* regular expressions
|
||||||
*
|
*
|
||||||
@@ -30,35 +29,98 @@
|
|||||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $Id$
|
*
|
||||||
|
*
|
||||||
|
* Prototypes etc. marked with "^" within comments get gathered up (and
|
||||||
|
* possibly edited) by the regfwd program and inserted near the bottom of
|
||||||
|
* this file.
|
||||||
|
*
|
||||||
|
* We offer the option of declaring one wide-character version of the
|
||||||
|
* RE functions as well as the char versions. To do that, define
|
||||||
|
* __REG_WIDE_T to the type of wide characters (unfortunately, there
|
||||||
|
* is no consensus that wchar_t is suitable) and __REG_WIDE_COMPILE and
|
||||||
|
* __REG_WIDE_EXEC to the names to be used for the compile and execute
|
||||||
|
* functions (suggestion: re_Xcomp and re_Xexec, where X is a letter
|
||||||
|
* suggestive of the wide type, e.g. re_ucomp and re_uexec for Unicode).
|
||||||
|
* For cranky old compilers, it may be necessary to do something like:
|
||||||
|
* #define __REG_WIDE_COMPILE(a,b,c,d) re_Xcomp(a,b,c,d)
|
||||||
|
* #define __REG_WIDE_EXEC(a,b,c,d,e,f,g) re_Xexec(a,b,c,d,e,f,g)
|
||||||
|
* rather than just #defining the names as parameterless macros.
|
||||||
|
*
|
||||||
|
* For some specialized purposes, it may be desirable to suppress the
|
||||||
|
* declarations of the "front end" functions, regcomp() and regexec(),
|
||||||
|
* or of the char versions of the compile and execute functions. To
|
||||||
|
* suppress the front-end functions, define __REG_NOFRONT. To suppress
|
||||||
|
* the char versions, define __REG_NOCHAR.
|
||||||
|
*
|
||||||
|
* The right place to do those defines (and some others you may want, see
|
||||||
|
* below) would be <sys/types.h>. If you don't have control of that file,
|
||||||
|
* the right place to add your own defines to this file is marked below.
|
||||||
|
* This is normally done automatically, by the makefile and regmkhdr, based
|
||||||
|
* on the contents of regcustom.h.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Add your own defines, if needed, here.
|
* voodoo for C++
|
||||||
*/
|
*/
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*****************************
|
|
||||||
WXWINDOWS CUSTOM
|
|
||||||
*****************************/
|
|
||||||
#ifndef _REGEX_CUSTOM_H_
|
|
||||||
# define wx_wchar wxChar
|
|
||||||
/* FreeBSD, Watcom and DMars require this, CW doesn't have nor need it. */
|
|
||||||
/* Others also don't seem to need it. If you have an error related to */
|
|
||||||
/* (not) including <sys/types.h> please report details to */
|
|
||||||
/* wx-dev@lists.wxwindows.org */
|
|
||||||
# if defined(__UNIX__) || defined(__WATCOMC__) || defined(__DIGITALMARS__)
|
|
||||||
# include <sys/types.h>
|
|
||||||
# endif
|
|
||||||
#endif /* ndef _REGEX_CUSTOM_H_ */
|
|
||||||
/*****************************
|
|
||||||
END WXWINDOWS CUSTOM
|
|
||||||
*****************************/
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
/*
|
||||||
|
* Add your own defines, if needed, here.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Location where a chunk of regcustom.h is automatically spliced into
|
||||||
|
* this file (working from its prototype, regproto.h).
|
||||||
|
*/
|
||||||
|
/* --- begin --- */
|
||||||
|
/* ensure certain things don't sneak in from system headers */
|
||||||
|
#ifdef __REG_WIDE_T
|
||||||
|
#undef __REG_WIDE_T
|
||||||
|
#endif
|
||||||
|
#ifdef __REG_WIDE_COMPILE
|
||||||
|
#undef __REG_WIDE_COMPILE
|
||||||
|
#endif
|
||||||
|
#ifdef __REG_WIDE_EXEC
|
||||||
|
#undef __REG_WIDE_EXEC
|
||||||
|
#endif
|
||||||
|
#ifdef __REG_REGOFF_T
|
||||||
|
#undef __REG_REGOFF_T
|
||||||
|
#endif
|
||||||
|
#ifdef __REG_VOID_T
|
||||||
|
#undef __REG_VOID_T
|
||||||
|
#endif
|
||||||
|
#ifdef __REG_CONST
|
||||||
|
#undef __REG_CONST
|
||||||
|
#endif
|
||||||
|
#ifdef __REG_NOFRONT
|
||||||
|
#undef __REG_NOFRONT
|
||||||
|
#endif
|
||||||
|
#ifdef __REG_NOCHAR
|
||||||
|
#undef __REG_NOCHAR
|
||||||
|
#endif
|
||||||
|
/* interface types */
|
||||||
|
#define __REG_WIDE_T Tcl_UniChar
|
||||||
|
#define __REG_REGOFF_T long /* not really right, but good enough... */
|
||||||
|
#define __REG_VOID_T VOID
|
||||||
|
#define __REG_CONST CONST
|
||||||
|
/* names and declarations */
|
||||||
|
#define __REG_WIDE_COMPILE TclReComp
|
||||||
|
#define __REG_WIDE_EXEC TclReExec
|
||||||
|
#define __REG_NOFRONT /* don't want regcomp() and regexec() */
|
||||||
|
#define __REG_NOCHAR /* or the char versions */
|
||||||
|
#define regfree TclReFree
|
||||||
|
#define regerror TclReError
|
||||||
|
/* --- end --- */
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* interface types etc.
|
* interface types etc.
|
||||||
@@ -66,34 +128,58 @@ extern "C" {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* regoff_t has to be large enough to hold either off_t or ssize_t,
|
* regoff_t has to be large enough to hold either off_t or ssize_t,
|
||||||
* and must be signed; it's only a guess that long is suitable.
|
* and must be signed; it's only a guess that long is suitable, so we
|
||||||
|
* offer <sys/types.h> an override.
|
||||||
*/
|
*/
|
||||||
|
#ifdef __REG_REGOFF_T
|
||||||
|
typedef __REG_REGOFF_T regoff_t;
|
||||||
|
#else
|
||||||
typedef long regoff_t;
|
typedef long regoff_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For benefit of old compilers, we offer <sys/types.h> the option of
|
||||||
|
* overriding the `void' type used to declare nonexistent return types.
|
||||||
|
*/
|
||||||
|
#ifdef __REG_VOID_T
|
||||||
|
typedef __REG_VOID_T re_void;
|
||||||
|
#else
|
||||||
|
typedef void re_void;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Also for benefit of old compilers, <sys/types.h> can supply a macro
|
||||||
|
* which expands to a substitute for `const'.
|
||||||
|
*/
|
||||||
|
#ifndef __REG_CONST
|
||||||
|
#define __REG_CONST const
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* other interface types
|
* other interface types
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* the biggie, a compiled RE (or rather, a front end to same) */
|
/* the biggie, a compiled RE (or rather, a front end to same) */
|
||||||
typedef struct
|
typedef struct {
|
||||||
{
|
|
||||||
int re_magic; /* magic number */
|
int re_magic; /* magic number */
|
||||||
size_t re_nsub; /* number of subexpressions */
|
size_t re_nsub; /* number of subexpressions */
|
||||||
long re_info; /* information about RE */
|
long re_info; /* information about RE */
|
||||||
#define REG_UBACKREF 000001
|
# define REG_UBACKREF 000001
|
||||||
#define REG_ULOOKAHEAD 000002
|
# define REG_ULOOKAHEAD 000002
|
||||||
#define REG_UBOUNDS 000004
|
# define REG_UBOUNDS 000004
|
||||||
#define REG_UBRACES 000010
|
# define REG_UBRACES 000010
|
||||||
#define REG_UBSALNUM 000020
|
# define REG_UBSALNUM 000020
|
||||||
#define REG_UPBOTCH 000040
|
# define REG_UPBOTCH 000040
|
||||||
#define REG_UBBS 000100
|
# define REG_UBBS 000100
|
||||||
#define REG_UNONPOSIX 000200
|
# define REG_UNONPOSIX 000200
|
||||||
#define REG_UUNSPEC 000400
|
# define REG_UUNSPEC 000400
|
||||||
#define REG_UUNPORT 001000
|
# define REG_UUNPORT 001000
|
||||||
#define REG_ULOCALE 002000
|
# define REG_ULOCALE 002000
|
||||||
#define REG_UEMPTYMATCH 004000
|
# define REG_UEMPTYMATCH 004000
|
||||||
#define REG_UIMPOSSIBLE 010000
|
# define REG_UIMPOSSIBLE 010000
|
||||||
#define REG_USHORTEST 020000
|
# define REG_USHORTEST 020000
|
||||||
int re_csize; /* sizeof(character) */
|
int re_csize; /* sizeof(character) */
|
||||||
char *re_endp; /* backward compatibility kludge */
|
char *re_endp; /* backward compatibility kludge */
|
||||||
/* the rest is opaque pointers to hidden innards */
|
/* the rest is opaque pointers to hidden innards */
|
||||||
@@ -102,22 +188,29 @@ typedef struct
|
|||||||
} regex_t;
|
} regex_t;
|
||||||
|
|
||||||
/* result reporting (may acquire more fields later) */
|
/* result reporting (may acquire more fields later) */
|
||||||
typedef struct
|
typedef struct {
|
||||||
{
|
|
||||||
regoff_t rm_so; /* start of substring */
|
regoff_t rm_so; /* start of substring */
|
||||||
regoff_t rm_eo; /* end of substring */
|
regoff_t rm_eo; /* end of substring */
|
||||||
} regmatch_t;
|
} regmatch_t;
|
||||||
|
|
||||||
/* supplementary control and reporting */
|
/* supplementary control and reporting */
|
||||||
typedef struct
|
typedef struct {
|
||||||
{
|
|
||||||
regmatch_t rm_extend; /* see REG_EXPECT */
|
regmatch_t rm_extend; /* see REG_EXPECT */
|
||||||
} rm_detail_t;
|
} rm_detail_t;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* regex compilation flags
|
* compilation
|
||||||
|
^ #ifndef __REG_NOCHAR
|
||||||
|
^ int re_comp(regex_t *, __REG_CONST char *, size_t, int);
|
||||||
|
^ #endif
|
||||||
|
^ #ifndef __REG_NOFRONT
|
||||||
|
^ int regcomp(regex_t *, __REG_CONST char *, int);
|
||||||
|
^ #endif
|
||||||
|
^ #ifdef __REG_WIDE_T
|
||||||
|
^ int __REG_WIDE_COMPILE(regex_t *, __REG_CONST __REG_WIDE_T *, size_t, int);
|
||||||
|
^ #endif
|
||||||
*/
|
*/
|
||||||
#define REG_BASIC 000000 /* BREs (convenience) */
|
#define REG_BASIC 000000 /* BREs (convenience) */
|
||||||
#define REG_EXTENDED 000001 /* EREs */
|
#define REG_EXTENDED 000001 /* EREs */
|
||||||
@@ -132,8 +225,7 @@ typedef struct
|
|||||||
#define REG_NLANCH 000200 /* ^ matches after \n, $ before */
|
#define REG_NLANCH 000200 /* ^ matches after \n, $ before */
|
||||||
#define REG_NEWLINE 000300 /* newlines are line terminators */
|
#define REG_NEWLINE 000300 /* newlines are line terminators */
|
||||||
#define REG_PEND 000400 /* ugh -- backward-compatibility hack */
|
#define REG_PEND 000400 /* ugh -- backward-compatibility hack */
|
||||||
#define REG_EXPECT 001000 /* report details on partial/limited
|
#define REG_EXPECT 001000 /* report details on partial/limited matches */
|
||||||
* matches */
|
|
||||||
#define REG_BOSONLY 002000 /* temporary kludge for BOS-only matches */
|
#define REG_BOSONLY 002000 /* temporary kludge for BOS-only matches */
|
||||||
#define REG_DUMP 004000 /* none of your business :-) */
|
#define REG_DUMP 004000 /* none of your business :-) */
|
||||||
#define REG_FAKE 010000 /* none of your business :-) */
|
#define REG_FAKE 010000 /* none of your business :-) */
|
||||||
@@ -142,7 +234,18 @@ typedef struct
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* regex execution flags
|
* execution
|
||||||
|
^ #ifndef __REG_NOCHAR
|
||||||
|
^ int re_exec(regex_t *, __REG_CONST char *, size_t,
|
||||||
|
^ rm_detail_t *, size_t, regmatch_t [], int);
|
||||||
|
^ #endif
|
||||||
|
^ #ifndef __REG_NOFRONT
|
||||||
|
^ int regexec(regex_t *, __REG_CONST char *, size_t, regmatch_t [], int);
|
||||||
|
^ #endif
|
||||||
|
^ #ifdef __REG_WIDE_T
|
||||||
|
^ int __REG_WIDE_EXEC(regex_t *, __REG_CONST __REG_WIDE_T *, size_t,
|
||||||
|
^ rm_detail_t *, size_t, regmatch_t [], int);
|
||||||
|
^ #endif
|
||||||
*/
|
*/
|
||||||
#define REG_NOTBOL 0001 /* BOS is not BOL */
|
#define REG_NOTBOL 0001 /* BOS is not BOL */
|
||||||
#define REG_NOTEOL 0002 /* EOS is not EOL */
|
#define REG_NOTEOL 0002 /* EOS is not EOL */
|
||||||
@@ -152,10 +255,24 @@ typedef struct
|
|||||||
#define REG_SMALL 0040 /* none of your business */
|
#define REG_SMALL 0040 /* none of your business */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* misc generics (may be more functions here eventually)
|
||||||
|
^ re_void regfree(regex_t *);
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* error reporting
|
* error reporting
|
||||||
* Be careful if modifying the list of error codes -- the table used by
|
* Be careful if modifying the list of error codes -- the table used by
|
||||||
* regerror() is generated automatically from this file!
|
* regerror() is generated automatically from this file!
|
||||||
|
*
|
||||||
|
* Note that there is no wide-char variant of regerror at this time; what
|
||||||
|
* kind of character is used for error reports is independent of what kind
|
||||||
|
* is used in matching.
|
||||||
|
*
|
||||||
|
^ extern size_t regerror(int, __REG_CONST regex_t *, char *, size_t);
|
||||||
*/
|
*/
|
||||||
#define REG_OKAY 0 /* no errors detected */
|
#define REG_OKAY 0 /* no errors detected */
|
||||||
#define REG_NOMATCH 1 /* failed to match */
|
#define REG_NOMATCH 1 /* failed to match */
|
||||||
@@ -173,8 +290,7 @@ typedef struct
|
|||||||
#define REG_BADRPT 13 /* quantifier operand invalid */
|
#define REG_BADRPT 13 /* quantifier operand invalid */
|
||||||
#define REG_ASSERT 15 /* "can't happen" -- you found a bug */
|
#define REG_ASSERT 15 /* "can't happen" -- you found a bug */
|
||||||
#define REG_INVARG 16 /* invalid argument to regex function */
|
#define REG_INVARG 16 /* invalid argument to regex function */
|
||||||
#define REG_MIXED 17 /* character widths of regex and string
|
#define REG_MIXED 17 /* character widths of regex and string differ */
|
||||||
* differ */
|
|
||||||
#define REG_BADOPT 18 /* invalid embedded option */
|
#define REG_BADOPT 18 /* invalid embedded option */
|
||||||
/* two specials for debugging and testing */
|
/* two specials for debugging and testing */
|
||||||
#define REG_ATOI 101 /* convert error-code name to number */
|
#define REG_ATOI 101 /* convert error-code name to number */
|
||||||
@@ -183,19 +299,43 @@ typedef struct
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* the prototypes for exported functions
|
* the prototypes, as possibly munched by regfwd
|
||||||
*/
|
*/
|
||||||
extern int wx_regcomp(regex_t *, const wx_wchar *, size_t, int);
|
/* =====^!^===== begin forwards =====^!^===== */
|
||||||
extern int regcomp(regex_t *, const wx_wchar *, int);
|
/* automatically gathered by fwd; do not hand-edit */
|
||||||
extern int wx_regexec(regex_t *, const wx_wchar *, size_t, rm_detail_t *, size_t, regmatch_t[], int);
|
/* === regproto.h === */
|
||||||
extern int regexec(regex_t *, const wx_wchar *, size_t, regmatch_t[], int);
|
#ifndef __REG_NOCHAR
|
||||||
extern void regfree(regex_t *);
|
int re_comp _ANSI_ARGS_((regex_t *, __REG_CONST char *, size_t, int));
|
||||||
extern size_t regerror(int, const regex_t *, char *, size_t);
|
#endif
|
||||||
extern void wx_regfree(regex_t *);
|
#ifndef __REG_NOFRONT
|
||||||
extern size_t wx_regerror(int, const regex_t *, char *, size_t);
|
int regcomp _ANSI_ARGS_((regex_t *, __REG_CONST char *, int));
|
||||||
|
#endif
|
||||||
|
#ifdef __REG_WIDE_T
|
||||||
|
int __REG_WIDE_COMPILE _ANSI_ARGS_((regex_t *, __REG_CONST __REG_WIDE_T *, size_t, int));
|
||||||
|
#endif
|
||||||
|
#ifndef __REG_NOCHAR
|
||||||
|
int re_exec _ANSI_ARGS_((regex_t *, __REG_CONST char *, size_t, rm_detail_t *, size_t, regmatch_t [], int));
|
||||||
|
#endif
|
||||||
|
#ifndef __REG_NOFRONT
|
||||||
|
int regexec _ANSI_ARGS_((regex_t *, __REG_CONST char *, size_t, regmatch_t [], int));
|
||||||
|
#endif
|
||||||
|
#ifdef __REG_WIDE_T
|
||||||
|
int __REG_WIDE_EXEC _ANSI_ARGS_((regex_t *, __REG_CONST __REG_WIDE_T *, size_t, rm_detail_t *, size_t, regmatch_t [], int));
|
||||||
|
#endif
|
||||||
|
re_void regfree _ANSI_ARGS_((regex_t *));
|
||||||
|
extern size_t regerror _ANSI_ARGS_((int, __REG_CONST regex_t *, char *, size_t));
|
||||||
|
/* automatically gathered by fwd; do not hand-edit */
|
||||||
|
/* =====^!^===== end forwards =====^!^===== */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* more C++ voodoo
|
||||||
|
*/
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* _REGEX_H_ */
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
File diff suppressed because it is too large
Load Diff
@@ -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);
|
||||||
}
|
}
|
||||||
|
@@ -26,8 +26,6 @@
|
|||||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
|
||||||
* $Id$
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@@ -45,32 +43,52 @@
|
|||||||
* Things that regcustom.h might override.
|
* Things that regcustom.h might override.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* standard header files (NULL is a reasonable indicator for them) */
|
||||||
|
#ifndef NULL
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <string.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
/* assertions */
|
/* assertions */
|
||||||
#ifndef __WXWINCE__
|
|
||||||
#ifndef assert
|
#ifndef assert
|
||||||
#ifndef REG_DEBUG
|
# ifndef REG_DEBUG
|
||||||
# ifndef NDEBUG
|
|
||||||
# define NDEBUG /* no assertions */
|
# define NDEBUG /* no assertions */
|
||||||
# endif
|
# endif
|
||||||
#endif
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#endif
|
#endif
|
||||||
#else
|
|
||||||
// To do: assertion on WinCE
|
|
||||||
#define assert(x)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* voids */
|
/* voids */
|
||||||
|
#ifndef VOID
|
||||||
|
#define VOID void /* for function return values */
|
||||||
|
#endif
|
||||||
#ifndef DISCARD
|
#ifndef DISCARD
|
||||||
#define DISCARD void /* for throwing values away */
|
#define DISCARD VOID /* for throwing values away */
|
||||||
|
#endif
|
||||||
|
#ifndef PVOID
|
||||||
|
#define PVOID VOID * /* generic pointer */
|
||||||
#endif
|
#endif
|
||||||
#ifndef VS
|
#ifndef VS
|
||||||
#define VS(x) ((void *)(x)) /* cast something to generic ptr */
|
#define VS(x) ((PVOID)(x)) /* cast something to generic ptr */
|
||||||
|
#endif
|
||||||
|
#ifndef NOPARMS
|
||||||
|
#define NOPARMS VOID /* for empty parm lists */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* const */
|
||||||
|
#ifndef CONST
|
||||||
|
#define CONST const /* for old compilers, might be empty */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* function-pointer declarator */
|
/* function-pointer declarator */
|
||||||
#ifndef FUNCPTR
|
#ifndef FUNCPTR
|
||||||
#define FUNCPTR(name, args) (*name) args
|
#if __STDC__ >= 1
|
||||||
|
#define FUNCPTR(name, args) (*name)args
|
||||||
|
#else
|
||||||
|
#define FUNCPTR(name, args) (*name)()
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* memory allocation */
|
/* memory allocation */
|
||||||
@@ -141,8 +159,7 @@
|
|||||||
#ifndef BYTBITS
|
#ifndef BYTBITS
|
||||||
#define BYTBITS 8 /* bits in a byt */
|
#define BYTBITS 8 /* bits in a byt */
|
||||||
#endif
|
#endif
|
||||||
#define BYTTAB (1<<BYTBITS) /* size of table with one entry per byt
|
#define BYTTAB (1<<BYTBITS) /* size of table with one entry per byt value */
|
||||||
* value */
|
|
||||||
#define BYTMASK (BYTTAB-1) /* bit mask for byt */
|
#define BYTMASK (BYTTAB-1) /* bit mask for byt */
|
||||||
#define NBYTS ((CHRBITS+BYTBITS-1)/BYTBITS)
|
#define NBYTS ((CHRBITS+BYTBITS-1)/BYTBITS)
|
||||||
/* the definition of GETCOLOR(), below, assumes NBYTS <= 4 */
|
/* the definition of GETCOLOR(), below, assumes NBYTS <= 4 */
|
||||||
@@ -155,7 +172,6 @@
|
|||||||
*/
|
*/
|
||||||
typedef short color; /* colors of characters */
|
typedef short color; /* colors of characters */
|
||||||
typedef int pcolor; /* what color promotes to */
|
typedef int pcolor; /* what color promotes to */
|
||||||
|
|
||||||
#define COLORLESS (-1) /* impossible color */
|
#define COLORLESS (-1) /* impossible color */
|
||||||
#define WHITE 0 /* default color, parent of all others */
|
#define WHITE 0 /* default color, parent of all others */
|
||||||
|
|
||||||
@@ -172,49 +188,43 @@ typedef int pcolor; /* what color promotes to */
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* the tree itself */
|
/* the tree itself */
|
||||||
struct colors
|
struct colors {
|
||||||
{
|
|
||||||
color ccolor[BYTTAB];
|
color ccolor[BYTTAB];
|
||||||
};
|
};
|
||||||
struct ptrs
|
struct ptrs {
|
||||||
{
|
|
||||||
union tree *pptr[BYTTAB];
|
union tree *pptr[BYTTAB];
|
||||||
};
|
};
|
||||||
union tree
|
union tree {
|
||||||
{
|
|
||||||
struct colors colors;
|
struct colors colors;
|
||||||
struct ptrs ptrs;
|
struct ptrs ptrs;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define tcolor colors.ccolor
|
#define tcolor colors.ccolor
|
||||||
#define tptr ptrs.pptr
|
#define tptr ptrs.pptr
|
||||||
|
|
||||||
/* internal per-color structure for the color machinery */
|
/* internal per-color structure for the color machinery */
|
||||||
struct colordesc
|
struct colordesc {
|
||||||
{
|
|
||||||
uchr nchrs; /* number of chars of this color */
|
uchr nchrs; /* number of chars of this color */
|
||||||
color sub; /* open subcolor (if any); free chain ptr */
|
color sub; /* open subcolor (if any); free chain ptr */
|
||||||
#define NOSUB COLORLESS
|
# define NOSUB COLORLESS
|
||||||
struct arc *arcs; /* color chain */
|
struct arc *arcs; /* color chain */
|
||||||
int flags;
|
int flags;
|
||||||
#define FREECOL 01 /* currently free */
|
# define FREECOL 01 /* currently free */
|
||||||
#define PSEUDO 02 /* pseudocolor, no real chars */
|
# define PSEUDO 02 /* pseudocolor, no real chars */
|
||||||
#define UNUSEDCOLOR(cd) ((cd)->flags&FREECOL)
|
# define UNUSEDCOLOR(cd) ((cd)->flags&FREECOL)
|
||||||
union tree *block; /* block of solid color, if any */
|
union tree *block; /* block of solid color, if any */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* the color map itself */
|
/* the color map itself */
|
||||||
struct colormap
|
struct colormap {
|
||||||
{
|
|
||||||
int magic;
|
int magic;
|
||||||
#define CMMAGIC 0x876
|
# define CMMAGIC 0x876
|
||||||
struct vars *v; /* for compile error reporting */
|
struct vars *v; /* for compile error reporting */
|
||||||
size_t ncds; /* number of colordescs */
|
size_t ncds; /* number of colordescs */
|
||||||
size_t max; /* highest in use */
|
size_t max; /* highest in use */
|
||||||
color free; /* beginning of free chain (if non-0) */
|
color free; /* beginning of free chain (if non-0) */
|
||||||
struct colordesc *cd;
|
struct colordesc *cd;
|
||||||
#define CDEND(cm) (&(cm)->cd[(cm)->max + 1])
|
# define CDEND(cm) (&(cm)->cd[(cm)->max + 1])
|
||||||
#define NINLINECDS ((size_t)10)
|
# define NINLINECDS ((size_t)10)
|
||||||
struct colordesc cdspace[NINLINECDS];
|
struct colordesc cdspace[NINLINECDS];
|
||||||
union tree tree[NBYTS]; /* tree top, plus fill blocks */
|
union tree tree[NBYTS]; /* tree top, plus fill blocks */
|
||||||
};
|
};
|
||||||
@@ -241,8 +251,7 @@ struct colormap
|
|||||||
* Interface definitions for locale-interface functions in locale.c.
|
* Interface definitions for locale-interface functions in locale.c.
|
||||||
* Multi-character collating elements (MCCEs) cause most of the trouble.
|
* Multi-character collating elements (MCCEs) cause most of the trouble.
|
||||||
*/
|
*/
|
||||||
struct cvec
|
struct cvec {
|
||||||
{
|
|
||||||
int nchrs; /* number of chrs */
|
int nchrs; /* number of chrs */
|
||||||
int chrspace; /* number of chrs possible */
|
int chrspace; /* number of chrs possible */
|
||||||
chr *chrs; /* pointer to vector of chrs */
|
chr *chrs; /* pointer to vector of chrs */
|
||||||
@@ -269,30 +278,27 @@ struct cvec
|
|||||||
*/
|
*/
|
||||||
struct state;
|
struct state;
|
||||||
|
|
||||||
struct arc
|
struct arc {
|
||||||
{
|
|
||||||
int type;
|
int type;
|
||||||
#define ARCFREE '\0'
|
# define ARCFREE '\0'
|
||||||
color co;
|
color co;
|
||||||
struct state *from; /* where it's from (and contained within) */
|
struct state *from; /* where it's from (and contained within) */
|
||||||
struct state *to; /* where it's to */
|
struct state *to; /* where it's to */
|
||||||
struct arc *outchain; /* *from's outs chain or free chain */
|
struct arc *outchain; /* *from's outs chain or free chain */
|
||||||
#define freechain outchain
|
# define freechain outchain
|
||||||
struct arc *inchain; /* *to's ins chain */
|
struct arc *inchain; /* *to's ins chain */
|
||||||
struct arc *colorchain; /* color's arc chain */
|
struct arc *colorchain; /* color's arc chain */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct arcbatch
|
struct arcbatch { /* for bulk allocation of arcs */
|
||||||
{ /* for bulk allocation of arcs */
|
|
||||||
struct arcbatch *next;
|
struct arcbatch *next;
|
||||||
#define ABSIZE 10
|
# define ABSIZE 10
|
||||||
struct arc a[ABSIZE];
|
struct arc a[ABSIZE];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct state
|
struct state {
|
||||||
{
|
|
||||||
int no;
|
int no;
|
||||||
#define FREESTATE (-1)
|
# define FREESTATE (-1)
|
||||||
char flag; /* marks special states */
|
char flag; /* marks special states */
|
||||||
int nins; /* number of inarcs */
|
int nins; /* number of inarcs */
|
||||||
struct arc *ins; /* chain of inarcs */
|
struct arc *ins; /* chain of inarcs */
|
||||||
@@ -302,13 +308,11 @@ struct state
|
|||||||
struct state *tmp; /* temporary for traversal algorithms */
|
struct state *tmp; /* temporary for traversal algorithms */
|
||||||
struct state *next; /* chain for traversing all */
|
struct state *next; /* chain for traversing all */
|
||||||
struct state *prev; /* back chain */
|
struct state *prev; /* back chain */
|
||||||
struct arcbatch oas; /* first arcbatch, avoid malloc in easy
|
struct arcbatch oas; /* first arcbatch, avoid malloc in easy case */
|
||||||
* case */
|
|
||||||
int noas; /* number of arcs used in first arcbatch */
|
int noas; /* number of arcs used in first arcbatch */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct nfa
|
struct nfa {
|
||||||
{
|
|
||||||
struct state *pre; /* pre-initial state */
|
struct state *pre; /* pre-initial state */
|
||||||
struct state *init; /* initial state */
|
struct state *init; /* initial state */
|
||||||
struct state *final; /* final state */
|
struct state *final; /* final state */
|
||||||
@@ -329,18 +333,16 @@ struct nfa
|
|||||||
/*
|
/*
|
||||||
* definitions for compacted NFA
|
* definitions for compacted NFA
|
||||||
*/
|
*/
|
||||||
struct carc
|
struct carc {
|
||||||
{
|
|
||||||
color co; /* COLORLESS is list terminator */
|
color co; /* COLORLESS is list terminator */
|
||||||
int to; /* state number */
|
int to; /* state number */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct cnfa
|
struct cnfa {
|
||||||
{
|
|
||||||
int nstates; /* number of states */
|
int nstates; /* number of states */
|
||||||
int ncolors; /* number of colors */
|
int ncolors; /* number of colors */
|
||||||
int flags;
|
int flags;
|
||||||
#define HASLACONS 01 /* uses lookahead constraints */
|
# define HASLACONS 01 /* uses lookahead constraints */
|
||||||
int pre; /* setup state number */
|
int pre; /* setup state number */
|
||||||
int post; /* teardown state number */
|
int post; /* teardown state number */
|
||||||
color bos[2]; /* colors, if any, assigned to BOS and BOL */
|
color bos[2]; /* colors, if any, assigned to BOS and BOL */
|
||||||
@@ -348,7 +350,6 @@ struct cnfa
|
|||||||
struct carc **states; /* vector of pointers to outarc lists */
|
struct carc **states; /* vector of pointers to outarc lists */
|
||||||
struct carc *arcs; /* the area for the lists */
|
struct carc *arcs; /* the area for the lists */
|
||||||
};
|
};
|
||||||
|
|
||||||
#define ZAPCNFA(cnfa) ((cnfa).nstates = 0)
|
#define ZAPCNFA(cnfa) ((cnfa).nstates = 0)
|
||||||
#define NULLCNFA(cnfa) ((cnfa).nstates == 0)
|
#define NULLCNFA(cnfa) ((cnfa).nstates == 0)
|
||||||
|
|
||||||
@@ -357,31 +358,28 @@ struct cnfa
|
|||||||
/*
|
/*
|
||||||
* subexpression tree
|
* subexpression tree
|
||||||
*/
|
*/
|
||||||
struct subre
|
struct subre {
|
||||||
{
|
char op; /* '|', '.' (concat), 'b' (backref), '(', '=' */
|
||||||
char op; /* '|', '.' (concat), 'b' (backref), '(',
|
|
||||||
* '=' */
|
|
||||||
char flags;
|
char flags;
|
||||||
#define LONGER 01 /* prefers longer match */
|
# define LONGER 01 /* prefers longer match */
|
||||||
#define SHORTER 02 /* prefers shorter match */
|
# define SHORTER 02 /* prefers shorter match */
|
||||||
#define MIXED 04 /* mixed preference below */
|
# define MIXED 04 /* mixed preference below */
|
||||||
#define CAP 010 /* capturing parens below */
|
# define CAP 010 /* capturing parens below */
|
||||||
#define BACKR 020 /* back reference below */
|
# define BACKR 020 /* back reference below */
|
||||||
#define INUSE 0100 /* in use in final tree */
|
# define INUSE 0100 /* in use in final tree */
|
||||||
#define LOCAL 03 /* bits which may not propagate up */
|
# define LOCAL 03 /* bits which may not propagate up */
|
||||||
#define LMIX(f) ((f)<<2) /* LONGER -> MIXED */
|
# define LMIX(f) ((f)<<2) /* LONGER -> MIXED */
|
||||||
#define SMIX(f) ((f)<<1) /* SHORTER -> MIXED */
|
# define SMIX(f) ((f)<<1) /* SHORTER -> MIXED */
|
||||||
#define UP(f) (((f)&~LOCAL) | (LMIX(f) & SMIX(f) & MIXED))
|
# define UP(f) (((f)&~LOCAL) | (LMIX(f) & SMIX(f) & MIXED))
|
||||||
#define MESSY(f) ((f)&(MIXED|CAP|BACKR))
|
# define MESSY(f) ((f)&(MIXED|CAP|BACKR))
|
||||||
#define PREF(f) ((f)&LOCAL)
|
# define PREF(f) ((f)&LOCAL)
|
||||||
#define PREF2(f1, f2) ((PREF(f1) != 0) ? PREF(f1) : PREF(f2))
|
# define PREF2(f1, f2) ((PREF(f1) != 0) ? PREF(f1) : PREF(f2))
|
||||||
#define COMBINE(f1, f2) (UP((f1)|(f2)) | PREF2(f1, f2))
|
# define COMBINE(f1, f2) (UP((f1)|(f2)) | PREF2(f1, f2))
|
||||||
short retry; /* index into retry memory */
|
short retry; /* index into retry memory */
|
||||||
int subno; /* subexpression number (for 'b' and '(') */
|
int subno; /* subexpression number (for 'b' and '(') */
|
||||||
short min; /* min repetitions, for backref only */
|
short min; /* min repetitions, for backref only */
|
||||||
short max; /* max repetitions, for backref only */
|
short max; /* max repetitions, for backref only */
|
||||||
struct subre *left; /* left child, if any (also freelist
|
struct subre *left; /* left child, if any (also freelist chain) */
|
||||||
* chain) */
|
|
||||||
struct subre *right; /* right child, if any */
|
struct subre *right; /* right child, if any */
|
||||||
struct state *begin; /* outarcs from here... */
|
struct state *begin; /* outarcs from here... */
|
||||||
struct state *end; /* ...ending in inarcs here */
|
struct state *end; /* ...ending in inarcs here */
|
||||||
@@ -395,9 +393,8 @@ struct subre
|
|||||||
* table of function pointers for generic manipulation functions
|
* table of function pointers for generic manipulation functions
|
||||||
* A regex_t's re_fns points to one of these.
|
* A regex_t's re_fns points to one of these.
|
||||||
*/
|
*/
|
||||||
struct fns
|
struct fns {
|
||||||
{
|
VOID FUNCPTR(free, (regex_t *));
|
||||||
void FUNCPTR(free, (regex_t *));
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -405,10 +402,9 @@ struct fns
|
|||||||
/*
|
/*
|
||||||
* the insides of a regex_t, hidden behind a void *
|
* the insides of a regex_t, hidden behind a void *
|
||||||
*/
|
*/
|
||||||
struct guts
|
struct guts {
|
||||||
{
|
|
||||||
int magic;
|
int magic;
|
||||||
#define GUTSMAGIC 0xfed9
|
# define GUTSMAGIC 0xfed9
|
||||||
int cflags; /* copy of compile flags */
|
int cflags; /* copy of compile flags */
|
||||||
long info; /* copy of re_info */
|
long info; /* copy of re_info */
|
||||||
size_t nsub; /* copy of re_nsub */
|
size_t nsub; /* copy of re_nsub */
|
||||||
@@ -416,7 +412,7 @@ struct guts
|
|||||||
struct cnfa search; /* for fast preliminary search */
|
struct cnfa search; /* for fast preliminary search */
|
||||||
int ntree;
|
int ntree;
|
||||||
struct colormap cmap;
|
struct colormap cmap;
|
||||||
int FUNCPTR(compare, (const chr *, const chr *, size_t));
|
int FUNCPTR(compare, (CONST chr *, CONST chr *, size_t));
|
||||||
struct subre *lacons; /* lookahead-constraint vector */
|
struct subre *lacons; /* lookahead-constraint vector */
|
||||||
int nlacons; /* size of lacons */
|
int nlacons; /* size of lacons */
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user