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
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $Header$
|
||||
*
|
||||
*
|
||||
* Note that there are some incestuous relationships between this code and
|
||||
@@ -43,11 +42,13 @@
|
||||
|
||||
|
||||
/*
|
||||
* initcm - set up new colormap
|
||||
- initcm - set up new colormap
|
||||
^ static VOID initcm(struct vars *, struct colormap *);
|
||||
*/
|
||||
static void
|
||||
initcm(struct vars * v,
|
||||
struct colormap * cm)
|
||||
static VOID
|
||||
initcm(v, cm)
|
||||
struct vars *v;
|
||||
struct colormap *cm;
|
||||
{
|
||||
int i;
|
||||
int j;
|
||||
@@ -70,8 +71,7 @@ initcm(struct vars * v,
|
||||
cd->nchrs = CHR_MAX - CHR_MIN + 1;
|
||||
|
||||
/* upper levels of tree */
|
||||
for (t = &cm->tree[0], j = NBYTS - 1; j > 0; t = nextt, j--)
|
||||
{
|
||||
for (t = &cm->tree[0], j = NBYTS-1; j > 0; t = nextt, j--) {
|
||||
nextt = t + 1;
|
||||
for (i = BYTTAB-1; i >= 0; i--)
|
||||
t->tptr[i] = nextt;
|
||||
@@ -84,10 +84,12 @@ initcm(struct vars * v,
|
||||
}
|
||||
|
||||
/*
|
||||
* freecm - free dynamically-allocated things in a colormap
|
||||
- freecm - free dynamically-allocated things in a colormap
|
||||
^ static VOID freecm(struct colormap *);
|
||||
*/
|
||||
static void
|
||||
freecm(struct colormap * cm)
|
||||
static VOID
|
||||
freecm(cm)
|
||||
struct colormap *cm;
|
||||
{
|
||||
size_t i;
|
||||
union tree *cb;
|
||||
@@ -96,8 +98,7 @@ freecm(struct colormap * cm)
|
||||
if (NBYTS > 1)
|
||||
cmtreefree(cm, cm->tree, 0);
|
||||
for (i = 1; i <= cm->max; i++) /* skip WHITE */
|
||||
if (!UNUSEDCOLOR(&cm->cd[i]))
|
||||
{
|
||||
if (!UNUSEDCOLOR(&cm->cd[i])) {
|
||||
cb = cm->cd[i].block;
|
||||
if (cb != NULL)
|
||||
FREE(cb);
|
||||
@@ -107,12 +108,14 @@ freecm(struct colormap * cm)
|
||||
}
|
||||
|
||||
/*
|
||||
* cmtreefree - free a non-terminal part of a colormap tree
|
||||
- cmtreefree - free a non-terminal part of a colormap tree
|
||||
^ static VOID cmtreefree(struct colormap *, union tree *, int);
|
||||
*/
|
||||
static void
|
||||
cmtreefree(struct colormap * cm,
|
||||
union tree * tree,
|
||||
int level) /* level number (top == 0) of this block */
|
||||
static VOID
|
||||
cmtreefree(cm, tree, level)
|
||||
struct colormap *cm;
|
||||
union tree *tree;
|
||||
int level; /* level number (top == 0) of this block */
|
||||
{
|
||||
int i;
|
||||
union tree *t;
|
||||
@@ -120,19 +123,14 @@ cmtreefree(struct colormap * cm,
|
||||
union tree *cb;
|
||||
|
||||
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];
|
||||
assert(t != NULL);
|
||||
if (t != fillt)
|
||||
{
|
||||
if (level < NBYTS - 2)
|
||||
{ /* more pointer blocks below */
|
||||
if (t != fillt) {
|
||||
if (level < NBYTS-2) { /* more pointer blocks below */
|
||||
cmtreefree(cm, t, level+1);
|
||||
FREE(t);
|
||||
}
|
||||
else
|
||||
{ /* color block below */
|
||||
} else { /* color block below */
|
||||
cb = cm->cd[t->tcolor[0]].block;
|
||||
if (t != cb) /* not a solid block */
|
||||
FREE(t);
|
||||
@@ -142,12 +140,14 @@ cmtreefree(struct colormap * cm,
|
||||
}
|
||||
|
||||
/*
|
||||
* setcolor - set the color of a character in a colormap
|
||||
- setcolor - set the color of a character in a colormap
|
||||
^ static color setcolor(struct colormap *, pchr, pcolor);
|
||||
*/
|
||||
static color /* previous color */
|
||||
setcolor(struct colormap * cm,
|
||||
chr c,
|
||||
pcolor co)
|
||||
setcolor(cm, c, co)
|
||||
struct colormap *cm;
|
||||
pchr c;
|
||||
pcolor co;
|
||||
{
|
||||
uchr uc = c;
|
||||
int shift;
|
||||
@@ -167,8 +167,7 @@ setcolor(struct colormap * cm,
|
||||
|
||||
t = cm->tree;
|
||||
for (level = 0, shift = BYTBITS * (NBYTS - 1); shift > 0;
|
||||
level++, shift -= BYTBITS)
|
||||
{
|
||||
level++, shift -= BYTBITS) {
|
||||
b = (uc >> shift) & BYTMASK;
|
||||
lastt = t;
|
||||
t = lastt->tptr[b];
|
||||
@@ -176,12 +175,10 @@ setcolor(struct colormap * cm,
|
||||
fillt = &cm->tree[level+1];
|
||||
bottom = (shift <= BYTBITS) ? 1 : 0;
|
||||
cb = (bottom) ? cm->cd[t->tcolor[0]].block : fillt;
|
||||
if (t == fillt || t == cb)
|
||||
{ /* must allocate a new block */
|
||||
if (t == fillt || t == cb) { /* must allocate a new block */
|
||||
newt = (union tree *)MALLOC((bottom) ?
|
||||
sizeof(struct colors) : sizeof(struct ptrs));
|
||||
if (newt == NULL)
|
||||
{
|
||||
if (newt == NULL) {
|
||||
CERR(REG_ESPACE);
|
||||
return COLORLESS;
|
||||
}
|
||||
@@ -203,10 +200,12 @@ setcolor(struct colormap * cm,
|
||||
}
|
||||
|
||||
/*
|
||||
* maxcolor - report largest color number in use
|
||||
- maxcolor - report largest color number in use
|
||||
^ static color maxcolor(struct colormap *);
|
||||
*/
|
||||
static color
|
||||
maxcolor(struct colormap * cm)
|
||||
maxcolor(cm)
|
||||
struct colormap *cm;
|
||||
{
|
||||
if (CISERR())
|
||||
return COLORLESS;
|
||||
@@ -215,11 +214,13 @@ maxcolor(struct colormap * cm)
|
||||
}
|
||||
|
||||
/*
|
||||
* newcolor - find a new color (must be subject of setcolor at once)
|
||||
- newcolor - find a new color (must be subject of setcolor at once)
|
||||
* Beware: may relocate the colordescs.
|
||||
^ static color newcolor(struct colormap *);
|
||||
*/
|
||||
static color /* COLORLESS for error */
|
||||
newcolor(struct colormap * cm)
|
||||
newcolor(cm)
|
||||
struct colormap *cm;
|
||||
{
|
||||
struct colordesc *cd;
|
||||
struct colordesc *new;
|
||||
@@ -228,37 +229,29 @@ newcolor(struct colormap * cm)
|
||||
if (CISERR())
|
||||
return COLORLESS;
|
||||
|
||||
if (cm->free != 0)
|
||||
{
|
||||
if (cm->free != 0) {
|
||||
assert(cm->free > 0);
|
||||
assert((size_t)cm->free < cm->ncds);
|
||||
cd = &cm->cd[cm->free];
|
||||
assert(UNUSEDCOLOR(cd));
|
||||
assert(cd->arcs == NULL);
|
||||
cm->free = cd->sub;
|
||||
}
|
||||
else if (cm->max < cm->ncds - 1)
|
||||
{
|
||||
} else if (cm->max < cm->ncds - 1) {
|
||||
cm->max++;
|
||||
cd = &cm->cd[cm->max];
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
/* oops, must allocate more */
|
||||
n = cm->ncds * 2;
|
||||
if (cm->cd == cm->cdspace)
|
||||
{
|
||||
if (cm->cd == cm->cdspace) {
|
||||
new = (struct colordesc *)MALLOC(n *
|
||||
sizeof(struct colordesc));
|
||||
if (new != NULL)
|
||||
memcpy(VS(new), VS(cm->cdspace), cm->ncds *
|
||||
sizeof(struct colordesc));
|
||||
}
|
||||
else
|
||||
} else
|
||||
new = (struct colordesc *)REALLOC(cm->cd,
|
||||
n * sizeof(struct colordesc));
|
||||
if (new == NULL)
|
||||
{
|
||||
if (new == NULL) {
|
||||
CERR(REG_ESPACE);
|
||||
return COLORLESS;
|
||||
}
|
||||
@@ -279,15 +272,16 @@ newcolor(struct colormap * cm)
|
||||
}
|
||||
|
||||
/*
|
||||
* freecolor - free a color (must have no arcs or subcolor)
|
||||
- freecolor - free a color (must have no arcs or subcolor)
|
||||
^ static VOID freecolor(struct colormap *, pcolor);
|
||||
*/
|
||||
static void
|
||||
freecolor(struct colormap * cm,
|
||||
pcolor co)
|
||||
static VOID
|
||||
freecolor(cm, co)
|
||||
struct colormap *cm;
|
||||
pcolor co;
|
||||
{
|
||||
struct colordesc *cd = &cm->cd[co];
|
||||
color pco,
|
||||
nco; /* for freelist scan */
|
||||
color pco, nco; /* for freelist scan */
|
||||
|
||||
assert(co >= 0);
|
||||
if (co == WHITE)
|
||||
@@ -297,51 +291,45 @@ freecolor(struct colormap * cm,
|
||||
assert(cd->sub == NOSUB);
|
||||
assert(cd->nchrs == 0);
|
||||
cd->flags = FREECOL;
|
||||
if (cd->block != NULL)
|
||||
{
|
||||
if (cd->block != NULL) {
|
||||
FREE(cd->block);
|
||||
cd->block = NULL; /* just paranoia */
|
||||
}
|
||||
|
||||
if ((size_t) co == cm->max)
|
||||
{
|
||||
if ((size_t)co == cm->max) {
|
||||
while (cm->max > WHITE && UNUSEDCOLOR(&cm->cd[cm->max]))
|
||||
cm->max--;
|
||||
assert(cm->free >= 0);
|
||||
while ((size_t)cm->free > cm->max)
|
||||
cm->free = cm->cd[cm->free].sub;
|
||||
if (cm->free > 0)
|
||||
{
|
||||
if (cm->free > 0) {
|
||||
assert(cm->free < cm->max);
|
||||
pco = cm->free;
|
||||
nco = cm->cd[pco].sub;
|
||||
while (nco > 0)
|
||||
if ((size_t) nco > cm->max)
|
||||
{
|
||||
if ((size_t)nco > cm->max) {
|
||||
/* take this one out of freelist */
|
||||
nco = cm->cd[nco].sub;
|
||||
cm->cd[pco].sub = nco;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
assert(nco < cm->max);
|
||||
pco = nco;
|
||||
nco = cm->cd[pco].sub;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
cd->sub = cm->free;
|
||||
cm->free = (color)(cd - cm->cd);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* pseudocolor - allocate a false color, to be managed by other means
|
||||
- pseudocolor - allocate a false color, to be managed by other means
|
||||
^ static color pseudocolor(struct colormap *);
|
||||
*/
|
||||
static color
|
||||
pseudocolor(struct colormap * cm)
|
||||
pseudocolor(cm)
|
||||
struct colormap *cm;
|
||||
{
|
||||
color co;
|
||||
|
||||
@@ -354,10 +342,13 @@ pseudocolor(struct colormap * cm)
|
||||
}
|
||||
|
||||
/*
|
||||
* subcolor - allocate a new subcolor (if necessary) to this chr
|
||||
- subcolor - allocate a new subcolor (if necessary) to this chr
|
||||
^ static color subcolor(struct colormap *, pchr c);
|
||||
*/
|
||||
static color
|
||||
subcolor(struct colormap * cm, chr c)
|
||||
subcolor(cm, c)
|
||||
struct colormap *cm;
|
||||
pchr c;
|
||||
{
|
||||
color co; /* current color of c */
|
||||
color sco; /* new subcolor */
|
||||
@@ -377,22 +368,22 @@ subcolor(struct colormap * cm, chr c)
|
||||
}
|
||||
|
||||
/*
|
||||
* newsub - allocate a new subcolor (if necessary) for a color
|
||||
- newsub - allocate a new subcolor (if necessary) for a color
|
||||
^ static color newsub(struct colormap *, pcolor);
|
||||
*/
|
||||
static color
|
||||
newsub(struct colormap * cm,
|
||||
pcolor co)
|
||||
newsub(cm, co)
|
||||
struct colormap *cm;
|
||||
pcolor co;
|
||||
{
|
||||
color sco; /* new subcolor */
|
||||
|
||||
sco = cm->cd[co].sub;
|
||||
if (sco == NOSUB)
|
||||
{ /* color has no open subcolor */
|
||||
if (sco == NOSUB) { /* color has no open subcolor */
|
||||
if (cm->cd[co].nchrs == 1) /* optimization */
|
||||
return co;
|
||||
sco = newcolor(cm); /* must create subcolor */
|
||||
if (sco == COLORLESS)
|
||||
{
|
||||
if (sco == COLORLESS) {
|
||||
assert(CISERR());
|
||||
return COLORLESS;
|
||||
}
|
||||
@@ -405,14 +396,17 @@ newsub(struct colormap * cm,
|
||||
}
|
||||
|
||||
/*
|
||||
* subrange - allocate new subcolors to this range of chrs, fill in arcs
|
||||
- subrange - allocate new subcolors to this range of chrs, fill in arcs
|
||||
^ static VOID subrange(struct vars *, pchr, pchr, struct state *,
|
||||
^ struct state *);
|
||||
*/
|
||||
static void
|
||||
subrange(struct vars * v,
|
||||
chr from,
|
||||
chr to,
|
||||
struct state * lp,
|
||||
struct state * rp)
|
||||
static VOID
|
||||
subrange(v, from, to, lp, rp)
|
||||
struct vars *v;
|
||||
pchr from;
|
||||
pchr to;
|
||||
struct state *lp;
|
||||
struct state *rp;
|
||||
{
|
||||
uchr uf;
|
||||
int i;
|
||||
@@ -437,13 +431,15 @@ subrange(struct vars * v,
|
||||
}
|
||||
|
||||
/*
|
||||
* subblock - allocate new subcolors for one tree block of chrs, fill in arcs
|
||||
- subblock - allocate new subcolors for one tree block of chrs, fill in arcs
|
||||
^ static VOID subblock(struct vars *, pchr, struct state *, struct state *);
|
||||
*/
|
||||
static void
|
||||
subblock(struct vars * v,
|
||||
chr start, /* first of BYTTAB chrs */
|
||||
struct state * lp,
|
||||
struct state * rp)
|
||||
static VOID
|
||||
subblock(v, start, lp, rp)
|
||||
struct vars *v;
|
||||
pchr start; /* first of BYTTAB chrs */
|
||||
struct state *lp;
|
||||
struct state *rp;
|
||||
{
|
||||
uchr uc = start;
|
||||
struct colormap *cm = v->cm;
|
||||
@@ -466,18 +462,15 @@ subblock(struct vars * v,
|
||||
t = cm->tree;
|
||||
fillt = NULL;
|
||||
for (level = 0, shift = BYTBITS * (NBYTS - 1); shift > 0;
|
||||
level++, shift -= BYTBITS)
|
||||
{
|
||||
level++, shift -= BYTBITS) {
|
||||
b = (uc >> shift) & BYTMASK;
|
||||
lastt = t;
|
||||
t = lastt->tptr[b];
|
||||
assert(t != NULL);
|
||||
fillt = &cm->tree[level+1];
|
||||
if (t == fillt && shift > BYTBITS)
|
||||
{ /* need new ptr block */
|
||||
if (t == fillt && shift > BYTBITS) { /* need new ptr block */
|
||||
t = (union tree *)MALLOC(sizeof(struct ptrs));
|
||||
if (t == NULL)
|
||||
{
|
||||
if (t == NULL) {
|
||||
CERR(REG_ESPACE);
|
||||
return;
|
||||
}
|
||||
@@ -490,16 +483,13 @@ subblock(struct vars * v,
|
||||
/* special cases: fill block or solid block */
|
||||
co = t->tcolor[0];
|
||||
cb = cm->cd[co].block;
|
||||
if (t == fillt || t == cb)
|
||||
{
|
||||
if (t == fillt || t == cb) {
|
||||
/* either way, we want a subcolor solid block */
|
||||
sco = newsub(cm, co);
|
||||
t = cm->cd[sco].block;
|
||||
if (t == NULL)
|
||||
{ /* must set it up */
|
||||
if (t == NULL) { /* must set it up */
|
||||
t = (union tree *)MALLOC(sizeof(struct colors));
|
||||
if (t == NULL)
|
||||
{
|
||||
if (t == NULL) {
|
||||
CERR(REG_ESPACE);
|
||||
return;
|
||||
}
|
||||
@@ -517,14 +507,12 @@ subblock(struct vars * v,
|
||||
|
||||
/* general case, a mixed block to be altered */
|
||||
i = 0;
|
||||
while (i < BYTTAB)
|
||||
{
|
||||
while (i < BYTTAB) {
|
||||
co = t->tcolor[i];
|
||||
sco = newsub(cm, co);
|
||||
newarc(v->nfa, PLAIN, sco, lp, rp);
|
||||
previ = i;
|
||||
do
|
||||
{
|
||||
do {
|
||||
t->tcolor[i++] = sco;
|
||||
} while (i < BYTTAB && t->tcolor[i] == co);
|
||||
ndone = i - previ;
|
||||
@@ -534,11 +522,13 @@ subblock(struct vars * v,
|
||||
}
|
||||
|
||||
/*
|
||||
* okcolors - promote subcolors to full colors
|
||||
- okcolors - promote subcolors to full colors
|
||||
^ static VOID okcolors(struct nfa *, struct colormap *);
|
||||
*/
|
||||
static void
|
||||
okcolors(struct nfa * nfa,
|
||||
struct colormap * cm)
|
||||
static VOID
|
||||
okcolors(nfa, cm)
|
||||
struct nfa *nfa;
|
||||
struct colormap *cm;
|
||||
{
|
||||
struct colordesc *cd;
|
||||
struct colordesc *end = CDEND(cm);
|
||||
@@ -547,27 +537,20 @@ okcolors(struct nfa * nfa,
|
||||
color co;
|
||||
color sco;
|
||||
|
||||
for (cd = cm->cd, co = 0; cd < end; cd++, co++)
|
||||
{
|
||||
for (cd = cm->cd, co = 0; cd < end; cd++, co++) {
|
||||
sco = cd->sub;
|
||||
if (UNUSEDCOLOR(cd) || sco == NOSUB)
|
||||
{
|
||||
if (UNUSEDCOLOR(cd) || sco == NOSUB) {
|
||||
/* has no subcolor, no further action */
|
||||
}
|
||||
else if (sco == co)
|
||||
{
|
||||
} else if (sco == co) {
|
||||
/* is subcolor, let parent deal with it */
|
||||
}
|
||||
else if (cd->nchrs == 0)
|
||||
{
|
||||
} else if (cd->nchrs == 0) {
|
||||
/* parent empty, its arcs change color to subcolor */
|
||||
cd->sub = NOSUB;
|
||||
scd = &cm->cd[sco];
|
||||
assert(scd->nchrs > 0);
|
||||
assert(scd->sub == sco);
|
||||
scd->sub = NOSUB;
|
||||
while ((a = cd->arcs) != NULL)
|
||||
{
|
||||
while ((a = cd->arcs) != NULL) {
|
||||
assert(a->co == co);
|
||||
/* uncolorchain(cm, a); */
|
||||
cd->arcs = a->colorchain;
|
||||
@@ -577,17 +560,14 @@ okcolors(struct nfa * nfa,
|
||||
scd->arcs = a;
|
||||
}
|
||||
freecolor(cm, co);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
/* parent's arcs must gain parallel subcolor arcs */
|
||||
cd->sub = NOSUB;
|
||||
scd = &cm->cd[sco];
|
||||
assert(scd->nchrs > 0);
|
||||
assert(scd->sub == sco);
|
||||
scd->sub = NOSUB;
|
||||
for (a = cd->arcs; a != NULL; a = a->colorchain)
|
||||
{
|
||||
for (a = cd->arcs; a != NULL; a = a->colorchain) {
|
||||
assert(a->co == co);
|
||||
newarc(nfa, a->type, sco, a->from, a->to);
|
||||
}
|
||||
@@ -596,11 +576,13 @@ okcolors(struct nfa * nfa,
|
||||
}
|
||||
|
||||
/*
|
||||
* colorchain - add this arc to the color chain of its color
|
||||
- colorchain - add this arc to the color chain of its color
|
||||
^ static VOID colorchain(struct colormap *, struct arc *);
|
||||
*/
|
||||
static void
|
||||
colorchain(struct colormap * cm,
|
||||
struct arc * a)
|
||||
static VOID
|
||||
colorchain(cm, a)
|
||||
struct colormap *cm;
|
||||
struct arc *a;
|
||||
{
|
||||
struct colordesc *cd = &cm->cd[a->co];
|
||||
|
||||
@@ -609,11 +591,13 @@ colorchain(struct colormap * cm,
|
||||
}
|
||||
|
||||
/*
|
||||
* uncolorchain - delete this arc from the color chain of its color
|
||||
- uncolorchain - delete this arc from the color chain of its color
|
||||
^ static VOID uncolorchain(struct colormap *, struct arc *);
|
||||
*/
|
||||
static void
|
||||
uncolorchain(struct colormap * cm,
|
||||
struct arc * a)
|
||||
static VOID
|
||||
uncolorchain(cm, a)
|
||||
struct colormap *cm;
|
||||
struct arc *a;
|
||||
{
|
||||
struct colordesc *cd = &cm->cd[a->co];
|
||||
struct arc *aa;
|
||||
@@ -621,8 +605,7 @@ uncolorchain(struct colormap * cm,
|
||||
aa = cd->arcs;
|
||||
if (aa == a) /* easy case */
|
||||
cd->arcs = a->colorchain;
|
||||
else
|
||||
{
|
||||
else {
|
||||
for (; aa != NULL && aa->colorchain != a; aa = aa->colorchain)
|
||||
continue;
|
||||
assert(aa != NULL);
|
||||
@@ -632,11 +615,13 @@ uncolorchain(struct colormap * cm,
|
||||
}
|
||||
|
||||
/*
|
||||
* singleton - is this character in its own color?
|
||||
- singleton - is this character in its own color?
|
||||
^ static int singleton(struct colormap *, pchr c);
|
||||
*/
|
||||
static int /* predicate */
|
||||
singleton(struct colormap * cm,
|
||||
chr c)
|
||||
singleton(cm, c)
|
||||
struct colormap *cm;
|
||||
pchr c;
|
||||
{
|
||||
color co; /* color of c */
|
||||
|
||||
@@ -647,15 +632,18 @@ singleton(struct colormap * cm,
|
||||
}
|
||||
|
||||
/*
|
||||
* rainbow - add arcs of all full colors (but one) between specified states
|
||||
- rainbow - add arcs of all full colors (but one) between specified states
|
||||
^ static VOID rainbow(struct nfa *, struct colormap *, int, pcolor,
|
||||
^ struct state *, struct state *);
|
||||
*/
|
||||
static void
|
||||
rainbow(struct nfa * nfa,
|
||||
struct colormap * cm,
|
||||
int type,
|
||||
pcolor but, /* COLORLESS if no exceptions */
|
||||
struct state * from,
|
||||
struct state * to)
|
||||
static VOID
|
||||
rainbow(nfa, cm, type, but, from, to)
|
||||
struct nfa *nfa;
|
||||
struct colormap *cm;
|
||||
int type;
|
||||
pcolor but; /* COLORLESS if no exceptions */
|
||||
struct state *from;
|
||||
struct state *to;
|
||||
{
|
||||
struct colordesc *cd;
|
||||
struct colordesc *end = CDEND(cm);
|
||||
@@ -668,18 +656,19 @@ rainbow(struct nfa * nfa,
|
||||
}
|
||||
|
||||
/*
|
||||
* colorcomplement - add arcs of complementary colors
|
||||
*
|
||||
- colorcomplement - add arcs of complementary colors
|
||||
* The calling sequence ought to be reconciled with cloneouts().
|
||||
^ static VOID colorcomplement(struct nfa *, struct colormap *, int,
|
||||
^ struct state *, struct state *, struct state *);
|
||||
*/
|
||||
static void
|
||||
colorcomplement(struct nfa * nfa,
|
||||
struct colormap * cm,
|
||||
int type,
|
||||
struct state * of, /* complements of this guy's PLAIN
|
||||
* outarcs */
|
||||
struct state * from,
|
||||
struct state * to)
|
||||
static VOID
|
||||
colorcomplement(nfa, cm, type, of, from, to)
|
||||
struct nfa *nfa;
|
||||
struct colormap *cm;
|
||||
int type;
|
||||
struct state *of; /* complements of this guy's PLAIN outarcs */
|
||||
struct state *from;
|
||||
struct state *to;
|
||||
{
|
||||
struct colordesc *cd;
|
||||
struct colordesc *end = CDEND(cm);
|
||||
@@ -693,14 +682,20 @@ colorcomplement(struct nfa * nfa,
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef REG_DEBUG
|
||||
/*
|
||||
^ #ifdef REG_DEBUG
|
||||
*/
|
||||
|
||||
/*
|
||||
* dumpcolors - debugging output
|
||||
- dumpcolors - debugging output
|
||||
^ static VOID dumpcolors(struct colormap *, FILE *);
|
||||
*/
|
||||
static void
|
||||
dumpcolors(struct colormap * cm,
|
||||
FILE *f)
|
||||
static VOID
|
||||
dumpcolors(cm, f)
|
||||
struct colormap *cm;
|
||||
FILE *f;
|
||||
{
|
||||
struct colordesc *cd;
|
||||
struct colordesc *end;
|
||||
@@ -713,8 +708,7 @@ dumpcolors(struct colormap * cm,
|
||||
fillcheck(cm, cm->tree, 0, f);
|
||||
end = CDEND(cm);
|
||||
for (cd = cm->cd + 1, co = 1; cd < end; cd++, co++) /* skip 0 */
|
||||
if (!UNUSEDCOLOR(cd))
|
||||
{
|
||||
if (!UNUSEDCOLOR(cd)) {
|
||||
assert(cd->nchrs > 0);
|
||||
has = (cd->block != NULL) ? "#" : "";
|
||||
if (cd->flags&PSEUDO)
|
||||
@@ -734,51 +728,51 @@ dumpcolors(struct colormap * cm,
|
||||
}
|
||||
|
||||
/*
|
||||
* fillcheck - check proper filling of a tree
|
||||
- fillcheck - check proper filling of a tree
|
||||
^ static VOID fillcheck(struct colormap *, union tree *, int, FILE *);
|
||||
*/
|
||||
static void
|
||||
fillcheck(struct colormap * cm,
|
||||
union tree * tree,
|
||||
int level, /* level number (top == 0) of this block */
|
||||
FILE *f)
|
||||
static VOID
|
||||
fillcheck(cm, tree, level, f)
|
||||
struct colormap *cm;
|
||||
union tree *tree;
|
||||
int level; /* level number (top == 0) of this block */
|
||||
FILE *f;
|
||||
{
|
||||
int i;
|
||||
union tree *t;
|
||||
union tree *fillt = &cm->tree[level+1];
|
||||
|
||||
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];
|
||||
if (t == NULL)
|
||||
fprintf(f, "NULL found in filled tree!\n");
|
||||
else if (t == fillt)
|
||||
{
|
||||
}
|
||||
{}
|
||||
else if (level < NBYTS-2) /* more pointer blocks below */
|
||||
fillcheck(cm, t, level+1, f);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* dumpchr - print a chr
|
||||
*
|
||||
- dumpchr - print a chr
|
||||
* Kind of char-centric but works well enough for debug use.
|
||||
^ static VOID dumpchr(pchr, FILE *);
|
||||
*/
|
||||
static void
|
||||
dumpchr(chr c,
|
||||
FILE *f)
|
||||
static VOID
|
||||
dumpchr(c, f)
|
||||
pchr c;
|
||||
FILE *f;
|
||||
{
|
||||
#if wxUSE_UNICODE
|
||||
fprintf(f, "Debugging not implemented in unicode mode");
|
||||
#else
|
||||
if (c == '\\')
|
||||
fprintf(f, "\\\\");
|
||||
else if (c > ' ' && c <= '~')
|
||||
putc((char)c, f);
|
||||
else
|
||||
fprintf(f, "\\u%04lx", (long)c);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* REG_DEBUG */
|
||||
/*
|
||||
^ #endif
|
||||
*/
|
||||
#endif /* ifdef REG_DEBUG */
|
||||
|
||||
@@ -28,32 +28,31 @@
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $Header$
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* newcvec - allocate a new cvec
|
||||
- newcvec - allocate a new cvec
|
||||
^ static struct cvec *newcvec(int, int, int);
|
||||
*/
|
||||
static struct cvec *
|
||||
newcvec(int nchrs, /* to hold this many chrs... */
|
||||
int nranges, /* ... and this many ranges... */
|
||||
int nmcces) /* ... and this many MCCEs */
|
||||
newcvec(nchrs, nranges, nmcces)
|
||||
int nchrs; /* to hold this many chrs... */
|
||||
int nranges; /* ... and this many ranges... */
|
||||
int nmcces; /* ... and this many MCCEs */
|
||||
{
|
||||
size_t n;
|
||||
size_t nc;
|
||||
struct cvec *cv;
|
||||
|
||||
nc = (size_t)nchrs + (size_t)nmcces*(MAXMCCE+1) + (size_t)nranges*2;
|
||||
|
||||
n = sizeof(struct cvec) + (size_t)(nmcces-1)*sizeof(chr *)
|
||||
+ nc*sizeof(chr);
|
||||
cv = (struct cvec *)MALLOC(n);
|
||||
if (cv == NULL)
|
||||
if (cv == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
cv->chrspace = nchrs;
|
||||
cv->chrs = (chr *) &cv->mcces[nmcces]; /* chrs just after MCCE
|
||||
* ptrs */
|
||||
cv->chrs = (chr *)&cv->mcces[nmcces]; /* chrs just after MCCE ptrs */
|
||||
cv->mccespace = nmcces;
|
||||
cv->ranges = cv->chrs + nchrs + nmcces*(MAXMCCE+1);
|
||||
cv->rangespace = nranges;
|
||||
@@ -61,11 +60,13 @@ newcvec(int nchrs, /* to hold this many chrs... */
|
||||
}
|
||||
|
||||
/*
|
||||
* clearcvec - clear a possibly-new cvec
|
||||
- clearcvec - clear a possibly-new cvec
|
||||
* Returns pointer as convenience.
|
||||
^ static struct cvec *clearcvec(struct cvec *);
|
||||
*/
|
||||
static struct cvec *
|
||||
clearcvec(struct cvec * cv)
|
||||
clearcvec(cv)
|
||||
struct cvec *cv; /* character vector */
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -75,30 +76,35 @@ clearcvec(struct cvec * cv)
|
||||
cv->nmcces = 0;
|
||||
cv->nmccechrs = 0;
|
||||
cv->nranges = 0;
|
||||
for (i = 0; i < cv->mccespace; i++)
|
||||
for (i = 0; i < cv->mccespace; i++) {
|
||||
cv->mcces[i] = NULL;
|
||||
}
|
||||
|
||||
return cv;
|
||||
}
|
||||
|
||||
/*
|
||||
* addchr - add a chr to a cvec
|
||||
- addchr - add a chr to a cvec
|
||||
^ static VOID addchr(struct cvec *, pchr);
|
||||
*/
|
||||
static void
|
||||
addchr(struct cvec * cv, /* character vector */
|
||||
chr c) /* character to add */
|
||||
static VOID
|
||||
addchr(cv, c)
|
||||
struct cvec *cv; /* character vector */
|
||||
pchr c; /* character to add */
|
||||
{
|
||||
assert(cv->nchrs < cv->chrspace - cv->nmccechrs);
|
||||
cv->chrs[cv->nchrs++] = (chr)c;
|
||||
}
|
||||
|
||||
/*
|
||||
* addrange - add a range to a cvec
|
||||
- addrange - add a range to a cvec
|
||||
^ static VOID addrange(struct cvec *, pchr, pchr);
|
||||
*/
|
||||
static void
|
||||
addrange(struct cvec * cv, /* character vector */
|
||||
chr from, /* first character of range */
|
||||
chr to) /* last character of range */
|
||||
static VOID
|
||||
addrange(cv, from, to)
|
||||
struct cvec *cv; /* character vector */
|
||||
pchr from; /* first character of range */
|
||||
pchr to; /* last character of range */
|
||||
{
|
||||
assert(cv->nranges < cv->rangespace);
|
||||
cv->ranges[cv->nranges*2] = (chr)from;
|
||||
@@ -107,83 +113,96 @@ addrange(struct cvec * cv, /* character vector */
|
||||
}
|
||||
|
||||
/*
|
||||
* addmcce - add an MCCE to a cvec
|
||||
- addmcce - add an MCCE to a cvec
|
||||
^ static VOID addmcce(struct cvec *, chr *, chr *);
|
||||
*/
|
||||
static void
|
||||
addmcce(struct cvec * cv, /* character vector */
|
||||
chr *startp, /* beginning of text */
|
||||
chr *endp) /* just past end of text */
|
||||
static VOID
|
||||
addmcce(cv, startp, endp)
|
||||
struct cvec *cv; /* character vector */
|
||||
chr *startp; /* beginning of text */
|
||||
chr *endp; /* just past end of text */
|
||||
{
|
||||
int len;
|
||||
int i;
|
||||
chr *s;
|
||||
chr *d;
|
||||
|
||||
if (startp == NULL && endp == NULL)
|
||||
if (startp == NULL && endp == NULL) {
|
||||
return;
|
||||
}
|
||||
len = endp - startp;
|
||||
assert(len > 0);
|
||||
assert(cv->nchrs + len < cv->chrspace - cv->nmccechrs);
|
||||
assert(cv->nmcces < cv->mccespace);
|
||||
d = &cv->chrs[cv->chrspace - cv->nmccechrs - len - 1];
|
||||
cv->mcces[cv->nmcces++] = d;
|
||||
for (s = startp, i = len; i > 0; s++, i--)
|
||||
for (s = startp, i = len; i > 0; s++, i--) {
|
||||
*d++ = *s;
|
||||
}
|
||||
*d++ = 0; /* endmarker */
|
||||
assert(d == &cv->chrs[cv->chrspace - cv->nmccechrs]);
|
||||
cv->nmccechrs += len + 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* haschr - does a cvec contain this chr?
|
||||
- haschr - does a cvec contain this chr?
|
||||
^ static int haschr(struct cvec *, pchr);
|
||||
*/
|
||||
static int /* predicate */
|
||||
haschr(struct cvec * cv, /* character vector */
|
||||
chr c) /* character to test for */
|
||||
haschr(cv, c)
|
||||
struct cvec *cv; /* character vector */
|
||||
pchr c; /* character to test for */
|
||||
{
|
||||
int i;
|
||||
chr *p;
|
||||
|
||||
for (p = cv->chrs, i = cv->nchrs; i > 0; p++, i--)
|
||||
{
|
||||
if (*p == c)
|
||||
for (p = cv->chrs, i = cv->nchrs; i > 0; p++, i--) {
|
||||
if (*p == c) {
|
||||
return 1;
|
||||
}
|
||||
for (p = cv->ranges, i = cv->nranges; i > 0; p += 2, i--)
|
||||
{
|
||||
if ((*p <= c) && (c <= *(p + 1)))
|
||||
}
|
||||
for (p = cv->ranges, i = cv->nranges; i > 0; p += 2, i--) {
|
||||
if ((*p <= c) && (c <= *(p+1))) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* getcvec - get a cvec, remembering it as v->cv
|
||||
- getcvec - get a cvec, remembering it as v->cv
|
||||
^ static struct cvec *getcvec(struct vars *, int, int, int);
|
||||
*/
|
||||
static struct cvec *
|
||||
getcvec(struct vars * v, /* context */
|
||||
int nchrs, /* to hold this many chrs... */
|
||||
int nranges, /* ... and this many ranges... */
|
||||
int nmcces) /* ... and this many MCCEs */
|
||||
getcvec(v, nchrs, nranges, nmcces)
|
||||
struct vars *v; /* context */
|
||||
int nchrs; /* to hold this many chrs... */
|
||||
int nranges; /* ... and this many ranges... */
|
||||
int nmcces; /* ... and this many MCCEs */
|
||||
{
|
||||
if (v->cv != NULL && nchrs <= v->cv->chrspace &&
|
||||
nranges <= v->cv->rangespace && nmcces <= v->cv->mccespace)
|
||||
nranges <= v->cv->rangespace && nmcces <= v->cv->mccespace) {
|
||||
return clearcvec(v->cv);
|
||||
}
|
||||
|
||||
if (v->cv != NULL)
|
||||
if (v->cv != NULL) {
|
||||
freecvec(v->cv);
|
||||
}
|
||||
v->cv = newcvec(nchrs, nranges, nmcces);
|
||||
if (v->cv == NULL)
|
||||
if (v->cv == NULL) {
|
||||
ERR(REG_ESPACE);
|
||||
}
|
||||
|
||||
return v->cv;
|
||||
}
|
||||
|
||||
/*
|
||||
* freecvec - free a cvec
|
||||
- freecvec - free a cvec
|
||||
^ static VOID freecvec(struct cvec *);
|
||||
*/
|
||||
static void
|
||||
freecvec(struct cvec * cv)
|
||||
static VOID
|
||||
freecvec(cv)
|
||||
struct cvec *cv; /* character vector */
|
||||
{
|
||||
FREE(cv);
|
||||
}
|
||||
|
||||
@@ -28,8 +28,6 @@
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $Header$
|
||||
*
|
||||
*/
|
||||
|
||||
/* scanning macros (know about v) */
|
||||
@@ -64,26 +62,23 @@
|
||||
#define ENDOF(array) ((array) + sizeof(array)/sizeof(chr))
|
||||
|
||||
/*
|
||||
* lexstart - set up lexical stuff, scan leading options
|
||||
- lexstart - set up lexical stuff, scan leading options
|
||||
^ static VOID lexstart(struct vars *);
|
||||
*/
|
||||
static void
|
||||
lexstart(struct vars * v)
|
||||
static VOID
|
||||
lexstart(v)
|
||||
struct vars *v;
|
||||
{
|
||||
prefixes(v); /* may turn on new type bits etc. */
|
||||
NOERR();
|
||||
|
||||
if (v->cflags & REG_QUOTE)
|
||||
{
|
||||
if (v->cflags®_QUOTE) {
|
||||
assert(!(v->cflags&(REG_ADVANCED|REG_EXPANDED|REG_NEWLINE)));
|
||||
INTOCON(L_Q);
|
||||
}
|
||||
else if (v->cflags & REG_EXTENDED)
|
||||
{
|
||||
} else if (v->cflags®_EXTENDED) {
|
||||
assert(!(v->cflags®_QUOTE));
|
||||
INTOCON(L_ERE);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
assert(!(v->cflags&(REG_QUOTE|REG_ADVF)));
|
||||
INTOCON(L_BRE);
|
||||
}
|
||||
@@ -93,10 +88,12 @@ lexstart(struct vars * v)
|
||||
}
|
||||
|
||||
/*
|
||||
* prefixes - implement various special prefixes
|
||||
- prefixes - implement various special prefixes
|
||||
^ static VOID prefixes(struct vars *);
|
||||
*/
|
||||
static void
|
||||
prefixes(struct vars * v)
|
||||
static VOID
|
||||
prefixes(v)
|
||||
struct vars *v;
|
||||
{
|
||||
/* literal string doesn't get any of this stuff */
|
||||
if (v->cflags®_QUOTE)
|
||||
@@ -104,8 +101,7 @@ prefixes(struct vars * v)
|
||||
|
||||
/* initial "***" gets special things */
|
||||
if (HAVE(4) && NEXT3('*', '*', '*'))
|
||||
switch (*(v->now + 3))
|
||||
{
|
||||
switch (*(v->now + 3)) {
|
||||
case CHR('?'): /* "***?" error, msg shows version */
|
||||
ERR(REG_BADPAT);
|
||||
return; /* proceed no further */
|
||||
@@ -133,13 +129,11 @@ prefixes(struct vars * v)
|
||||
return;
|
||||
|
||||
/* embedded options (AREs only) */
|
||||
if (HAVE(3) && NEXT2('(', '?') && iscalpha(*(v->now + 2)))
|
||||
{
|
||||
if (HAVE(3) && NEXT2('(', '?') && iscalpha(*(v->now + 2))) {
|
||||
NOTE(REG_UNONPOSIX);
|
||||
v->now += 2;
|
||||
for (; !ATEOS() && iscalpha(*v->now); v->now++)
|
||||
switch (*v->now)
|
||||
{
|
||||
switch (*v->now) {
|
||||
case CHR('b'): /* BREs (but why???) */
|
||||
v->cflags &= ~(REG_ADVANCED|REG_QUOTE);
|
||||
break;
|
||||
@@ -182,8 +176,7 @@ prefixes(struct vars * v)
|
||||
ERR(REG_BADOPT);
|
||||
return;
|
||||
}
|
||||
if (!NEXT1(')'))
|
||||
{
|
||||
if (!NEXT1(')')) {
|
||||
ERR(REG_BADOPT);
|
||||
return;
|
||||
}
|
||||
@@ -194,15 +187,16 @@ prefixes(struct vars * v)
|
||||
}
|
||||
|
||||
/*
|
||||
* lexnest - "call a subroutine", interpolating string at the lexical level
|
||||
*
|
||||
- lexnest - "call a subroutine", interpolating string at the lexical level
|
||||
* Note, this is not a very general facility. There are a number of
|
||||
* implicit assumptions about what sorts of strings can be subroutines.
|
||||
^ static VOID lexnest(struct vars *, chr *, chr *);
|
||||
*/
|
||||
static void
|
||||
lexnest(struct vars * v,
|
||||
chr *beginp, /* start of interpolation */
|
||||
chr *endp) /* one past end of interpolation */
|
||||
static VOID
|
||||
lexnest(v, beginp, endp)
|
||||
struct vars *v;
|
||||
chr *beginp; /* start of interpolation */
|
||||
chr *endp; /* one past end of interpolation */
|
||||
{
|
||||
assert(v->savenow == NULL); /* only one level of nesting */
|
||||
v->savenow = v->now;
|
||||
@@ -261,20 +255,24 @@ static chr brbackw[] = { /* \w within brackets */
|
||||
};
|
||||
|
||||
/*
|
||||
* lexword - interpolate a bracket expression for word characters
|
||||
- lexword - interpolate a bracket expression for word characters
|
||||
* Possibly ought to inquire whether there is a "word" character class.
|
||||
^ static VOID lexword(struct vars *);
|
||||
*/
|
||||
static void
|
||||
lexword(struct vars * v)
|
||||
static VOID
|
||||
lexword(v)
|
||||
struct vars *v;
|
||||
{
|
||||
lexnest(v, backw, ENDOF(backw));
|
||||
}
|
||||
|
||||
/*
|
||||
* next - get next token
|
||||
- next - get next token
|
||||
^ static int next(struct vars *);
|
||||
*/
|
||||
static int /* 1 normal, 0 failure */
|
||||
next(struct vars * v)
|
||||
next(v)
|
||||
struct vars *v;
|
||||
{
|
||||
chr c;
|
||||
|
||||
@@ -286,15 +284,13 @@ next(struct vars * v)
|
||||
v->lasttype = v->nexttype;
|
||||
|
||||
/* REG_BOSONLY */
|
||||
if (v->nexttype == EMPTY && (v->cflags & REG_BOSONLY))
|
||||
{
|
||||
if (v->nexttype == EMPTY && (v->cflags®_BOSONLY)) {
|
||||
/* at start of a REG_BOSONLY RE */
|
||||
RETV(SBEGIN, 0); /* same as \A */
|
||||
}
|
||||
|
||||
/* if we're nested and we've hit end, return to outer level */
|
||||
if (v->savenow != NULL && ATEOS())
|
||||
{
|
||||
if (v->savenow != NULL && ATEOS()) {
|
||||
v->now = v->savenow;
|
||||
v->stop = v->savestop;
|
||||
v->savenow = v->savestop = NULL;
|
||||
@@ -302,8 +298,7 @@ next(struct vars * v)
|
||||
|
||||
/* skip white space etc. if appropriate (not in literal or []) */
|
||||
if (v->cflags®_EXPANDED)
|
||||
switch (v->lexcon)
|
||||
{
|
||||
switch (v->lexcon) {
|
||||
case L_ERE:
|
||||
case L_BRE:
|
||||
case L_EBND:
|
||||
@@ -313,10 +308,8 @@ next(struct vars * v)
|
||||
}
|
||||
|
||||
/* handle EOS, depending on context */
|
||||
if (ATEOS())
|
||||
{
|
||||
switch (v->lexcon)
|
||||
{
|
||||
if (ATEOS()) {
|
||||
switch (v->lexcon) {
|
||||
case L_ERE:
|
||||
case L_BRE:
|
||||
case L_Q:
|
||||
@@ -340,8 +333,7 @@ next(struct vars * v)
|
||||
c = *v->now++;
|
||||
|
||||
/* deal with the easy contexts, punt EREs to code below */
|
||||
switch (v->lexcon)
|
||||
{
|
||||
switch (v->lexcon) {
|
||||
case L_BRE: /* punt BREs to separate function */
|
||||
return brenext(v, c);
|
||||
break;
|
||||
@@ -352,46 +344,33 @@ next(struct vars * v)
|
||||
break;
|
||||
case L_BBND: /* bounds are fairly simple */
|
||||
case L_EBND:
|
||||
switch (c)
|
||||
{
|
||||
case CHR('0'):
|
||||
case CHR('1'):
|
||||
case CHR('2'):
|
||||
case CHR('3'):
|
||||
case CHR('4'):
|
||||
case CHR('5'):
|
||||
case CHR('6'):
|
||||
case CHR('7'):
|
||||
case CHR('8'):
|
||||
case CHR('9'):
|
||||
switch (c) {
|
||||
case CHR('0'): case CHR('1'): case CHR('2'): case CHR('3'):
|
||||
case CHR('4'): case CHR('5'): case CHR('6'): case CHR('7'):
|
||||
case CHR('8'): case CHR('9'):
|
||||
RETV(DIGIT, (chr)DIGITVAL(c));
|
||||
break;
|
||||
case CHR(','):
|
||||
RET(',');
|
||||
break;
|
||||
case CHR('}'): /* ERE bound ends with } */
|
||||
if (INCON(L_EBND))
|
||||
{
|
||||
if (INCON(L_EBND)) {
|
||||
INTOCON(L_ERE);
|
||||
if ((v->cflags & REG_ADVF) && NEXT1('?'))
|
||||
{
|
||||
if ((v->cflags®_ADVF) && NEXT1('?')) {
|
||||
v->now++;
|
||||
NOTE(REG_UNONPOSIX);
|
||||
RETV('}', 0);
|
||||
}
|
||||
RETV('}', 1);
|
||||
}
|
||||
else
|
||||
} else
|
||||
FAILW(REG_BADBR);
|
||||
break;
|
||||
case CHR('\\'): /* BRE bound ends with \} */
|
||||
if (INCON(L_BBND) && NEXT1('}'))
|
||||
{
|
||||
if (INCON(L_BBND) && NEXT1('}')) {
|
||||
v->now++;
|
||||
INTOCON(L_BRE);
|
||||
RET('}');
|
||||
}
|
||||
else
|
||||
} else
|
||||
FAILW(REG_BADBR);
|
||||
break;
|
||||
default:
|
||||
@@ -401,13 +380,11 @@ next(struct vars * v)
|
||||
assert(NOTREACHED);
|
||||
break;
|
||||
case L_BRACK: /* brackets are not too hard */
|
||||
switch (c)
|
||||
{
|
||||
switch (c) {
|
||||
case CHR(']'):
|
||||
if (LASTTYPE('['))
|
||||
RETV(PLAIN, c);
|
||||
else
|
||||
{
|
||||
else {
|
||||
INTOCON((v->cflags®_EXTENDED) ?
|
||||
L_ERE : L_BRE);
|
||||
RET(']');
|
||||
@@ -421,14 +398,12 @@ next(struct vars * v)
|
||||
if (ATEOS())
|
||||
FAILW(REG_EESCAPE);
|
||||
(DISCARD)lexescape(v);
|
||||
switch (v->nexttype)
|
||||
{ /* not all escapes okay here */
|
||||
switch (v->nexttype) { /* not all escapes okay here */
|
||||
case PLAIN:
|
||||
return 1;
|
||||
break;
|
||||
case CCLASS:
|
||||
switch (v->nextvalue)
|
||||
{
|
||||
switch (v->nextvalue) {
|
||||
case 'd':
|
||||
lexnest(v, brbackd, ENDOF(brbackd));
|
||||
break;
|
||||
@@ -459,8 +434,7 @@ next(struct vars * v)
|
||||
case CHR('['):
|
||||
if (ATEOS())
|
||||
FAILW(REG_EBRACK);
|
||||
switch (*v->now++)
|
||||
{
|
||||
switch (*v->now++) {
|
||||
case CHR('.'):
|
||||
INTOCON(L_CEL);
|
||||
/* might or might not be locale-specific */
|
||||
@@ -490,33 +464,27 @@ next(struct vars * v)
|
||||
assert(NOTREACHED);
|
||||
break;
|
||||
case L_CEL: /* collating elements are easy */
|
||||
if (c == CHR('.') && NEXT1(']'))
|
||||
{
|
||||
if (c == CHR('.') && NEXT1(']')) {
|
||||
v->now++;
|
||||
INTOCON(L_BRACK);
|
||||
RETV(END, '.');
|
||||
}
|
||||
else
|
||||
} else
|
||||
RETV(PLAIN, c);
|
||||
break;
|
||||
case L_ECL: /* ditto equivalence classes */
|
||||
if (c == CHR('=') && NEXT1(']'))
|
||||
{
|
||||
if (c == CHR('=') && NEXT1(']')) {
|
||||
v->now++;
|
||||
INTOCON(L_BRACK);
|
||||
RETV(END, '=');
|
||||
}
|
||||
else
|
||||
} else
|
||||
RETV(PLAIN, c);
|
||||
break;
|
||||
case L_CCL: /* ditto character classes */
|
||||
if (c == CHR(':') && NEXT1(']'))
|
||||
{
|
||||
if (c == CHR(':') && NEXT1(']')) {
|
||||
v->now++;
|
||||
INTOCON(L_BRACK);
|
||||
RETV(END, ':');
|
||||
}
|
||||
else
|
||||
} else
|
||||
RETV(PLAIN, c);
|
||||
break;
|
||||
default:
|
||||
@@ -528,14 +496,12 @@ next(struct vars * v)
|
||||
assert(INCON(L_ERE));
|
||||
|
||||
/* deal with EREs and AREs, except for backslashes */
|
||||
switch (c)
|
||||
{
|
||||
switch (c) {
|
||||
case CHR('|'):
|
||||
RET('|');
|
||||
break;
|
||||
case CHR('*'):
|
||||
if ((v->cflags & REG_ADVF) && NEXT1('?'))
|
||||
{
|
||||
if ((v->cflags®_ADVF) && NEXT1('?')) {
|
||||
v->now++;
|
||||
NOTE(REG_UNONPOSIX);
|
||||
RETV('*', 0);
|
||||
@@ -543,8 +509,7 @@ next(struct vars * v)
|
||||
RETV('*', 1);
|
||||
break;
|
||||
case CHR('+'):
|
||||
if ((v->cflags & REG_ADVF) && NEXT1('?'))
|
||||
{
|
||||
if ((v->cflags®_ADVF) && NEXT1('?')) {
|
||||
v->now++;
|
||||
NOTE(REG_UNONPOSIX);
|
||||
RETV('+', 0);
|
||||
@@ -552,8 +517,7 @@ next(struct vars * v)
|
||||
RETV('+', 1);
|
||||
break;
|
||||
case CHR('?'):
|
||||
if ((v->cflags & REG_ADVF) && NEXT1('?'))
|
||||
{
|
||||
if ((v->cflags®_ADVF) && NEXT1('?')) {
|
||||
v->now++;
|
||||
NOTE(REG_UNONPOSIX);
|
||||
RETV('?', 0);
|
||||
@@ -563,14 +527,11 @@ next(struct vars * v)
|
||||
case CHR('{'): /* bounds start or plain character */
|
||||
if (v->cflags®_EXPANDED)
|
||||
skip(v);
|
||||
if (ATEOS() || !iscdigit(*v->now))
|
||||
{
|
||||
if (ATEOS() || !iscdigit(*v->now)) {
|
||||
NOTE(REG_UBRACES);
|
||||
NOTE(REG_UUNSPEC);
|
||||
RETV(PLAIN, c);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
NOTE(REG_UBOUNDS);
|
||||
INTOCON(L_EBND);
|
||||
RET('{');
|
||||
@@ -578,12 +539,10 @@ next(struct vars * v)
|
||||
assert(NOTREACHED);
|
||||
break;
|
||||
case CHR('('): /* parenthesis, or advanced extension */
|
||||
if ((v->cflags & REG_ADVF) && NEXT1('?'))
|
||||
{
|
||||
if ((v->cflags®_ADVF) && NEXT1('?')) {
|
||||
NOTE(REG_UNONPOSIX);
|
||||
v->now++;
|
||||
switch (*v->now++)
|
||||
{
|
||||
switch (*v->now++) {
|
||||
case CHR(':'): /* non-capturing paren */
|
||||
RETV('(', 0);
|
||||
break;
|
||||
@@ -615,8 +574,9 @@ next(struct vars * v)
|
||||
RETV('(', 1);
|
||||
break;
|
||||
case CHR(')'):
|
||||
if (LASTTYPE('('))
|
||||
if (LASTTYPE('(')) {
|
||||
NOTE(REG_UUNSPEC);
|
||||
}
|
||||
RETV(')', c);
|
||||
break;
|
||||
case CHR('['): /* easy except for [[:<:]] and [[:>:]] */
|
||||
@@ -626,16 +586,14 @@ next(struct vars * v)
|
||||
*(v->now+2) == CHR('>')) &&
|
||||
*(v->now+3) == CHR(':') &&
|
||||
*(v->now+4) == CHR(']') &&
|
||||
*(v->now + 5) == CHR(']'))
|
||||
{
|
||||
*(v->now+5) == CHR(']')) {
|
||||
c = *(v->now+2);
|
||||
v->now += 6;
|
||||
NOTE(REG_UNONPOSIX);
|
||||
RET((c == CHR('<')) ? '<' : '>');
|
||||
}
|
||||
INTOCON(L_BRACK);
|
||||
if (NEXT1('^'))
|
||||
{
|
||||
if (NEXT1('^')) {
|
||||
v->now++;
|
||||
RETV('[', 0);
|
||||
}
|
||||
@@ -661,10 +619,8 @@ next(struct vars * v)
|
||||
|
||||
/* ERE/ARE backslash handling; backslash already eaten */
|
||||
assert(!ATEOS());
|
||||
if (!(v->cflags & REG_ADVF))
|
||||
{ /* only AREs have non-trivial escapes */
|
||||
if (iscalnum(*v->now))
|
||||
{
|
||||
if (!(v->cflags®_ADVF)) { /* only AREs have non-trivial escapes */
|
||||
if (iscalnum(*v->now)) {
|
||||
NOTE(REG_UBSALNUM);
|
||||
NOTE(REG_UUNSPEC);
|
||||
}
|
||||
@@ -673,28 +629,14 @@ next(struct vars * v)
|
||||
(DISCARD)lexescape(v);
|
||||
if (ISERR())
|
||||
FAILW(REG_EESCAPE);
|
||||
if (v->nexttype == CCLASS)
|
||||
{ /* fudge at lexical level */
|
||||
switch (v->nextvalue)
|
||||
{
|
||||
case 'd':
|
||||
lexnest(v, backd, ENDOF(backd));
|
||||
break;
|
||||
case 'D':
|
||||
lexnest(v, backD, ENDOF(backD));
|
||||
break;
|
||||
case 's':
|
||||
lexnest(v, backs, ENDOF(backs));
|
||||
break;
|
||||
case 'S':
|
||||
lexnest(v, backS, ENDOF(backS));
|
||||
break;
|
||||
case 'w':
|
||||
lexnest(v, backw, ENDOF(backw));
|
||||
break;
|
||||
case 'W':
|
||||
lexnest(v, backW, ENDOF(backW));
|
||||
break;
|
||||
if (v->nexttype == CCLASS) { /* fudge at lexical level */
|
||||
switch (v->nextvalue) {
|
||||
case 'd': lexnest(v, backd, ENDOF(backd)); break;
|
||||
case 'D': lexnest(v, backD, ENDOF(backD)); break;
|
||||
case 's': lexnest(v, backs, ENDOF(backs)); break;
|
||||
case 'S': lexnest(v, backS, ENDOF(backS)); break;
|
||||
case 'w': lexnest(v, backw, ENDOF(backw)); break;
|
||||
case 'W': lexnest(v, backW, ENDOF(backW)); break;
|
||||
default:
|
||||
assert(NOTREACHED);
|
||||
FAILW(REG_ASSERT);
|
||||
@@ -709,12 +651,13 @@ next(struct vars * v)
|
||||
}
|
||||
|
||||
/*
|
||||
* lexescape - parse an ARE backslash escape (backslash already eaten)
|
||||
- lexescape - parse an ARE backslash escape (backslash already eaten)
|
||||
* Note slightly nonstandard use of the CCLASS type code.
|
||||
^ static int lexescape(struct vars *);
|
||||
*/
|
||||
static int /* not actually used, but convenient for
|
||||
* RETV */
|
||||
lexescape(struct vars * v)
|
||||
static int /* not actually used, but convenient for RETV */
|
||||
lexescape(v)
|
||||
struct vars *v;
|
||||
{
|
||||
chr c;
|
||||
static chr alert[] = {
|
||||
@@ -733,8 +676,7 @@ lexescape(struct vars * v)
|
||||
RETV(PLAIN, c);
|
||||
|
||||
NOTE(REG_UNONPOSIX);
|
||||
switch (c)
|
||||
{
|
||||
switch (c) {
|
||||
case CHR('a'):
|
||||
RETV(PLAIN, chrnamed(v, alert, ENDOF(alert), CHR('\007')));
|
||||
break;
|
||||
@@ -816,8 +758,7 @@ lexescape(struct vars * v)
|
||||
break;
|
||||
case CHR('x'):
|
||||
NOTE(REG_UUNPORT);
|
||||
c = lexdigits(v, 16, 1, 255); /* REs >255 long outside
|
||||
* spec */
|
||||
c = lexdigits(v, 16, 1, 255); /* REs >255 long outside spec */
|
||||
if (ISERR())
|
||||
FAILW(REG_EESCAPE);
|
||||
RETV(PLAIN, c);
|
||||
@@ -833,24 +774,16 @@ lexescape(struct vars * v)
|
||||
case CHR('Z'):
|
||||
RETV(SEND, 0);
|
||||
break;
|
||||
case CHR('1'):
|
||||
case CHR('2'):
|
||||
case CHR('3'):
|
||||
case CHR('4'):
|
||||
case CHR('5'):
|
||||
case CHR('6'):
|
||||
case CHR('7'):
|
||||
case CHR('8'):
|
||||
case CHR('1'): case CHR('2'): case CHR('3'): case CHR('4'):
|
||||
case CHR('5'): case CHR('6'): case CHR('7'): case CHR('8'):
|
||||
case CHR('9'):
|
||||
save = v->now;
|
||||
v->now--; /* put first digit back */
|
||||
c = lexdigits(v, 10, 1, 255); /* REs >255 long outside
|
||||
* spec */
|
||||
c = lexdigits(v, 10, 1, 255); /* REs >255 long outside spec */
|
||||
if (ISERR())
|
||||
FAILW(REG_EESCAPE);
|
||||
/* ugly heuristic (first test is "exactly 1 digit?") */
|
||||
if (v->now - save == 0 || (int) c <= v->nsubexp)
|
||||
{
|
||||
if (v->now - save == 0 || (int)c <= v->nsubexp) {
|
||||
NOTE(REG_UBACKREF);
|
||||
RETV(BACKREF, (chr)c);
|
||||
}
|
||||
@@ -874,70 +807,44 @@ lexescape(struct vars * v)
|
||||
}
|
||||
|
||||
/*
|
||||
* lexdigits - slurp up digits and return chr value
|
||||
- lexdigits - slurp up digits and return chr value
|
||||
^ static chr lexdigits(struct vars *, int, int, int);
|
||||
*/
|
||||
static chr /* chr value; errors signalled via ERR */
|
||||
lexdigits(struct vars * v,
|
||||
int base,
|
||||
int minlen,
|
||||
int maxlen)
|
||||
lexdigits(v, base, minlen, maxlen)
|
||||
struct vars *v;
|
||||
int base;
|
||||
int minlen;
|
||||
int maxlen;
|
||||
{
|
||||
uchr n; /* unsigned to avoid overflow misbehavior */
|
||||
int len;
|
||||
chr c;
|
||||
int d;
|
||||
const uchr ub = (uchr) base;
|
||||
CONST uchr ub = (uchr) base;
|
||||
|
||||
n = 0;
|
||||
for (len = 0; len < maxlen && !ATEOS(); len++)
|
||||
{
|
||||
for (len = 0; len < maxlen && !ATEOS(); len++) {
|
||||
c = *v->now++;
|
||||
switch (c)
|
||||
{
|
||||
case CHR('0'):
|
||||
case CHR('1'):
|
||||
case CHR('2'):
|
||||
case CHR('3'):
|
||||
case CHR('4'):
|
||||
case CHR('5'):
|
||||
case CHR('6'):
|
||||
case CHR('7'):
|
||||
case CHR('8'):
|
||||
case CHR('9'):
|
||||
switch (c) {
|
||||
case CHR('0'): case CHR('1'): case CHR('2'): case CHR('3'):
|
||||
case CHR('4'): case CHR('5'): case CHR('6'): case CHR('7'):
|
||||
case CHR('8'): case CHR('9'):
|
||||
d = DIGITVAL(c);
|
||||
break;
|
||||
case CHR('a'):
|
||||
case CHR('A'):
|
||||
d = 10;
|
||||
break;
|
||||
case CHR('b'):
|
||||
case CHR('B'):
|
||||
d = 11;
|
||||
break;
|
||||
case CHR('c'):
|
||||
case CHR('C'):
|
||||
d = 12;
|
||||
break;
|
||||
case CHR('d'):
|
||||
case CHR('D'):
|
||||
d = 13;
|
||||
break;
|
||||
case CHR('e'):
|
||||
case CHR('E'):
|
||||
d = 14;
|
||||
break;
|
||||
case CHR('f'):
|
||||
case CHR('F'):
|
||||
d = 15;
|
||||
break;
|
||||
case CHR('a'): case CHR('A'): d = 10; break;
|
||||
case CHR('b'): case CHR('B'): d = 11; break;
|
||||
case CHR('c'): case CHR('C'): d = 12; break;
|
||||
case CHR('d'): case CHR('D'): d = 13; break;
|
||||
case CHR('e'): case CHR('E'): d = 14; break;
|
||||
case CHR('f'): case CHR('F'): d = 15; break;
|
||||
default:
|
||||
v->now--; /* oops, not a digit at all */
|
||||
d = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (d >= base)
|
||||
{ /* not a plausible digit */
|
||||
if (d >= base) { /* not a plausible digit */
|
||||
v->now--;
|
||||
d = -1;
|
||||
}
|
||||
@@ -952,19 +859,19 @@ lexdigits(struct vars * v,
|
||||
}
|
||||
|
||||
/*
|
||||
* brenext - get next BRE token
|
||||
*
|
||||
- brenext - get next BRE token
|
||||
* This is much like EREs except for all the stupid backslashes and the
|
||||
* context-dependency of some things.
|
||||
^ static int brenext(struct vars *, pchr);
|
||||
*/
|
||||
static int /* 1 normal, 0 failure */
|
||||
brenext(struct vars * v,
|
||||
chr pc)
|
||||
brenext(v, pc)
|
||||
struct vars *v;
|
||||
pchr pc;
|
||||
{
|
||||
chr c = (chr)pc;
|
||||
|
||||
switch (c)
|
||||
{
|
||||
switch (c) {
|
||||
case CHR('*'):
|
||||
if (LASTTYPE(EMPTY) || LASTTYPE('(') || LASTTYPE('^'))
|
||||
RETV(PLAIN, c);
|
||||
@@ -977,16 +884,14 @@ brenext(struct vars * v,
|
||||
*(v->now+2) == CHR('>')) &&
|
||||
*(v->now+3) == CHR(':') &&
|
||||
*(v->now+4) == CHR(']') &&
|
||||
*(v->now + 5) == CHR(']'))
|
||||
{
|
||||
*(v->now+5) == CHR(']')) {
|
||||
c = *(v->now+2);
|
||||
v->now += 6;
|
||||
NOTE(REG_UNONPOSIX);
|
||||
RET((c == CHR('<')) ? '<' : '>');
|
||||
}
|
||||
INTOCON(L_BRACK);
|
||||
if (NEXT1('^'))
|
||||
{
|
||||
if (NEXT1('^')) {
|
||||
v->now++;
|
||||
RETV('[', 0);
|
||||
}
|
||||
@@ -998,8 +903,7 @@ brenext(struct vars * v,
|
||||
case CHR('^'):
|
||||
if (LASTTYPE(EMPTY))
|
||||
RET('^');
|
||||
if (LASTTYPE('('))
|
||||
{
|
||||
if (LASTTYPE('(')) {
|
||||
NOTE(REG_UUNSPEC);
|
||||
RET('^');
|
||||
}
|
||||
@@ -1010,8 +914,7 @@ brenext(struct vars * v,
|
||||
skip(v);
|
||||
if (ATEOS())
|
||||
RET('$');
|
||||
if (NEXT2('\\', ')'))
|
||||
{
|
||||
if (NEXT2('\\', ')')) {
|
||||
NOTE(REG_UUNSPEC);
|
||||
RET('$');
|
||||
}
|
||||
@@ -1030,8 +933,7 @@ brenext(struct vars * v,
|
||||
FAILW(REG_EESCAPE);
|
||||
|
||||
c = *v->now++;
|
||||
switch (c)
|
||||
{
|
||||
switch (c) {
|
||||
case CHR('{'):
|
||||
INTOCON(L_BBND);
|
||||
NOTE(REG_UBOUNDS);
|
||||
@@ -1051,21 +953,14 @@ brenext(struct vars * v,
|
||||
NOTE(REG_UNONPOSIX);
|
||||
RET('>');
|
||||
break;
|
||||
case CHR('1'):
|
||||
case CHR('2'):
|
||||
case CHR('3'):
|
||||
case CHR('4'):
|
||||
case CHR('5'):
|
||||
case CHR('6'):
|
||||
case CHR('7'):
|
||||
case CHR('8'):
|
||||
case CHR('1'): case CHR('2'): case CHR('3'): case CHR('4'):
|
||||
case CHR('5'): case CHR('6'): case CHR('7'): case CHR('8'):
|
||||
case CHR('9'):
|
||||
NOTE(REG_UBACKREF);
|
||||
RETV(BACKREF, (chr)DIGITVAL(c));
|
||||
break;
|
||||
default:
|
||||
if (iscalnum(c))
|
||||
{
|
||||
if (iscalnum(c)) {
|
||||
NOTE(REG_UBSALNUM);
|
||||
NOTE(REG_UUNSPEC);
|
||||
}
|
||||
@@ -1077,17 +972,18 @@ brenext(struct vars * v,
|
||||
}
|
||||
|
||||
/*
|
||||
* skip - skip white space and comments in expanded form
|
||||
- skip - skip white space and comments in expanded form
|
||||
^ static VOID skip(struct vars *);
|
||||
*/
|
||||
static void
|
||||
skip(struct vars * v)
|
||||
static VOID
|
||||
skip(v)
|
||||
struct vars *v;
|
||||
{
|
||||
chr *start = v->now;
|
||||
|
||||
assert(v->cflags®_EXPANDED);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
for (;;) {
|
||||
while (!ATEOS() && iscspace(*v->now))
|
||||
v->now++;
|
||||
if (ATEOS() || *v->now != CHR('#'))
|
||||
@@ -1103,27 +999,46 @@ skip(struct vars * v)
|
||||
}
|
||||
|
||||
/*
|
||||
* newline - return the chr for a newline
|
||||
*
|
||||
- newline - return the chr for a newline
|
||||
* This helps confine use of CHR to this source file.
|
||||
^ static chr newline(NOPARMS);
|
||||
*/
|
||||
static chr
|
||||
newline(void)
|
||||
newline()
|
||||
{
|
||||
return CHR('\n');
|
||||
}
|
||||
|
||||
/*
|
||||
* chrnamed - return the chr known by a given (chr string) name
|
||||
*
|
||||
- ch - return the chr sequence for regc_locale.c's fake collating element ch
|
||||
* This helps confine use of CHR to this source file. Beware that the caller
|
||||
* knows how long the sequence is.
|
||||
^ #ifdef REG_DEBUG
|
||||
^ static chr *ch(NOPARMS);
|
||||
^ #endif
|
||||
*/
|
||||
#ifdef REG_DEBUG
|
||||
static chr *
|
||||
ch()
|
||||
{
|
||||
static chr chstr[] = { CHR('c'), CHR('h'), CHR('\0') };
|
||||
|
||||
return chstr;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
- chrnamed - return the chr known by a given (chr string) name
|
||||
* The code is a bit clumsy, but this routine gets only such specialized
|
||||
* use that it hardly matters.
|
||||
^ static chr chrnamed(struct vars *, chr *, chr *, pchr);
|
||||
*/
|
||||
static chr
|
||||
chrnamed(struct vars * v,
|
||||
chr *startp, /* start of name */
|
||||
chr *endp, /* just past end of name */
|
||||
chr lastresort) /* what to return if name lookup fails */
|
||||
chrnamed(v, startp, endp, lastresort)
|
||||
struct vars *v;
|
||||
chr *startp; /* start of name */
|
||||
chr *endp; /* just past end of name */
|
||||
pchr lastresort; /* what to return if name lookup fails */
|
||||
{
|
||||
celt c;
|
||||
int errsave;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
1079
src/regex/regcomp.c
1079
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.
|
||||
*
|
||||
@@ -27,72 +24,97 @@
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
/* headers if any */
|
||||
|
||||
/* FreeBSD, Watcom and DMars require this, CW doesn't have nor need it. */
|
||||
/* Others also don't seem to need it. If you have an error related to */
|
||||
/* (not) including <sys/types.h> please report details to */
|
||||
/* wx-dev@lists.wxwindows.org */
|
||||
#if defined(__UNIX__) || defined(__WATCOMC__) || defined(__DIGITALMARS__)
|
||||
# include <sys/types.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "wx/wxchar.h"
|
||||
|
||||
/**
|
||||
*
|
||||
* wx_wchar == wxChar
|
||||
*
|
||||
*/
|
||||
#define wx_wchar wxChar
|
||||
#include "tclInt.h"
|
||||
|
||||
/* overrides for regguts.h definitions, if any */
|
||||
#define FUNCPTR(name, args) (*name) args
|
||||
#define MALLOC(n) malloc(n)
|
||||
#define FREE(p) free(VS(p))
|
||||
#define REALLOC(p,n) realloc(VS(p),n)
|
||||
#define FUNCPTR(name, args) (*name) _ANSI_ARGS_(args)
|
||||
#define MALLOC(n) ckalloc(n)
|
||||
#define FREE(p) ckfree(VS(p))
|
||||
#define REALLOC(p,n) ckrealloc(VS(p),n)
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Do not insert extras between the "begin" and "end" lines -- this
|
||||
* chunk is automatically extracted to be fitted into regex.h.
|
||||
*/
|
||||
/* --- begin --- */
|
||||
/* ensure certain things don't sneak in from system headers */
|
||||
#ifdef __REG_WIDE_T
|
||||
#undef __REG_WIDE_T
|
||||
#endif
|
||||
#ifdef __REG_WIDE_COMPILE
|
||||
#undef __REG_WIDE_COMPILE
|
||||
#endif
|
||||
#ifdef __REG_WIDE_EXEC
|
||||
#undef __REG_WIDE_EXEC
|
||||
#endif
|
||||
#ifdef __REG_REGOFF_T
|
||||
#undef __REG_REGOFF_T
|
||||
#endif
|
||||
#ifdef __REG_VOID_T
|
||||
#undef __REG_VOID_T
|
||||
#endif
|
||||
#ifdef __REG_CONST
|
||||
#undef __REG_CONST
|
||||
#endif
|
||||
#ifdef __REG_NOFRONT
|
||||
#undef __REG_NOFRONT
|
||||
#endif
|
||||
#ifdef __REG_NOCHAR
|
||||
#undef __REG_NOCHAR
|
||||
#endif
|
||||
/* interface types */
|
||||
#define __REG_WIDE_T Tcl_UniChar
|
||||
#define __REG_REGOFF_T long /* not really right, but good enough... */
|
||||
#define __REG_VOID_T VOID
|
||||
#define __REG_CONST CONST
|
||||
/* names and declarations */
|
||||
#define __REG_WIDE_COMPILE TclReComp
|
||||
#define __REG_WIDE_EXEC TclReExec
|
||||
#define __REG_NOFRONT /* don't want regcomp() and regexec() */
|
||||
#define __REG_NOCHAR /* or the char versions */
|
||||
#define regfree TclReFree
|
||||
#define regerror TclReError
|
||||
/* --- end --- */
|
||||
|
||||
|
||||
|
||||
/* internal character type and related */
|
||||
typedef wx_wchar chr; /* the type itself */
|
||||
typedef unsigned long uchr; /* unsigned type that will hold a chr */
|
||||
typedef long celt; /* type to hold chr, MCCE number, or
|
||||
* NOCELT */
|
||||
|
||||
#define NOCELT (-1) /* celt value which is not valid chr or
|
||||
* MCCE */
|
||||
#define CHR(c) ((unsigned char) (c)) /* turn char literal into chr
|
||||
* literal */
|
||||
typedef Tcl_UniChar chr; /* the type itself */
|
||||
typedef int pchr; /* what it promotes to */
|
||||
typedef unsigned uchr; /* unsigned type that will hold a chr */
|
||||
typedef int celt; /* type to hold chr, MCCE number, or NOCELT */
|
||||
#define NOCELT (-1) /* celt value which is not valid chr or MCCE */
|
||||
#define CHR(c) (UCHAR(c)) /* turn char literal into chr literal */
|
||||
#define DIGITVAL(c) ((c)-'0') /* turn chr digit into its value */
|
||||
|
||||
#if wxUSE_WCHAR_T
|
||||
# define CHRBITS (SIZEOF_WCHAR_T << 3) /* bits in a chr; must not use sizeof */
|
||||
# define CHR_MAX ((1 << CHRBITS) - 1)
|
||||
#if TCL_UTF_MAX > 3
|
||||
#define CHRBITS 32 /* bits in a chr; must not use sizeof */
|
||||
#define CHR_MIN 0x00000000 /* smallest and largest chr; the value */
|
||||
#else /*ANSI*/
|
||||
# define CHRBITS 8
|
||||
# define CHR_MAX 0xFF
|
||||
# define CHR_MIN 0x00
|
||||
#endif /*wxUSE_WCHAR_T*/
|
||||
#define CHR_MAX 0xffffffff /* CHR_MAX-CHR_MIN+1 should fit in uchr */
|
||||
#else
|
||||
#define CHRBITS 16 /* bits in a chr; must not use sizeof */
|
||||
#define CHR_MIN 0x0000 /* smallest and largest chr; the value */
|
||||
#define CHR_MAX 0xffff /* CHR_MAX-CHR_MIN+1 should fit in uchr */
|
||||
#endif
|
||||
|
||||
/* functions operating on chr */
|
||||
#define iscalnum(x) wx_isalnum(x)
|
||||
#define iscalpha(x) wx_isalpha(x)
|
||||
#define iscdigit(x) wx_isdigit(x)
|
||||
#define iscspace(x) wx_isspace(x)
|
||||
#define iscalnum(x) Tcl_UniCharIsAlnum(x)
|
||||
#define iscalpha(x) Tcl_UniCharIsAlpha(x)
|
||||
#define iscdigit(x) Tcl_UniCharIsDigit(x)
|
||||
#define iscspace(x) Tcl_UniCharIsSpace(x)
|
||||
|
||||
extern int wx_strlen(const wx_wchar* szString);
|
||||
/* name the external functions */
|
||||
#define compile TclReComp
|
||||
#define exec TclReExec
|
||||
|
||||
/* enable/disable debugging code (by whether REG_DEBUG is defined or not) */
|
||||
#if 0 /* no debug unless requested by makefile */
|
||||
#define REG_DEBUG /* */
|
||||
#endif
|
||||
|
||||
/* and pick up the standard header */
|
||||
#include "regex.h"
|
||||
|
||||
#endif /* _REGEX_CUSTOM_H_ */
|
||||
|
||||
@@ -28,19 +28,19 @@
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $Header$
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* longest - longest-preferred matching engine
|
||||
- longest - longest-preferred matching engine
|
||||
^ static chr *longest(struct vars *, struct dfa *, chr *, chr *, int *);
|
||||
*/
|
||||
static chr * /* endpoint, or NULL */
|
||||
longest(struct vars * v, /* used only for debug and exec flags */
|
||||
struct dfa * d,
|
||||
chr *start, /* where the match should start */
|
||||
chr *stop, /* match must end at or before here */
|
||||
int *hitstopp) /* record whether hit v->stop, if non-NULL */
|
||||
longest(v, d, start, stop, hitstopp)
|
||||
struct vars *v; /* used only for debug and exec flags */
|
||||
struct dfa *d;
|
||||
chr *start; /* where the match should start */
|
||||
chr *stop; /* match must end at or before here */
|
||||
int *hitstopp; /* record whether hit v->stop, if non-NULL */
|
||||
{
|
||||
chr *cp;
|
||||
chr *realstop = (stop == v->stop) ? stop : stop + 1;
|
||||
@@ -59,13 +59,10 @@ longest(struct vars * v, /* used only for debug and exec flags */
|
||||
|
||||
/* startup */
|
||||
FDEBUG(("+++ startup +++\n"));
|
||||
if (cp == v->start)
|
||||
{
|
||||
if (cp == v->start) {
|
||||
co = d->cnfa->bos[(v->eflags®_NOTBOL) ? 0 : 1];
|
||||
FDEBUG(("color %ld\n", (long)co));
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
co = GETCOLOR(cm, *(cp - 1));
|
||||
FDEBUG(("char %c, color %ld\n", (char)*(cp-1), (long)co));
|
||||
}
|
||||
@@ -76,14 +73,12 @@ longest(struct vars * v, /* used only for debug and exec flags */
|
||||
|
||||
/* main loop */
|
||||
if (v->eflags®_FTRACE)
|
||||
while (cp < realstop)
|
||||
{
|
||||
while (cp < realstop) {
|
||||
FDEBUG(("+++ at c%d +++\n", css - d->ssets));
|
||||
co = GETCOLOR(cm, *cp);
|
||||
FDEBUG(("char %c, color %ld\n", (char)*cp, (long)co));
|
||||
ss = css->outs[co];
|
||||
if (ss == NULL)
|
||||
{
|
||||
if (ss == NULL) {
|
||||
ss = miss(v, d, css, co, cp+1, start);
|
||||
if (ss == NULL)
|
||||
break; /* NOTE BREAK OUT */
|
||||
@@ -93,12 +88,10 @@ longest(struct vars * v, /* used only for debug and exec flags */
|
||||
css = ss;
|
||||
}
|
||||
else
|
||||
while (cp < realstop)
|
||||
{
|
||||
while (cp < realstop) {
|
||||
co = GETCOLOR(cm, *cp);
|
||||
ss = css->outs[co];
|
||||
if (ss == NULL)
|
||||
{
|
||||
if (ss == NULL) {
|
||||
ss = miss(v, d, css, co, cp+1, start);
|
||||
if (ss == NULL)
|
||||
break; /* NOTE BREAK OUT */
|
||||
@@ -110,8 +103,7 @@ longest(struct vars * v, /* used only for debug and exec flags */
|
||||
|
||||
/* shutdown */
|
||||
FDEBUG(("+++ shutdown at c%d +++\n", css - d->ssets));
|
||||
if (cp == v->stop && stop == v->stop)
|
||||
{
|
||||
if (cp == v->stop && stop == v->stop) {
|
||||
if (hitstopp != NULL)
|
||||
*hitstopp = 1;
|
||||
co = d->cnfa->eos[(v->eflags®_NOTEOL) ? 0 : 1];
|
||||
@@ -137,17 +129,19 @@ longest(struct vars * v, /* used only for debug and exec flags */
|
||||
}
|
||||
|
||||
/*
|
||||
* shortest - shortest-preferred matching engine
|
||||
- shortest - shortest-preferred matching engine
|
||||
^ static chr *shortest(struct vars *, struct dfa *, chr *, chr *, chr *,
|
||||
^ chr **, int *);
|
||||
*/
|
||||
static chr * /* endpoint, or NULL */
|
||||
shortest(struct vars * v,
|
||||
struct dfa * d,
|
||||
chr *start, /* where the match should start */
|
||||
chr *min, /* match must end at or after here */
|
||||
chr *max, /* match must end at or before here */
|
||||
chr **coldp, /* store coldstart pointer here, if
|
||||
* nonNULL */
|
||||
int *hitstopp) /* record whether hit v->stop, if non-NULL */
|
||||
shortest(v, d, start, min, max, coldp, hitstopp)
|
||||
struct vars *v;
|
||||
struct dfa *d;
|
||||
chr *start; /* where the match should start */
|
||||
chr *min; /* match must end at or after here */
|
||||
chr *max; /* match must end at or before here */
|
||||
chr **coldp; /* store coldstart pointer here, if nonNULL */
|
||||
int *hitstopp; /* record whether hit v->stop, if non-NULL */
|
||||
{
|
||||
chr *cp;
|
||||
chr *realmin = (min == v->stop) ? min : min + 1;
|
||||
@@ -165,13 +159,10 @@ shortest(struct vars * v,
|
||||
|
||||
/* startup */
|
||||
FDEBUG(("--- startup ---\n"));
|
||||
if (cp == v->start)
|
||||
{
|
||||
if (cp == v->start) {
|
||||
co = d->cnfa->bos[(v->eflags®_NOTBOL) ? 0 : 1];
|
||||
FDEBUG(("color %ld\n", (long)co));
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
co = GETCOLOR(cm, *(cp - 1));
|
||||
FDEBUG(("char %c, color %ld\n", (char)*(cp-1), (long)co));
|
||||
}
|
||||
@@ -183,14 +174,12 @@ shortest(struct vars * v,
|
||||
|
||||
/* main loop */
|
||||
if (v->eflags®_FTRACE)
|
||||
while (cp < realmax)
|
||||
{
|
||||
while (cp < realmax) {
|
||||
FDEBUG(("--- at c%d ---\n", css - d->ssets));
|
||||
co = GETCOLOR(cm, *cp);
|
||||
FDEBUG(("char %c, color %ld\n", (char)*cp, (long)co));
|
||||
ss = css->outs[co];
|
||||
if (ss == NULL)
|
||||
{
|
||||
if (ss == NULL) {
|
||||
ss = miss(v, d, css, co, cp+1, start);
|
||||
if (ss == NULL)
|
||||
break; /* NOTE BREAK OUT */
|
||||
@@ -202,12 +191,10 @@ shortest(struct vars * v,
|
||||
break; /* NOTE BREAK OUT */
|
||||
}
|
||||
else
|
||||
while (cp < realmax)
|
||||
{
|
||||
while (cp < realmax) {
|
||||
co = GETCOLOR(cm, *cp);
|
||||
ss = css->outs[co];
|
||||
if (ss == NULL)
|
||||
{
|
||||
if (ss == NULL) {
|
||||
ss = miss(v, d, css, co, cp+1, start);
|
||||
if (ss == NULL)
|
||||
break; /* NOTE BREAK OUT */
|
||||
@@ -222,17 +209,13 @@ shortest(struct vars * v,
|
||||
if (ss == NULL)
|
||||
return NULL;
|
||||
|
||||
if (coldp != NULL) /* report last no-progress state set, if
|
||||
* any */
|
||||
if (coldp != NULL) /* report last no-progress state set, if any */
|
||||
*coldp = lastcold(v, d);
|
||||
|
||||
if ((ss->flags & POSTSTATE) && cp > min)
|
||||
{
|
||||
if ((ss->flags&POSTSTATE) && cp > min) {
|
||||
assert(cp >= realmin);
|
||||
cp--;
|
||||
}
|
||||
else if (cp == v->stop && max == v->stop)
|
||||
{
|
||||
} else if (cp == v->stop && max == v->stop) {
|
||||
co = d->cnfa->eos[(v->eflags®_NOTEOL) ? 0 : 1];
|
||||
FDEBUG(("color %ld\n", (long)co));
|
||||
ss = miss(v, d, css, co, cp, start);
|
||||
@@ -248,11 +231,13 @@ shortest(struct vars * v,
|
||||
}
|
||||
|
||||
/*
|
||||
* lastcold - determine last point at which no progress had been made
|
||||
- lastcold - determine last point at which no progress had been made
|
||||
^ static chr *lastcold(struct vars *, struct dfa *);
|
||||
*/
|
||||
static chr * /* endpoint, or NULL */
|
||||
lastcold(struct vars * v,
|
||||
struct dfa * d)
|
||||
lastcold(v, d)
|
||||
struct vars *v;
|
||||
struct dfa *d;
|
||||
{
|
||||
struct sset *ss;
|
||||
chr *nopr;
|
||||
@@ -268,13 +253,16 @@ lastcold(struct vars * v,
|
||||
}
|
||||
|
||||
/*
|
||||
* newdfa - set up a fresh DFA
|
||||
- newdfa - set up a fresh DFA
|
||||
^ static struct dfa *newdfa(struct vars *, struct cnfa *,
|
||||
^ struct colormap *, struct smalldfa *);
|
||||
*/
|
||||
static struct dfa *
|
||||
newdfa(struct vars * v,
|
||||
struct cnfa * cnfa,
|
||||
struct colormap * cm,
|
||||
struct smalldfa * small) /* preallocated space, may be NULL */
|
||||
newdfa(v, cnfa, cm, small)
|
||||
struct vars *v;
|
||||
struct cnfa *cnfa;
|
||||
struct colormap *cm;
|
||||
struct smalldfa *small; /* preallocated space, may be NULL */
|
||||
{
|
||||
struct dfa *d;
|
||||
size_t nss = cnfa->nstates * 2;
|
||||
@@ -283,15 +271,12 @@ newdfa(struct vars * v,
|
||||
|
||||
assert(cnfa != NULL && cnfa->nstates != 0);
|
||||
|
||||
if (nss <= FEWSTATES && cnfa->ncolors <= FEWCOLORS)
|
||||
{
|
||||
if (nss <= FEWSTATES && cnfa->ncolors <= FEWCOLORS) {
|
||||
assert(wordsper == 1);
|
||||
if (small == NULL)
|
||||
{
|
||||
if (small == NULL) {
|
||||
small = (struct smalldfa *)MALLOC(
|
||||
sizeof(struct smalldfa));
|
||||
if (small == NULL)
|
||||
{
|
||||
if (small == NULL) {
|
||||
ERR(REG_ESPACE);
|
||||
return NULL;
|
||||
}
|
||||
@@ -304,12 +289,9 @@ newdfa(struct vars * v,
|
||||
d->incarea = small->incarea;
|
||||
d->cptsmalloced = 0;
|
||||
d->mallocarea = (smallwas == NULL) ? (char *)small : NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
d = (struct dfa *)MALLOC(sizeof(struct dfa));
|
||||
if (d == NULL)
|
||||
{
|
||||
if (d == NULL) {
|
||||
ERR(REG_ESPACE);
|
||||
return NULL;
|
||||
}
|
||||
@@ -324,8 +306,7 @@ newdfa(struct vars * v,
|
||||
d->cptsmalloced = 1;
|
||||
d->mallocarea = (char *)d;
|
||||
if (d->ssets == NULL || d->statesarea == NULL ||
|
||||
d->outsarea == NULL || d->incarea == NULL)
|
||||
{
|
||||
d->outsarea == NULL || d->incarea == NULL) {
|
||||
freedfa(d);
|
||||
ERR(REG_ESPACE);
|
||||
return NULL;
|
||||
@@ -349,13 +330,14 @@ newdfa(struct vars * v,
|
||||
}
|
||||
|
||||
/*
|
||||
* freedfa - free a DFA
|
||||
- freedfa - free a DFA
|
||||
^ static VOID freedfa(struct dfa *);
|
||||
*/
|
||||
static void
|
||||
freedfa(struct dfa * d)
|
||||
{
|
||||
if (d->cptsmalloced)
|
||||
static VOID
|
||||
freedfa(d)
|
||||
struct dfa *d;
|
||||
{
|
||||
if (d->cptsmalloced) {
|
||||
if (d->ssets != NULL)
|
||||
FREE(d->ssets);
|
||||
if (d->statesarea != NULL)
|
||||
@@ -371,13 +353,14 @@ freedfa(struct dfa * d)
|
||||
}
|
||||
|
||||
/*
|
||||
* hash - construct a hash code for a bitvector
|
||||
*
|
||||
- hash - construct a hash code for a bitvector
|
||||
* There are probably better ways, but they're more expensive.
|
||||
^ static unsigned hash(unsigned *, int);
|
||||
*/
|
||||
static unsigned
|
||||
hash(unsigned *uv,
|
||||
int n)
|
||||
hash(uv, n)
|
||||
unsigned *uv;
|
||||
int n;
|
||||
{
|
||||
int i;
|
||||
unsigned h;
|
||||
@@ -389,12 +372,14 @@ hash(unsigned *uv,
|
||||
}
|
||||
|
||||
/*
|
||||
* initialize - hand-craft a cache entry for startup, otherwise get ready
|
||||
- initialize - hand-craft a cache entry for startup, otherwise get ready
|
||||
^ static struct sset *initialize(struct vars *, struct dfa *, chr *);
|
||||
*/
|
||||
static struct sset *
|
||||
initialize(struct vars * v, /* used only for debug flags */
|
||||
struct dfa * d,
|
||||
chr *start)
|
||||
initialize(v, d, start)
|
||||
struct vars *v; /* used only for debug flags */
|
||||
struct dfa *d;
|
||||
chr *start;
|
||||
{
|
||||
struct sset *ss;
|
||||
int i;
|
||||
@@ -402,8 +387,7 @@ initialize(struct vars * v, /* used only for debug flags */
|
||||
/* is previous one still there? */
|
||||
if (d->nssused > 0 && (d->ssets[0].flags&STARTER))
|
||||
ss = &d->ssets[0];
|
||||
else
|
||||
{ /* no, must (re)build it */
|
||||
else { /* no, must (re)build it */
|
||||
ss = getvacant(v, d, start, start);
|
||||
for (i = 0; i < d->wordsper; i++)
|
||||
ss->states[i] = 0;
|
||||
@@ -423,15 +407,18 @@ initialize(struct vars * v, /* used only for debug flags */
|
||||
}
|
||||
|
||||
/*
|
||||
* miss - handle a cache miss
|
||||
- miss - handle a cache miss
|
||||
^ static struct sset *miss(struct vars *, struct dfa *, struct sset *,
|
||||
^ pcolor, chr *, chr *);
|
||||
*/
|
||||
static struct sset * /* NULL if goes to empty set */
|
||||
miss(struct vars * v, /* used only for debug flags */
|
||||
struct dfa * d,
|
||||
struct sset * css,
|
||||
pcolor co,
|
||||
chr *cp, /* next chr */
|
||||
chr *start) /* where the attempt got started */
|
||||
miss(v, d, css, co, cp, start)
|
||||
struct vars *v; /* used only for debug flags */
|
||||
struct dfa *d;
|
||||
struct sset *css;
|
||||
pcolor co;
|
||||
chr *cp; /* next chr */
|
||||
chr *start; /* where the attempt got started */
|
||||
{
|
||||
struct cnfa *cnfa = d->cnfa;
|
||||
int i;
|
||||
@@ -445,8 +432,7 @@ miss(struct vars * v, /* used only for debug flags */
|
||||
int sawlacons;
|
||||
|
||||
/* for convenience, we can be called even if it might not be a miss */
|
||||
if (css->outs[co] != NULL)
|
||||
{
|
||||
if (css->outs[co] != NULL) {
|
||||
FDEBUG(("hit\n"));
|
||||
return css->outs[co];
|
||||
}
|
||||
@@ -461,8 +447,7 @@ miss(struct vars * v, /* used only for debug flags */
|
||||
for (i = 0; i < d->nstates; i++)
|
||||
if (ISBSET(css->states, i))
|
||||
for (ca = cnfa->states[i]+1; ca->co != COLORLESS; ca++)
|
||||
if (ca->co == co)
|
||||
{
|
||||
if (ca->co == co) {
|
||||
BSET(d->work, ca->to);
|
||||
gotstate = 1;
|
||||
if (ca->to == cnfa->post)
|
||||
@@ -473,14 +458,12 @@ miss(struct vars * v, /* used only for debug flags */
|
||||
}
|
||||
dolacons = (gotstate) ? (cnfa->flags&HASLACONS) : 0;
|
||||
sawlacons = 0;
|
||||
while (dolacons)
|
||||
{ /* transitive closure */
|
||||
while (dolacons) { /* transitive closure */
|
||||
dolacons = 0;
|
||||
for (i = 0; i < d->nstates; i++)
|
||||
if (ISBSET(d->work, i))
|
||||
for (ca = cnfa->states[i]+1; ca->co != COLORLESS;
|
||||
ca++)
|
||||
{
|
||||
ca++) {
|
||||
if (ca->co <= cnfa->ncolors)
|
||||
continue; /* NOTE CONTINUE */
|
||||
sawlacons = 1;
|
||||
@@ -503,13 +486,11 @@ miss(struct vars * v, /* used only for debug flags */
|
||||
|
||||
/* next, is that in the cache? */
|
||||
for (p = d->ssets, i = d->nssused; i > 0; p++, i--)
|
||||
if (HIT(h, d->work, p, d->wordsper))
|
||||
{
|
||||
if (HIT(h, d->work, p, d->wordsper)) {
|
||||
FDEBUG(("cached c%d\n", p - d->ssets));
|
||||
break; /* NOTE BREAK OUT */
|
||||
}
|
||||
if (i == 0)
|
||||
{ /* nope, need a new cache entry */
|
||||
if (i == 0) { /* nope, need a new cache entry */
|
||||
p = getvacant(v, d, cp, start);
|
||||
assert(p != css);
|
||||
for (i = 0; i < d->wordsper; i++)
|
||||
@@ -521,8 +502,7 @@ miss(struct vars * v, /* used only for debug flags */
|
||||
/* lastseen to be dealt with by caller */
|
||||
}
|
||||
|
||||
if (!sawlacons)
|
||||
{ /* lookahead conds. always cache miss */
|
||||
if (!sawlacons) { /* lookahead conds. always cache miss */
|
||||
FDEBUG(("c%d[%d]->c%d\n", css - d->ssets, co, p - d->ssets));
|
||||
css->outs[co] = p;
|
||||
css->inchain[co] = p->ins;
|
||||
@@ -533,13 +513,15 @@ miss(struct vars * v, /* used only for debug flags */
|
||||
}
|
||||
|
||||
/*
|
||||
* lacon - lookahead-constraint checker for miss()
|
||||
- lacon - lookahead-constraint checker for miss()
|
||||
^ static int lacon(struct vars *, struct cnfa *, chr *, pcolor);
|
||||
*/
|
||||
static int /* predicate: constraint satisfied? */
|
||||
lacon(struct vars * v,
|
||||
struct cnfa * pcnfa, /* parent cnfa */
|
||||
chr *cp,
|
||||
pcolor co) /* "color" of the lookahead constraint */
|
||||
lacon(v, pcnfa, cp, co)
|
||||
struct vars *v;
|
||||
struct cnfa *pcnfa; /* parent cnfa */
|
||||
chr *cp;
|
||||
pcolor co; /* "color" of the lookahead constraint */
|
||||
{
|
||||
int n;
|
||||
struct subre *sub;
|
||||
@@ -552,8 +534,7 @@ lacon(struct vars * v,
|
||||
FDEBUG(("=== testing lacon %d\n", n));
|
||||
sub = &v->g->lacons[n];
|
||||
d = newdfa(v, &sub->cnfa, &v->g->cmap, &sd);
|
||||
if (d == NULL)
|
||||
{
|
||||
if (d == NULL) {
|
||||
ERR(REG_ESPACE);
|
||||
return 0;
|
||||
}
|
||||
@@ -564,15 +545,17 @@ lacon(struct vars * v,
|
||||
}
|
||||
|
||||
/*
|
||||
* getvacant - get a vacant state set
|
||||
- getvacant - get a vacant state set
|
||||
* This routine clears out the inarcs and outarcs, but does not otherwise
|
||||
* clear the innards of the state set -- that's up to the caller.
|
||||
^ static struct sset *getvacant(struct vars *, struct dfa *, chr *, chr *);
|
||||
*/
|
||||
static struct sset *
|
||||
getvacant(struct vars * v, /* used only for debug flags */
|
||||
struct dfa * d,
|
||||
chr *cp,
|
||||
chr *start)
|
||||
getvacant(v, d, cp, start)
|
||||
struct vars *v; /* used only for debug flags */
|
||||
struct dfa *d;
|
||||
chr *cp;
|
||||
chr *start;
|
||||
{
|
||||
int i;
|
||||
struct sset *ss;
|
||||
@@ -586,8 +569,7 @@ getvacant(struct vars * v, /* used only for debug flags */
|
||||
|
||||
/* clear out its inarcs, including self-referential ones */
|
||||
ap = ss->ins;
|
||||
while ((p = ap.ss) != NULL)
|
||||
{
|
||||
while ((p = ap.ss) != NULL) {
|
||||
co = ap.co;
|
||||
FDEBUG(("zapping c%d's %ld outarc\n", p - d->ssets, (long)co));
|
||||
p->outs[co] = NULL;
|
||||
@@ -597,8 +579,7 @@ getvacant(struct vars * v, /* used only for debug flags */
|
||||
ss->ins.ss = NULL;
|
||||
|
||||
/* take it off the inarc chains of the ssets reached by its outarcs */
|
||||
for (i = 0; i < d->ncolors; i++)
|
||||
{
|
||||
for (i = 0; i < d->ncolors; i++) {
|
||||
p = ss->outs[i];
|
||||
assert(p != ss); /* not self-referential */
|
||||
if (p == NULL)
|
||||
@@ -606,8 +587,7 @@ getvacant(struct vars * v, /* used only for debug flags */
|
||||
FDEBUG(("del outarc %d from c%d's in chn\n", i, p - d->ssets));
|
||||
if (p->ins.ss == ss && p->ins.co == i)
|
||||
p->ins = ss->inchain[i];
|
||||
else
|
||||
{
|
||||
else {
|
||||
assert(p->ins.ss != NULL);
|
||||
for (ap = p->ins; ap.ss != NULL &&
|
||||
!(ap.ss == ss && ap.co == i);
|
||||
@@ -634,13 +614,15 @@ getvacant(struct vars * v, /* used only for debug flags */
|
||||
}
|
||||
|
||||
/*
|
||||
* pickss - pick the next stateset to be used
|
||||
- pickss - pick the next stateset to be used
|
||||
^ static struct sset *pickss(struct vars *, struct dfa *, chr *, chr *);
|
||||
*/
|
||||
static struct sset *
|
||||
pickss(struct vars * v, /* used only for debug flags */
|
||||
struct dfa * d,
|
||||
chr *cp,
|
||||
chr *start)
|
||||
pickss(v, d, cp, start)
|
||||
struct vars *v; /* used only for debug flags */
|
||||
struct dfa *d;
|
||||
chr *cp;
|
||||
chr *start;
|
||||
{
|
||||
int i;
|
||||
struct sset *ss;
|
||||
@@ -648,8 +630,7 @@ pickss(struct vars * v, /* used only for debug flags */
|
||||
chr *ancient;
|
||||
|
||||
/* shortcut for cases where cache isn't full */
|
||||
if (d->nssused < d->nssets)
|
||||
{
|
||||
if (d->nssused < d->nssets) {
|
||||
i = d->nssused;
|
||||
d->nssused++;
|
||||
ss = &d->ssets[i];
|
||||
@@ -661,8 +642,7 @@ pickss(struct vars * v, /* used only for debug flags */
|
||||
ss->ins.co = WHITE; /* give it some value */
|
||||
ss->outs = &d->outsarea[i * d->ncolors];
|
||||
ss->inchain = &d->incarea[i * d->ncolors];
|
||||
for (i = 0; i < d->ncolors; i++)
|
||||
{
|
||||
for (i = 0; i < d->ncolors; i++) {
|
||||
ss->outs[i] = NULL;
|
||||
ss->inchain[i].ss = NULL;
|
||||
}
|
||||
@@ -676,16 +656,14 @@ pickss(struct vars * v, /* used only for debug flags */
|
||||
ancient = start;
|
||||
for (ss = d->search, end = &d->ssets[d->nssets]; ss < end; ss++)
|
||||
if ((ss->lastseen == NULL || ss->lastseen < ancient) &&
|
||||
!(ss->flags & LOCKED))
|
||||
{
|
||||
!(ss->flags&LOCKED)) {
|
||||
d->search = ss + 1;
|
||||
FDEBUG(("replacing c%d\n", ss - d->ssets));
|
||||
return ss;
|
||||
}
|
||||
for (ss = d->ssets, end = d->search; ss < end; ss++)
|
||||
if ((ss->lastseen == NULL || ss->lastseen < ancient) &&
|
||||
!(ss->flags & LOCKED))
|
||||
{
|
||||
!(ss->flags&LOCKED)) {
|
||||
d->search = ss + 1;
|
||||
FDEBUG(("replacing c%d\n", ss - d->ssets));
|
||||
return ss;
|
||||
|
||||
@@ -27,8 +27,6 @@
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $Header: /projects/cvsroot/pgsql-server/src/backend/regex/regerror.c,v 1.26 2003/08/04 00:43:21 momjian Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
#include "regguts.h"
|
||||
@@ -37,36 +35,26 @@
|
||||
static char unk[] = "*** unknown regex error code 0x%x ***";
|
||||
|
||||
/* struct to map among codes, code names, and explanations */
|
||||
static struct rerr
|
||||
{
|
||||
static struct rerr {
|
||||
int code;
|
||||
char *name;
|
||||
char *explain;
|
||||
} rerrs[] =
|
||||
|
||||
{
|
||||
} rerrs[] = {
|
||||
/* the actual table is built from regex.h */
|
||||
# include "regerrs.h"
|
||||
{
|
||||
-1, "", "oops"
|
||||
}, /* explanation special-cased in code */
|
||||
{ -1, "", "oops" }, /* explanation special-cased in code */
|
||||
};
|
||||
|
||||
size_t
|
||||
regerror(int errcode, /* error code, or REG_ATOI or REG_ITOA */
|
||||
const regex_t *preg, /* associated regex_t (unused at present) */
|
||||
char *errbuf, /* result buffer (unless errbuf_size==0) */
|
||||
size_t errbuf_size) /* available space in errbuf, can be 0 */
|
||||
{ return wx_regerror(errcode, preg, errbuf, errbuf_size); }
|
||||
/*
|
||||
* pg_regerror - the interface to error numbers
|
||||
- regerror - the interface to error numbers
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
size_t /* actual space needed (including NUL) */
|
||||
wx_regerror(int errcode, /* error code, or REG_ATOI or REG_ITOA */
|
||||
const regex_t *preg, /* associated regex_t (unused at present) */
|
||||
char *errbuf, /* result buffer (unless errbuf_size==0) */
|
||||
size_t errbuf_size) /* available space in errbuf, can be 0 */
|
||||
regerror(errcode, preg, errbuf, errbuf_size)
|
||||
int errcode; /* error code, or REG_ATOI or REG_ITOA */
|
||||
CONST regex_t *preg; /* associated regex_t (unused at present) */
|
||||
char *errbuf; /* result buffer (unless errbuf_size==0) */
|
||||
size_t errbuf_size; /* available space in errbuf, can be 0 */
|
||||
{
|
||||
struct rerr *r;
|
||||
char *msg;
|
||||
@@ -74,8 +62,7 @@ wx_regerror(int errcode, /* error code, or REG_ATOI or REG_ITOA */
|
||||
size_t len;
|
||||
int icode;
|
||||
|
||||
switch (errcode)
|
||||
{
|
||||
switch (errcode) {
|
||||
case REG_ATOI: /* convert name to number */
|
||||
for (r = rerrs; r->code >= 0; r++)
|
||||
if (strcmp(r->name, errbuf) == 0)
|
||||
@@ -90,8 +77,7 @@ wx_regerror(int errcode, /* error code, or REG_ATOI or REG_ITOA */
|
||||
break;
|
||||
if (r->code >= 0)
|
||||
msg = r->name;
|
||||
else
|
||||
{ /* unknown; tell him the number */
|
||||
else { /* unknown; tell him the number */
|
||||
sprintf(convbuf, "REG_%u", (unsigned)icode);
|
||||
msg = convbuf;
|
||||
}
|
||||
@@ -102,8 +88,7 @@ wx_regerror(int errcode, /* error code, or REG_ATOI or REG_ITOA */
|
||||
break;
|
||||
if (r->code >= 0)
|
||||
msg = r->explain;
|
||||
else
|
||||
{ /* unknown; say so */
|
||||
else { /* unknown; say so */
|
||||
sprintf(convbuf, unk, errcode);
|
||||
msg = convbuf;
|
||||
}
|
||||
@@ -111,13 +96,11 @@ wx_regerror(int errcode, /* error code, or REG_ATOI or REG_ITOA */
|
||||
}
|
||||
|
||||
len = strlen(msg) + 1; /* space needed, including NUL */
|
||||
if (errbuf_size > 0)
|
||||
{
|
||||
if (errbuf_size > 0) {
|
||||
if (errbuf_size > len)
|
||||
strcpy(errbuf, msg);
|
||||
else
|
||||
{ /* truncate to fit */
|
||||
memcpy(errbuf, msg, errbuf_size - 1); /*RN - was strncpy*/
|
||||
else { /* truncate to fit */
|
||||
strncpy(errbuf, msg, errbuf_size-1);
|
||||
errbuf[errbuf_size-1] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,75 +1,18 @@
|
||||
/*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
{
|
||||
REG_OKAY, "REG_OKAY", "no errors detected"
|
||||
},
|
||||
|
||||
{
|
||||
REG_NOMATCH, "REG_NOMATCH", "failed to match"
|
||||
},
|
||||
|
||||
{
|
||||
REG_BADPAT, "REG_BADPAT", "invalid regexp (reg version 0.8)"
|
||||
},
|
||||
|
||||
{
|
||||
REG_ECOLLATE, "REG_ECOLLATE", "invalid collating element"
|
||||
},
|
||||
|
||||
{
|
||||
REG_ECTYPE, "REG_ECTYPE", "invalid character class"
|
||||
},
|
||||
|
||||
{
|
||||
REG_EESCAPE, "REG_EESCAPE", "invalid escape \\ sequence"
|
||||
},
|
||||
|
||||
{
|
||||
REG_ESUBREG, "REG_ESUBREG", "invalid backreference number"
|
||||
},
|
||||
|
||||
{
|
||||
REG_EBRACK, "REG_EBRACK", "brackets [] not balanced"
|
||||
},
|
||||
|
||||
{
|
||||
REG_EPAREN, "REG_EPAREN", "parentheses () not balanced"
|
||||
},
|
||||
|
||||
{
|
||||
REG_EBRACE, "REG_EBRACE", "braces {} not balanced"
|
||||
},
|
||||
|
||||
{
|
||||
REG_BADBR, "REG_BADBR", "invalid repetition count(s)"
|
||||
},
|
||||
|
||||
{
|
||||
REG_ERANGE, "REG_ERANGE", "invalid character range"
|
||||
},
|
||||
|
||||
{
|
||||
REG_ESPACE, "REG_ESPACE", "out of memory"
|
||||
},
|
||||
|
||||
{
|
||||
REG_BADRPT, "REG_BADRPT", "quantifier operand invalid"
|
||||
},
|
||||
|
||||
{
|
||||
REG_ASSERT, "REG_ASSERT", "\"can't happen\" -- you found a bug"
|
||||
},
|
||||
|
||||
{
|
||||
REG_INVARG, "REG_INVARG", "invalid argument to regex function"
|
||||
},
|
||||
|
||||
{
|
||||
REG_MIXED, "REG_MIXED", "character widths of regex and string differ"
|
||||
},
|
||||
|
||||
{
|
||||
REG_BADOPT, "REG_BADOPT", "invalid embedded option"
|
||||
},
|
||||
{ REG_OKAY, "REG_OKAY", "no errors detected" },
|
||||
{ REG_NOMATCH, "REG_NOMATCH", "failed to match" },
|
||||
{ REG_BADPAT, "REG_BADPAT", "invalid regexp (reg version 0.8)" },
|
||||
{ REG_ECOLLATE, "REG_ECOLLATE", "invalid collating element" },
|
||||
{ REG_ECTYPE, "REG_ECTYPE", "invalid character class" },
|
||||
{ REG_EESCAPE, "REG_EESCAPE", "invalid escape \\ sequence" },
|
||||
{ REG_ESUBREG, "REG_ESUBREG", "invalid backreference number" },
|
||||
{ REG_EBRACK, "REG_EBRACK", "brackets [] not balanced" },
|
||||
{ REG_EPAREN, "REG_EPAREN", "parentheses () not balanced" },
|
||||
{ REG_EBRACE, "REG_EBRACE", "braces {} not balanced" },
|
||||
{ REG_BADBR, "REG_BADBR", "invalid repetition count(s)" },
|
||||
{ REG_ERANGE, "REG_ERANGE", "invalid character range" },
|
||||
{ REG_ESPACE, "REG_ESPACE", "out of memory" },
|
||||
{ REG_BADRPT, "REG_BADRPT", "quantifier operand invalid" },
|
||||
{ REG_ASSERT, "REG_ASSERT", "\"can't happen\" -- you found a bug" },
|
||||
{ REG_INVARG, "REG_INVARG", "invalid argument to regex function" },
|
||||
{ REG_MIXED, "REG_MIXED", "character widths of regex and string differ" },
|
||||
{ REG_BADOPT, "REG_BADOPT", "invalid embedded option" },
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#ifndef _REGEX_H_
|
||||
#define _REGEX_H_ /* never again */
|
||||
|
||||
/*
|
||||
* regular expressions
|
||||
*
|
||||
@@ -30,35 +29,98 @@
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
*
|
||||
* Prototypes etc. marked with "^" within comments get gathered up (and
|
||||
* possibly edited) by the regfwd program and inserted near the bottom of
|
||||
* this file.
|
||||
*
|
||||
* We offer the option of declaring one wide-character version of the
|
||||
* RE functions as well as the char versions. To do that, define
|
||||
* __REG_WIDE_T to the type of wide characters (unfortunately, there
|
||||
* is no consensus that wchar_t is suitable) and __REG_WIDE_COMPILE and
|
||||
* __REG_WIDE_EXEC to the names to be used for the compile and execute
|
||||
* functions (suggestion: re_Xcomp and re_Xexec, where X is a letter
|
||||
* suggestive of the wide type, e.g. re_ucomp and re_uexec for Unicode).
|
||||
* For cranky old compilers, it may be necessary to do something like:
|
||||
* #define __REG_WIDE_COMPILE(a,b,c,d) re_Xcomp(a,b,c,d)
|
||||
* #define __REG_WIDE_EXEC(a,b,c,d,e,f,g) re_Xexec(a,b,c,d,e,f,g)
|
||||
* rather than just #defining the names as parameterless macros.
|
||||
*
|
||||
* For some specialized purposes, it may be desirable to suppress the
|
||||
* declarations of the "front end" functions, regcomp() and regexec(),
|
||||
* or of the char versions of the compile and execute functions. To
|
||||
* suppress the front-end functions, define __REG_NOFRONT. To suppress
|
||||
* the char versions, define __REG_NOCHAR.
|
||||
*
|
||||
* The right place to do those defines (and some others you may want, see
|
||||
* below) would be <sys/types.h>. If you don't have control of that file,
|
||||
* the right place to add your own defines to this file is marked below.
|
||||
* This is normally done automatically, by the makefile and regmkhdr, based
|
||||
* on the contents of regcustom.h.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Add your own defines, if needed, here.
|
||||
* voodoo for C++
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*****************************
|
||||
WXWINDOWS CUSTOM
|
||||
*****************************/
|
||||
#ifndef _REGEX_CUSTOM_H_
|
||||
# define wx_wchar wxChar
|
||||
/* FreeBSD, Watcom and DMars require this, CW doesn't have nor need it. */
|
||||
/* Others also don't seem to need it. If you have an error related to */
|
||||
/* (not) including <sys/types.h> please report details to */
|
||||
/* wx-dev@lists.wxwindows.org */
|
||||
# if defined(__UNIX__) || defined(__WATCOMC__) || defined(__DIGITALMARS__)
|
||||
# include <sys/types.h>
|
||||
# endif
|
||||
#endif /* ndef _REGEX_CUSTOM_H_ */
|
||||
/*****************************
|
||||
END WXWINDOWS CUSTOM
|
||||
*****************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/*
|
||||
* Add your own defines, if needed, here.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Location where a chunk of regcustom.h is automatically spliced into
|
||||
* this file (working from its prototype, regproto.h).
|
||||
*/
|
||||
/* --- begin --- */
|
||||
/* ensure certain things don't sneak in from system headers */
|
||||
#ifdef __REG_WIDE_T
|
||||
#undef __REG_WIDE_T
|
||||
#endif
|
||||
#ifdef __REG_WIDE_COMPILE
|
||||
#undef __REG_WIDE_COMPILE
|
||||
#endif
|
||||
#ifdef __REG_WIDE_EXEC
|
||||
#undef __REG_WIDE_EXEC
|
||||
#endif
|
||||
#ifdef __REG_REGOFF_T
|
||||
#undef __REG_REGOFF_T
|
||||
#endif
|
||||
#ifdef __REG_VOID_T
|
||||
#undef __REG_VOID_T
|
||||
#endif
|
||||
#ifdef __REG_CONST
|
||||
#undef __REG_CONST
|
||||
#endif
|
||||
#ifdef __REG_NOFRONT
|
||||
#undef __REG_NOFRONT
|
||||
#endif
|
||||
#ifdef __REG_NOCHAR
|
||||
#undef __REG_NOCHAR
|
||||
#endif
|
||||
/* interface types */
|
||||
#define __REG_WIDE_T Tcl_UniChar
|
||||
#define __REG_REGOFF_T long /* not really right, but good enough... */
|
||||
#define __REG_VOID_T VOID
|
||||
#define __REG_CONST CONST
|
||||
/* names and declarations */
|
||||
#define __REG_WIDE_COMPILE TclReComp
|
||||
#define __REG_WIDE_EXEC TclReExec
|
||||
#define __REG_NOFRONT /* don't want regcomp() and regexec() */
|
||||
#define __REG_NOCHAR /* or the char versions */
|
||||
#define regfree TclReFree
|
||||
#define regerror TclReError
|
||||
/* --- end --- */
|
||||
|
||||
|
||||
/*
|
||||
* interface types etc.
|
||||
@@ -66,17 +128,41 @@ extern "C" {
|
||||
|
||||
/*
|
||||
* regoff_t has to be large enough to hold either off_t or ssize_t,
|
||||
* and must be signed; it's only a guess that long is suitable.
|
||||
* and must be signed; it's only a guess that long is suitable, so we
|
||||
* offer <sys/types.h> an override.
|
||||
*/
|
||||
#ifdef __REG_REGOFF_T
|
||||
typedef __REG_REGOFF_T regoff_t;
|
||||
#else
|
||||
typedef long regoff_t;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* For benefit of old compilers, we offer <sys/types.h> the option of
|
||||
* overriding the `void' type used to declare nonexistent return types.
|
||||
*/
|
||||
#ifdef __REG_VOID_T
|
||||
typedef __REG_VOID_T re_void;
|
||||
#else
|
||||
typedef void re_void;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Also for benefit of old compilers, <sys/types.h> can supply a macro
|
||||
* which expands to a substitute for `const'.
|
||||
*/
|
||||
#ifndef __REG_CONST
|
||||
#define __REG_CONST const
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* other interface types
|
||||
*/
|
||||
|
||||
/* the biggie, a compiled RE (or rather, a front end to same) */
|
||||
typedef struct
|
||||
{
|
||||
typedef struct {
|
||||
int re_magic; /* magic number */
|
||||
size_t re_nsub; /* number of subexpressions */
|
||||
long re_info; /* information about RE */
|
||||
@@ -102,22 +188,29 @@ typedef struct
|
||||
} regex_t;
|
||||
|
||||
/* result reporting (may acquire more fields later) */
|
||||
typedef struct
|
||||
{
|
||||
typedef struct {
|
||||
regoff_t rm_so; /* start of substring */
|
||||
regoff_t rm_eo; /* end of substring */
|
||||
} regmatch_t;
|
||||
|
||||
/* supplementary control and reporting */
|
||||
typedef struct
|
||||
{
|
||||
typedef struct {
|
||||
regmatch_t rm_extend; /* see REG_EXPECT */
|
||||
} rm_detail_t;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* regex compilation flags
|
||||
* compilation
|
||||
^ #ifndef __REG_NOCHAR
|
||||
^ int re_comp(regex_t *, __REG_CONST char *, size_t, int);
|
||||
^ #endif
|
||||
^ #ifndef __REG_NOFRONT
|
||||
^ int regcomp(regex_t *, __REG_CONST char *, int);
|
||||
^ #endif
|
||||
^ #ifdef __REG_WIDE_T
|
||||
^ int __REG_WIDE_COMPILE(regex_t *, __REG_CONST __REG_WIDE_T *, size_t, int);
|
||||
^ #endif
|
||||
*/
|
||||
#define REG_BASIC 000000 /* BREs (convenience) */
|
||||
#define REG_EXTENDED 000001 /* EREs */
|
||||
@@ -132,8 +225,7 @@ typedef struct
|
||||
#define REG_NLANCH 000200 /* ^ matches after \n, $ before */
|
||||
#define REG_NEWLINE 000300 /* newlines are line terminators */
|
||||
#define REG_PEND 000400 /* ugh -- backward-compatibility hack */
|
||||
#define REG_EXPECT 001000 /* report details on partial/limited
|
||||
* matches */
|
||||
#define REG_EXPECT 001000 /* report details on partial/limited matches */
|
||||
#define REG_BOSONLY 002000 /* temporary kludge for BOS-only matches */
|
||||
#define REG_DUMP 004000 /* none of your business :-) */
|
||||
#define REG_FAKE 010000 /* none of your business :-) */
|
||||
@@ -142,7 +234,18 @@ typedef struct
|
||||
|
||||
|
||||
/*
|
||||
* regex execution flags
|
||||
* execution
|
||||
^ #ifndef __REG_NOCHAR
|
||||
^ int re_exec(regex_t *, __REG_CONST char *, size_t,
|
||||
^ rm_detail_t *, size_t, regmatch_t [], int);
|
||||
^ #endif
|
||||
^ #ifndef __REG_NOFRONT
|
||||
^ int regexec(regex_t *, __REG_CONST char *, size_t, regmatch_t [], int);
|
||||
^ #endif
|
||||
^ #ifdef __REG_WIDE_T
|
||||
^ int __REG_WIDE_EXEC(regex_t *, __REG_CONST __REG_WIDE_T *, size_t,
|
||||
^ rm_detail_t *, size_t, regmatch_t [], int);
|
||||
^ #endif
|
||||
*/
|
||||
#define REG_NOTBOL 0001 /* BOS is not BOL */
|
||||
#define REG_NOTEOL 0002 /* EOS is not EOL */
|
||||
@@ -152,10 +255,24 @@ typedef struct
|
||||
#define REG_SMALL 0040 /* none of your business */
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* misc generics (may be more functions here eventually)
|
||||
^ re_void regfree(regex_t *);
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* error reporting
|
||||
* Be careful if modifying the list of error codes -- the table used by
|
||||
* regerror() is generated automatically from this file!
|
||||
*
|
||||
* Note that there is no wide-char variant of regerror at this time; what
|
||||
* kind of character is used for error reports is independent of what kind
|
||||
* is used in matching.
|
||||
*
|
||||
^ extern size_t regerror(int, __REG_CONST regex_t *, char *, size_t);
|
||||
*/
|
||||
#define REG_OKAY 0 /* no errors detected */
|
||||
#define REG_NOMATCH 1 /* failed to match */
|
||||
@@ -173,8 +290,7 @@ typedef struct
|
||||
#define REG_BADRPT 13 /* quantifier operand invalid */
|
||||
#define REG_ASSERT 15 /* "can't happen" -- you found a bug */
|
||||
#define REG_INVARG 16 /* invalid argument to regex function */
|
||||
#define REG_MIXED 17 /* character widths of regex and string
|
||||
* differ */
|
||||
#define REG_MIXED 17 /* character widths of regex and string differ */
|
||||
#define REG_BADOPT 18 /* invalid embedded option */
|
||||
/* two specials for debugging and testing */
|
||||
#define REG_ATOI 101 /* convert error-code name to number */
|
||||
@@ -183,19 +299,43 @@ typedef struct
|
||||
|
||||
|
||||
/*
|
||||
* the prototypes for exported functions
|
||||
* the prototypes, as possibly munched by regfwd
|
||||
*/
|
||||
extern int wx_regcomp(regex_t *, const wx_wchar *, size_t, int);
|
||||
extern int regcomp(regex_t *, const wx_wchar *, int);
|
||||
extern int wx_regexec(regex_t *, const wx_wchar *, size_t, rm_detail_t *, size_t, regmatch_t[], int);
|
||||
extern int regexec(regex_t *, const wx_wchar *, size_t, regmatch_t[], int);
|
||||
extern void regfree(regex_t *);
|
||||
extern size_t regerror(int, const regex_t *, char *, size_t);
|
||||
extern void wx_regfree(regex_t *);
|
||||
extern size_t wx_regerror(int, const regex_t *, char *, size_t);
|
||||
/* =====^!^===== begin forwards =====^!^===== */
|
||||
/* automatically gathered by fwd; do not hand-edit */
|
||||
/* === regproto.h === */
|
||||
#ifndef __REG_NOCHAR
|
||||
int re_comp _ANSI_ARGS_((regex_t *, __REG_CONST char *, size_t, int));
|
||||
#endif
|
||||
#ifndef __REG_NOFRONT
|
||||
int regcomp _ANSI_ARGS_((regex_t *, __REG_CONST char *, int));
|
||||
#endif
|
||||
#ifdef __REG_WIDE_T
|
||||
int __REG_WIDE_COMPILE _ANSI_ARGS_((regex_t *, __REG_CONST __REG_WIDE_T *, size_t, int));
|
||||
#endif
|
||||
#ifndef __REG_NOCHAR
|
||||
int re_exec _ANSI_ARGS_((regex_t *, __REG_CONST char *, size_t, rm_detail_t *, size_t, regmatch_t [], int));
|
||||
#endif
|
||||
#ifndef __REG_NOFRONT
|
||||
int regexec _ANSI_ARGS_((regex_t *, __REG_CONST char *, size_t, regmatch_t [], int));
|
||||
#endif
|
||||
#ifdef __REG_WIDE_T
|
||||
int __REG_WIDE_EXEC _ANSI_ARGS_((regex_t *, __REG_CONST __REG_WIDE_T *, size_t, rm_detail_t *, size_t, regmatch_t [], int));
|
||||
#endif
|
||||
re_void regfree _ANSI_ARGS_((regex_t *));
|
||||
extern size_t regerror _ANSI_ARGS_((int, __REG_CONST regex_t *, char *, size_t));
|
||||
/* automatically gathered by fwd; do not hand-edit */
|
||||
/* =====^!^===== end forwards =====^!^===== */
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* more C++ voodoo
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _REGEX_H_ */
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -27,8 +27,6 @@
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $Header: /projects/cvsroot/pgsql-server/src/backend/regex/regexec.c,v 1.23 2003/08/08 21:41:56 momjian Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
#include "regguts.h"
|
||||
@@ -36,14 +34,12 @@
|
||||
|
||||
|
||||
/* lazy-DFA representation */
|
||||
struct arcp
|
||||
{ /* "pointer" to an outarc */
|
||||
struct arcp { /* "pointer" to an outarc */
|
||||
struct sset *ss;
|
||||
color co;
|
||||
};
|
||||
|
||||
struct sset
|
||||
{ /* state set */
|
||||
struct sset { /* state set */
|
||||
unsigned *states; /* pointer to bitvector */
|
||||
unsigned hash; /* hash of bitvector */
|
||||
# define HASH(bv, nw) (((nw) == 1) ? *(bv) : hash(bv, nw))
|
||||
@@ -60,8 +56,7 @@ struct sset
|
||||
struct arcp *inchain; /* chain-pointer vector for outarcs */
|
||||
};
|
||||
|
||||
struct dfa
|
||||
{
|
||||
struct dfa {
|
||||
int nssets; /* size of cache */
|
||||
int nssused; /* how many entries occupied yet */
|
||||
int nstates; /* number of states */
|
||||
@@ -75,8 +70,7 @@ struct dfa
|
||||
struct cnfa *cnfa;
|
||||
struct colormap *cm;
|
||||
chr *lastpost; /* location of last cache-flushed success */
|
||||
chr *lastnopr; /* location of last cache-flushed
|
||||
* NOPROGRESS */
|
||||
chr *lastnopr; /* location of last cache-flushed NOPROGRESS */
|
||||
struct sset *search; /* replacement-search-pointer memory */
|
||||
int cptsmalloced; /* were the areas individually malloced? */
|
||||
char *mallocarea; /* self, or master malloced area, or NULL */
|
||||
@@ -87,22 +81,19 @@ struct dfa
|
||||
/* setup for non-malloc allocation for small cases */
|
||||
#define FEWSTATES 20 /* must be less than UBITS */
|
||||
#define FEWCOLORS 15
|
||||
struct smalldfa
|
||||
{
|
||||
struct smalldfa {
|
||||
struct dfa dfa;
|
||||
struct sset ssets[FEWSTATES*2];
|
||||
unsigned statesarea[FEWSTATES*2 + WORK];
|
||||
struct sset *outsarea[FEWSTATES*2 * FEWCOLORS];
|
||||
struct arcp incarea[FEWSTATES*2 * FEWCOLORS];
|
||||
};
|
||||
|
||||
#define DOMALLOC ((struct smalldfa *)NULL) /* force malloc */
|
||||
|
||||
|
||||
|
||||
/* internal variables, bundled for easy passing around */
|
||||
struct vars
|
||||
{
|
||||
struct vars {
|
||||
regex_t *re;
|
||||
struct guts *g;
|
||||
int eflags; /* copies of arguments */
|
||||
@@ -116,13 +107,11 @@ struct vars
|
||||
struct smalldfa dfa1;
|
||||
struct smalldfa dfa2;
|
||||
};
|
||||
|
||||
#define VISERR(vv) ((vv)->err != 0) /* have we seen an error yet? */
|
||||
#define ISERR() VISERR(v)
|
||||
#define VERR(vv,e) (((vv)->err) ? (vv)->err : ((vv)->err = (e)))
|
||||
#define ERR(e) VERR(v, e) /* record an error */
|
||||
#define NOERR() {if (ISERR()) return v->err;} /* if error seen, return
|
||||
* it */
|
||||
#define NOERR() {if (ISERR()) return v->err;} /* if error seen, return it */
|
||||
#define OFF(p) ((p) - v->start)
|
||||
#define LOFF(p) ((long)OFF(p))
|
||||
|
||||
@@ -131,67 +120,63 @@ struct vars
|
||||
/*
|
||||
* forward declarations
|
||||
*/
|
||||
/* =====^!^===== begin forwards =====^!^===== */
|
||||
/* automatically gathered by fwd; do not hand-edit */
|
||||
/* === regexec.c === */
|
||||
static int find(struct vars *, struct cnfa *, struct colormap *);
|
||||
static int cfind(struct vars *, struct cnfa *, struct colormap *);
|
||||
static int cfindloop(struct vars *, struct cnfa *, struct colormap *, struct dfa *, struct dfa *, chr **);
|
||||
static void zapsubs(regmatch_t *, size_t);
|
||||
static void zapmem(struct vars *, struct subre *);
|
||||
static void subset(struct vars *, struct subre *, chr *, chr *);
|
||||
static int dissect(struct vars *, struct subre *, chr *, chr *);
|
||||
static int condissect(struct vars *, struct subre *, chr *, chr *);
|
||||
static int altdissect(struct vars *, struct subre *, chr *, chr *);
|
||||
static int cdissect(struct vars *, struct subre *, chr *, chr *);
|
||||
static int ccondissect(struct vars *, struct subre *, chr *, chr *);
|
||||
static int crevdissect(struct vars *, struct subre *, chr *, chr *);
|
||||
static int cbrdissect(struct vars *, struct subre *, chr *, chr *);
|
||||
static int caltdissect(struct vars *, struct subre *, chr *, chr *);
|
||||
|
||||
int exec _ANSI_ARGS_((regex_t *, CONST chr *, size_t, rm_detail_t *, size_t, regmatch_t [], int));
|
||||
static int find _ANSI_ARGS_((struct vars *, struct cnfa *, struct colormap *));
|
||||
static int cfind _ANSI_ARGS_((struct vars *, struct cnfa *, struct colormap *));
|
||||
static int cfindloop _ANSI_ARGS_((struct vars *, struct cnfa *, struct colormap *, struct dfa *, struct dfa *, chr **));
|
||||
static VOID zapsubs _ANSI_ARGS_((regmatch_t *, size_t));
|
||||
static VOID zapmem _ANSI_ARGS_((struct vars *, struct subre *));
|
||||
static VOID subset _ANSI_ARGS_((struct vars *, struct subre *, chr *, chr *));
|
||||
static int dissect _ANSI_ARGS_((struct vars *, struct subre *, chr *, chr *));
|
||||
static int condissect _ANSI_ARGS_((struct vars *, struct subre *, chr *, chr *));
|
||||
static int altdissect _ANSI_ARGS_((struct vars *, struct subre *, chr *, chr *));
|
||||
static int cdissect _ANSI_ARGS_((struct vars *, struct subre *, chr *, chr *));
|
||||
static int ccondissect _ANSI_ARGS_((struct vars *, struct subre *, chr *, chr *));
|
||||
static int crevdissect _ANSI_ARGS_((struct vars *, struct subre *, chr *, chr *));
|
||||
static int cbrdissect _ANSI_ARGS_((struct vars *, struct subre *, chr *, chr *));
|
||||
static int caltdissect _ANSI_ARGS_((struct vars *, struct subre *, chr *, chr *));
|
||||
/* === rege_dfa.c === */
|
||||
static chr *longest(struct vars *, struct dfa *, chr *, chr *, int *);
|
||||
static chr *shortest(struct vars *, struct dfa *, chr *, chr *, chr *, chr **, int *);
|
||||
static chr *lastcold(struct vars *, struct dfa *);
|
||||
static struct dfa *newdfa(struct vars *, struct cnfa *, struct colormap *, struct smalldfa *);
|
||||
static void freedfa(struct dfa *);
|
||||
static unsigned hash(unsigned *, int);
|
||||
static struct sset *initialize(struct vars *, struct dfa *, chr *);
|
||||
static struct sset *miss(struct vars *, struct dfa *, struct sset *, pcolor, chr *, chr *);
|
||||
static int lacon(struct vars *, struct cnfa *, chr *, pcolor);
|
||||
static struct sset *getvacant(struct vars *, struct dfa *, chr *, chr *);
|
||||
static struct sset *pickss(struct vars *, struct dfa *, chr *, chr *);
|
||||
static chr *longest _ANSI_ARGS_((struct vars *, struct dfa *, chr *, chr *, int *));
|
||||
static chr *shortest _ANSI_ARGS_((struct vars *, struct dfa *, chr *, chr *, chr *, chr **, int *));
|
||||
static chr *lastcold _ANSI_ARGS_((struct vars *, struct dfa *));
|
||||
static struct dfa *newdfa _ANSI_ARGS_((struct vars *, struct cnfa *, struct colormap *, struct smalldfa *));
|
||||
static VOID freedfa _ANSI_ARGS_((struct dfa *));
|
||||
static unsigned hash _ANSI_ARGS_((unsigned *, int));
|
||||
static struct sset *initialize _ANSI_ARGS_((struct vars *, struct dfa *, chr *));
|
||||
static struct sset *miss _ANSI_ARGS_((struct vars *, struct dfa *, struct sset *, pcolor, chr *, chr *));
|
||||
static int lacon _ANSI_ARGS_((struct vars *, struct cnfa *, chr *, pcolor));
|
||||
static struct sset *getvacant _ANSI_ARGS_((struct vars *, struct dfa *, chr *, chr *));
|
||||
static struct sset *pickss _ANSI_ARGS_((struct vars *, struct dfa *, chr *, chr *));
|
||||
/* automatically gathered by fwd; do not hand-edit */
|
||||
/* =====^!^===== end forwards =====^!^===== */
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* regexec - match regular expression
|
||||
- exec - match regular expression
|
||||
^ int exec(regex_t *, CONST chr *, size_t, rm_detail_t *,
|
||||
^ size_t, regmatch_t [], int);
|
||||
*/
|
||||
int
|
||||
regexec(regex_t *re,
|
||||
const chr *string,
|
||||
size_t nmatch,
|
||||
regmatch_t pmatch[],
|
||||
int flags)
|
||||
{
|
||||
rm_detail_t det;
|
||||
return wx_regexec(re, string, wx_strlen(string), &det, nmatch, pmatch, flags);
|
||||
}
|
||||
int
|
||||
wx_regexec(regex_t *re,
|
||||
const chr *string,
|
||||
size_t len,
|
||||
rm_detail_t *details,
|
||||
size_t nmatch,
|
||||
regmatch_t pmatch[],
|
||||
int flags)
|
||||
exec(re, string, len, details, nmatch, pmatch, flags)
|
||||
regex_t *re;
|
||||
CONST chr *string;
|
||||
size_t len;
|
||||
rm_detail_t *details;
|
||||
size_t nmatch;
|
||||
regmatch_t pmatch[];
|
||||
int flags;
|
||||
{
|
||||
struct vars var;
|
||||
register struct vars *v = &var;
|
||||
int st;
|
||||
size_t n;
|
||||
int backref;
|
||||
|
||||
# define LOCALMAT 20
|
||||
regmatch_t mat[LOCALMAT];
|
||||
|
||||
# define LOCALMEM 40
|
||||
regoff_t mem[LOCALMEM];
|
||||
|
||||
@@ -213,8 +198,7 @@ wx_regexec(regex_t *re,
|
||||
if (v->g->cflags®_NOSUB)
|
||||
nmatch = 0; /* override client */
|
||||
v->nmatch = nmatch;
|
||||
if (backref)
|
||||
{
|
||||
if (backref) {
|
||||
/* need work area */
|
||||
if (v->g->nsub + 1 <= LOCALMAT)
|
||||
v->pmatch = mat;
|
||||
@@ -224,15 +208,13 @@ wx_regexec(regex_t *re,
|
||||
if (v->pmatch == NULL)
|
||||
return REG_ESPACE;
|
||||
v->nmatch = v->g->nsub + 1;
|
||||
}
|
||||
else
|
||||
} else
|
||||
v->pmatch = pmatch;
|
||||
v->details = details;
|
||||
v->start = (chr *)string;
|
||||
v->stop = (chr *)string + len;
|
||||
v->err = 0;
|
||||
if (backref)
|
||||
{
|
||||
if (backref) {
|
||||
/* need retry memory */
|
||||
assert(v->g->ntree >= 0);
|
||||
n = (size_t)v->g->ntree;
|
||||
@@ -240,14 +222,12 @@ wx_regexec(regex_t *re,
|
||||
v->mem = mem;
|
||||
else
|
||||
v->mem = (regoff_t *)MALLOC(n*sizeof(regoff_t));
|
||||
if (v->mem == NULL)
|
||||
{
|
||||
if (v->mem == NULL) {
|
||||
if (v->pmatch != pmatch && v->pmatch != mat)
|
||||
FREE(v->pmatch);
|
||||
return REG_ESPACE;
|
||||
}
|
||||
}
|
||||
else
|
||||
} else
|
||||
v->mem = NULL;
|
||||
|
||||
/* do it */
|
||||
@@ -258,8 +238,7 @@ wx_regexec(regex_t *re,
|
||||
st = find(v, &v->g->tree->cnfa, &v->g->cmap);
|
||||
|
||||
/* copy (portion of) match vector over if necessary */
|
||||
if (st == REG_OKAY && v->pmatch != pmatch && nmatch > 0)
|
||||
{
|
||||
if (st == REG_OKAY && v->pmatch != pmatch && nmatch > 0) {
|
||||
zapsubs(pmatch, nmatch);
|
||||
n = (nmatch < v->nmatch) ? nmatch : v->nmatch;
|
||||
memcpy(VS(pmatch), VS(v->pmatch), n*sizeof(regmatch_t));
|
||||
@@ -274,20 +253,21 @@ wx_regexec(regex_t *re,
|
||||
}
|
||||
|
||||
/*
|
||||
* find - find a match for the main NFA (no-complications case)
|
||||
- find - find a match for the main NFA (no-complications case)
|
||||
^ static int find(struct vars *, struct cnfa *, struct colormap *);
|
||||
*/
|
||||
static int
|
||||
find(struct vars * v,
|
||||
struct cnfa * cnfa,
|
||||
struct colormap * cm)
|
||||
find(v, cnfa, cm)
|
||||
struct vars *v;
|
||||
struct cnfa *cnfa;
|
||||
struct colormap *cm;
|
||||
{
|
||||
struct dfa *s;
|
||||
struct dfa *d;
|
||||
chr *begin;
|
||||
chr *end = NULL;
|
||||
chr *cold;
|
||||
chr *open; /* open and close of range of possible
|
||||
* starts */
|
||||
chr *open; /* open and close of range of possible starts */
|
||||
chr *close;
|
||||
int hitend;
|
||||
int shorter = (v->g->tree->flags&SHORTER) ? 1 : 0;
|
||||
@@ -301,8 +281,7 @@ find(struct vars * v,
|
||||
close = shortest(v, s, v->start, v->start, v->stop, &cold, (int *)NULL);
|
||||
freedfa(s);
|
||||
NOERR();
|
||||
if (v->g->cflags & REG_EXPECT)
|
||||
{
|
||||
if (v->g->cflags®_EXPECT) {
|
||||
assert(v->details != NULL);
|
||||
if (cold != NULL)
|
||||
v->details->rm_extend.rm_so = OFF(cold);
|
||||
@@ -323,8 +302,7 @@ find(struct vars * v,
|
||||
d = newdfa(v, cnfa, cm, &v->dfa1);
|
||||
assert(!(ISERR() && d != NULL));
|
||||
NOERR();
|
||||
for (begin = open; begin <= close; begin++)
|
||||
{
|
||||
for (begin = open; begin <= close; begin++) {
|
||||
MDEBUG(("\nfind trying at %ld\n", LOFF(begin)));
|
||||
if (shorter)
|
||||
end = shortest(v, d, begin, begin, v->stop,
|
||||
@@ -344,8 +322,7 @@ find(struct vars * v,
|
||||
assert(v->nmatch > 0);
|
||||
v->pmatch[0].rm_so = OFF(begin);
|
||||
v->pmatch[0].rm_eo = OFF(end);
|
||||
if (v->g->cflags & REG_EXPECT)
|
||||
{
|
||||
if (v->g->cflags®_EXPECT) {
|
||||
if (cold != NULL)
|
||||
v->details->rm_extend.rm_so = OFF(cold);
|
||||
else
|
||||
@@ -361,12 +338,14 @@ find(struct vars * v,
|
||||
}
|
||||
|
||||
/*
|
||||
* cfind - find a match for the main NFA (with complications)
|
||||
- cfind - find a match for the main NFA (with complications)
|
||||
^ static int cfind(struct vars *, struct cnfa *, struct colormap *);
|
||||
*/
|
||||
static int
|
||||
cfind(struct vars * v,
|
||||
struct cnfa * cnfa,
|
||||
struct colormap * cm)
|
||||
cfind(v, cnfa, cm)
|
||||
struct vars *v;
|
||||
struct cnfa *cnfa;
|
||||
struct colormap *cm;
|
||||
{
|
||||
struct dfa *s;
|
||||
struct dfa *d;
|
||||
@@ -376,8 +355,7 @@ cfind(struct vars * v,
|
||||
s = newdfa(v, &v->g->search, cm, &v->dfa1);
|
||||
NOERR();
|
||||
d = newdfa(v, cnfa, cm, &v->dfa2);
|
||||
if (ISERR())
|
||||
{
|
||||
if (ISERR()) {
|
||||
assert(d == NULL);
|
||||
freedfa(s);
|
||||
return v->err;
|
||||
@@ -388,8 +366,7 @@ cfind(struct vars * v,
|
||||
freedfa(d);
|
||||
freedfa(s);
|
||||
NOERR();
|
||||
if (v->g->cflags & REG_EXPECT)
|
||||
{
|
||||
if (v->g->cflags®_EXPECT) {
|
||||
assert(v->details != NULL);
|
||||
if (cold != NULL)
|
||||
v->details->rm_extend.rm_so = OFF(cold);
|
||||
@@ -401,21 +378,23 @@ cfind(struct vars * v,
|
||||
}
|
||||
|
||||
/*
|
||||
* cfindloop - the heart of cfind
|
||||
- cfindloop - the heart of cfind
|
||||
^ static int cfindloop(struct vars *, struct cnfa *, struct colormap *,
|
||||
^ struct dfa *, struct dfa *, chr **);
|
||||
*/
|
||||
static int
|
||||
cfindloop(struct vars * v,
|
||||
struct cnfa * cnfa,
|
||||
struct colormap * cm,
|
||||
struct dfa * d,
|
||||
struct dfa * s,
|
||||
chr **coldp) /* where to put coldstart pointer */
|
||||
cfindloop(v, cnfa, cm, d, s, coldp)
|
||||
struct vars *v;
|
||||
struct cnfa *cnfa;
|
||||
struct colormap *cm;
|
||||
struct dfa *d;
|
||||
struct dfa *s;
|
||||
chr **coldp; /* where to put coldstart pointer */
|
||||
{
|
||||
chr *begin;
|
||||
chr *end;
|
||||
chr *cold;
|
||||
chr *open; /* open and close of range of possible
|
||||
* starts */
|
||||
chr *open; /* open and close of range of possible starts */
|
||||
chr *close;
|
||||
chr *estart;
|
||||
chr *estop;
|
||||
@@ -426,8 +405,7 @@ cfindloop(struct vars * v,
|
||||
assert(d != NULL && s != NULL);
|
||||
cold = NULL;
|
||||
close = v->start;
|
||||
do
|
||||
{
|
||||
do {
|
||||
MDEBUG(("\ncsearch at %ld\n", LOFF(close)));
|
||||
close = shortest(v, s, close, close, v->stop, &cold, (int *)NULL);
|
||||
if (close == NULL)
|
||||
@@ -436,13 +414,11 @@ cfindloop(struct vars * v,
|
||||
open = cold;
|
||||
cold = NULL;
|
||||
MDEBUG(("cbetween %ld and %ld\n", LOFF(open), LOFF(close)));
|
||||
for (begin = open; begin <= close; begin++)
|
||||
{
|
||||
for (begin = open; begin <= close; begin++) {
|
||||
MDEBUG(("\ncfind trying at %ld\n", LOFF(begin)));
|
||||
estart = begin;
|
||||
estop = v->stop;
|
||||
for (;;)
|
||||
{
|
||||
for (;;) {
|
||||
if (shorter)
|
||||
end = shortest(v, d, begin, estart,
|
||||
estop, (chr **)NULL, &hitend);
|
||||
@@ -457,23 +433,19 @@ cfindloop(struct vars * v,
|
||||
zapsubs(v->pmatch, v->nmatch);
|
||||
zapmem(v, v->g->tree);
|
||||
er = cdissect(v, v->g->tree, begin, end);
|
||||
if (er == REG_OKAY)
|
||||
{
|
||||
if (v->nmatch > 0)
|
||||
{
|
||||
if (er == REG_OKAY) {
|
||||
if (v->nmatch > 0) {
|
||||
v->pmatch[0].rm_so = OFF(begin);
|
||||
v->pmatch[0].rm_eo = OFF(end);
|
||||
}
|
||||
*coldp = cold;
|
||||
return REG_OKAY;
|
||||
}
|
||||
if (er != REG_NOMATCH)
|
||||
{
|
||||
if (er != REG_NOMATCH) {
|
||||
ERR(er);
|
||||
return er;
|
||||
}
|
||||
if ((shorter) ? end == estop : end == begin)
|
||||
{
|
||||
if ((shorter) ? end == estop : end == begin) {
|
||||
/* no point in trying again */
|
||||
*coldp = cold;
|
||||
return REG_NOMATCH;
|
||||
@@ -492,35 +464,37 @@ cfindloop(struct vars * v,
|
||||
}
|
||||
|
||||
/*
|
||||
* zapsubs - initialize the subexpression matches to "no match"
|
||||
- zapsubs - initialize the subexpression matches to "no match"
|
||||
^ static VOID zapsubs(regmatch_t *, size_t);
|
||||
*/
|
||||
static void
|
||||
zapsubs(regmatch_t *p,
|
||||
size_t n)
|
||||
static VOID
|
||||
zapsubs(p, n)
|
||||
regmatch_t *p;
|
||||
size_t n;
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = n - 1; i > 0; i--)
|
||||
{
|
||||
for (i = n-1; i > 0; i--) {
|
||||
p[i].rm_so = -1;
|
||||
p[i].rm_eo = -1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* zapmem - initialize the retry memory of a subtree to zeros
|
||||
- zapmem - initialize the retry memory of a subtree to zeros
|
||||
^ static VOID zapmem(struct vars *, struct subre *);
|
||||
*/
|
||||
static void
|
||||
zapmem(struct vars * v,
|
||||
struct subre * t)
|
||||
static VOID
|
||||
zapmem(v, t)
|
||||
struct vars *v;
|
||||
struct subre *t;
|
||||
{
|
||||
if (t == NULL)
|
||||
return;
|
||||
|
||||
assert(v->mem != NULL);
|
||||
v->mem[t->retry] = 0;
|
||||
if (t->op == '(')
|
||||
{
|
||||
if (t->op == '(') {
|
||||
assert(t->subno > 0);
|
||||
v->pmatch[t->subno].rm_so = -1;
|
||||
v->pmatch[t->subno].rm_eo = -1;
|
||||
@@ -533,13 +507,15 @@ zapmem(struct vars * v,
|
||||
}
|
||||
|
||||
/*
|
||||
* subset - set any subexpression relevant to a successful subre
|
||||
- subset - set any subexpression relevant to a successful subre
|
||||
^ static VOID subset(struct vars *, struct subre *, chr *, chr *);
|
||||
*/
|
||||
static void
|
||||
subset(struct vars * v,
|
||||
struct subre * sub,
|
||||
chr *begin,
|
||||
chr *end)
|
||||
static VOID
|
||||
subset(v, sub, begin, end)
|
||||
struct vars *v;
|
||||
struct subre *sub;
|
||||
chr *begin;
|
||||
chr *end;
|
||||
{
|
||||
int n = sub->subno;
|
||||
|
||||
@@ -553,19 +529,20 @@ subset(struct vars * v,
|
||||
}
|
||||
|
||||
/*
|
||||
* dissect - determine subexpression matches (uncomplicated case)
|
||||
- dissect - determine subexpression matches (uncomplicated case)
|
||||
^ static int dissect(struct vars *, struct subre *, chr *, chr *);
|
||||
*/
|
||||
static int /* regexec return code */
|
||||
dissect(struct vars * v,
|
||||
struct subre * t,
|
||||
chr *begin, /* beginning of relevant substring */
|
||||
chr *end) /* end of same */
|
||||
dissect(v, t, begin, end)
|
||||
struct vars *v;
|
||||
struct subre *t;
|
||||
chr *begin; /* beginning of relevant substring */
|
||||
chr *end; /* end of same */
|
||||
{
|
||||
assert(t != NULL);
|
||||
MDEBUG(("dissect %ld-%ld\n", LOFF(begin), LOFF(end)));
|
||||
|
||||
switch (t->op)
|
||||
{
|
||||
switch (t->op) {
|
||||
case '=': /* terminal node */
|
||||
assert(t->left == NULL && t->right == NULL);
|
||||
return REG_OKAY; /* no action, parent did the work */
|
||||
@@ -594,13 +571,15 @@ dissect(struct vars * v,
|
||||
}
|
||||
|
||||
/*
|
||||
* condissect - determine concatenation subexpression matches (uncomplicated)
|
||||
- condissect - determine concatenation subexpression matches (uncomplicated)
|
||||
^ static int condissect(struct vars *, struct subre *, chr *, chr *);
|
||||
*/
|
||||
static int /* regexec return code */
|
||||
condissect(struct vars * v,
|
||||
struct subre * t,
|
||||
chr *begin, /* beginning of relevant substring */
|
||||
chr *end) /* end of same */
|
||||
condissect(v, t, begin, end)
|
||||
struct vars *v;
|
||||
struct subre *t;
|
||||
chr *begin; /* beginning of relevant substring */
|
||||
chr *end; /* end of same */
|
||||
{
|
||||
struct dfa *d;
|
||||
struct dfa *d2;
|
||||
@@ -616,8 +595,7 @@ condissect(struct vars * v,
|
||||
d = newdfa(v, &t->left->cnfa, &v->g->cmap, &v->dfa1);
|
||||
NOERR();
|
||||
d2 = newdfa(v, &t->right->cnfa, &v->g->cmap, &v->dfa2);
|
||||
if (ISERR())
|
||||
{
|
||||
if (ISERR()) {
|
||||
assert(d2 == NULL);
|
||||
freedfa(d);
|
||||
return v->err;
|
||||
@@ -629,8 +607,7 @@ condissect(struct vars * v,
|
||||
(int *)NULL);
|
||||
else
|
||||
mid = longest(v, d, begin, end, (int *)NULL);
|
||||
if (mid == NULL)
|
||||
{
|
||||
if (mid == NULL) {
|
||||
freedfa(d);
|
||||
freedfa(d2);
|
||||
return REG_ASSERT;
|
||||
@@ -638,11 +615,9 @@ condissect(struct vars * v,
|
||||
MDEBUG(("tentative midpoint %ld\n", LOFF(mid)));
|
||||
|
||||
/* iterate until satisfaction or failure */
|
||||
while (longest(v, d2, mid, end, (int *) NULL) != end)
|
||||
{
|
||||
while (longest(v, d2, mid, end, (int *)NULL) != end) {
|
||||
/* that midpoint didn't work, find a new one */
|
||||
if (mid == stop)
|
||||
{
|
||||
if (mid == stop) {
|
||||
/* all possibilities exhausted! */
|
||||
MDEBUG(("no midpoint!\n"));
|
||||
freedfa(d);
|
||||
@@ -654,8 +629,7 @@ condissect(struct vars * v,
|
||||
(int *)NULL);
|
||||
else
|
||||
mid = longest(v, d, begin, mid-1, (int *)NULL);
|
||||
if (mid == NULL)
|
||||
{
|
||||
if (mid == NULL) {
|
||||
/* failed to find a new one! */
|
||||
MDEBUG(("failed midpoint!\n"));
|
||||
freedfa(d);
|
||||
@@ -676,13 +650,15 @@ condissect(struct vars * v,
|
||||
}
|
||||
|
||||
/*
|
||||
* altdissect - determine alternative subexpression matches (uncomplicated)
|
||||
- altdissect - determine alternative subexpression matches (uncomplicated)
|
||||
^ static int altdissect(struct vars *, struct subre *, chr *, chr *);
|
||||
*/
|
||||
static int /* regexec return code */
|
||||
altdissect(struct vars * v,
|
||||
struct subre * t,
|
||||
chr *begin, /* beginning of relevant substring */
|
||||
chr *end) /* end of same */
|
||||
altdissect(v, t, begin, end)
|
||||
struct vars *v;
|
||||
struct subre *t;
|
||||
chr *begin; /* beginning of relevant substring */
|
||||
chr *end; /* end of same */
|
||||
{
|
||||
struct dfa *d;
|
||||
int i;
|
||||
@@ -690,15 +666,13 @@ altdissect(struct vars * v,
|
||||
assert(t != NULL);
|
||||
assert(t->op == '|');
|
||||
|
||||
for (i = 0; t != NULL; t = t->right, i++)
|
||||
{
|
||||
for (i = 0; t != NULL; t = t->right, i++) {
|
||||
MDEBUG(("trying %dth\n", i));
|
||||
assert(t->left != NULL && t->left->cnfa.nstates > 0);
|
||||
d = newdfa(v, &t->left->cnfa, &v->g->cmap, &v->dfa1);
|
||||
if (ISERR())
|
||||
return v->err;
|
||||
if (longest(v, d, begin, end, (int *) NULL) == end)
|
||||
{
|
||||
if (longest(v, d, begin, end, (int *)NULL) == end) {
|
||||
MDEBUG(("success\n"));
|
||||
freedfa(d);
|
||||
return dissect(v, t->left, begin, end);
|
||||
@@ -709,23 +683,24 @@ altdissect(struct vars * v,
|
||||
}
|
||||
|
||||
/*
|
||||
* cdissect - determine subexpression matches (with complications)
|
||||
- cdissect - determine subexpression matches (with complications)
|
||||
* The retry memory stores the offset of the trial midpoint from begin,
|
||||
* plus 1 so that 0 uniquely means "clean slate".
|
||||
^ static int cdissect(struct vars *, struct subre *, chr *, chr *);
|
||||
*/
|
||||
static int /* regexec return code */
|
||||
cdissect(struct vars * v,
|
||||
struct subre * t,
|
||||
chr *begin, /* beginning of relevant substring */
|
||||
chr *end) /* end of same */
|
||||
cdissect(v, t, begin, end)
|
||||
struct vars *v;
|
||||
struct subre *t;
|
||||
chr *begin; /* beginning of relevant substring */
|
||||
chr *end; /* end of same */
|
||||
{
|
||||
int er;
|
||||
|
||||
assert(t != NULL);
|
||||
MDEBUG(("cdissect %ld-%ld %c\n", LOFF(begin), LOFF(end), t->op));
|
||||
|
||||
switch (t->op)
|
||||
{
|
||||
switch (t->op) {
|
||||
case '=': /* terminal node */
|
||||
assert(t->left == NULL && t->right == NULL);
|
||||
return REG_OKAY; /* no action, parent did the work */
|
||||
@@ -757,15 +732,17 @@ cdissect(struct vars * v,
|
||||
}
|
||||
|
||||
/*
|
||||
* ccondissect - concatenation subexpression matches (with complications)
|
||||
- ccondissect - concatenation subexpression matches (with complications)
|
||||
* The retry memory stores the offset of the trial midpoint from begin,
|
||||
* plus 1 so that 0 uniquely means "clean slate".
|
||||
^ static int ccondissect(struct vars *, struct subre *, chr *, chr *);
|
||||
*/
|
||||
static int /* regexec return code */
|
||||
ccondissect(struct vars * v,
|
||||
struct subre * t,
|
||||
chr *begin, /* beginning of relevant substring */
|
||||
chr *end) /* end of same */
|
||||
ccondissect(v, t, begin, end)
|
||||
struct vars *v;
|
||||
struct subre *t;
|
||||
chr *begin; /* beginning of relevant substring */
|
||||
chr *end; /* end of same */
|
||||
{
|
||||
struct dfa *d;
|
||||
struct dfa *d2;
|
||||
@@ -783,35 +760,29 @@ ccondissect(struct vars * v,
|
||||
if (ISERR())
|
||||
return v->err;
|
||||
d2 = newdfa(v, &t->right->cnfa, &v->g->cmap, DOMALLOC);
|
||||
if (ISERR())
|
||||
{
|
||||
if (ISERR()) {
|
||||
freedfa(d);
|
||||
return v->err;
|
||||
}
|
||||
MDEBUG(("cconcat %d\n", t->retry));
|
||||
|
||||
/* pick a tentative midpoint */
|
||||
if (v->mem[t->retry] == 0)
|
||||
{
|
||||
if (v->mem[t->retry] == 0) {
|
||||
mid = longest(v, d, begin, end, (int *)NULL);
|
||||
if (mid == NULL)
|
||||
{
|
||||
if (mid == NULL) {
|
||||
freedfa(d);
|
||||
freedfa(d2);
|
||||
return REG_NOMATCH;
|
||||
}
|
||||
MDEBUG(("tentative midpoint %ld\n", LOFF(mid)));
|
||||
v->mem[t->retry] = (mid - begin) + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
mid = begin + (v->mem[t->retry] - 1);
|
||||
MDEBUG(("working midpoint %ld\n", LOFF(mid)));
|
||||
}
|
||||
|
||||
/* iterate until satisfaction or failure */
|
||||
for (;;)
|
||||
{
|
||||
for (;;) {
|
||||
/* try this midpoint on for size */
|
||||
er = cdissect(v, t->left, begin, mid);
|
||||
if (er == REG_OKAY &&
|
||||
@@ -819,16 +790,14 @@ ccondissect(struct vars * v,
|
||||
(er = cdissect(v, t->right, mid, end)) ==
|
||||
REG_OKAY)
|
||||
break; /* NOTE BREAK OUT */
|
||||
if (er != REG_OKAY && er != REG_NOMATCH)
|
||||
{
|
||||
if (er != REG_OKAY && er != REG_NOMATCH) {
|
||||
freedfa(d);
|
||||
freedfa(d2);
|
||||
return er;
|
||||
}
|
||||
|
||||
/* that midpoint didn't work, find a new one */
|
||||
if (mid == begin)
|
||||
{
|
||||
if (mid == begin) {
|
||||
/* all possibilities exhausted */
|
||||
MDEBUG(("%d no midpoint\n", t->retry));
|
||||
freedfa(d);
|
||||
@@ -836,8 +805,7 @@ ccondissect(struct vars * v,
|
||||
return REG_NOMATCH;
|
||||
}
|
||||
mid = longest(v, d, begin, mid-1, (int *)NULL);
|
||||
if (mid == NULL)
|
||||
{
|
||||
if (mid == NULL) {
|
||||
/* failed to find a new one */
|
||||
MDEBUG(("%d failed midpoint\n", t->retry));
|
||||
freedfa(d);
|
||||
@@ -858,15 +826,17 @@ ccondissect(struct vars * v,
|
||||
}
|
||||
|
||||
/*
|
||||
* crevdissect - determine backref shortest-first subexpression matches
|
||||
- crevdissect - determine backref shortest-first subexpression matches
|
||||
* The retry memory stores the offset of the trial midpoint from begin,
|
||||
* plus 1 so that 0 uniquely means "clean slate".
|
||||
^ static int crevdissect(struct vars *, struct subre *, chr *, chr *);
|
||||
*/
|
||||
static int /* regexec return code */
|
||||
crevdissect(struct vars * v,
|
||||
struct subre * t,
|
||||
chr *begin, /* beginning of relevant substring */
|
||||
chr *end) /* end of same */
|
||||
crevdissect(v, t, begin, end)
|
||||
struct vars *v;
|
||||
struct subre *t;
|
||||
chr *begin; /* beginning of relevant substring */
|
||||
chr *end; /* end of same */
|
||||
{
|
||||
struct dfa *d;
|
||||
struct dfa *d2;
|
||||
@@ -883,35 +853,29 @@ crevdissect(struct vars * v,
|
||||
if (ISERR())
|
||||
return v->err;
|
||||
d2 = newdfa(v, &t->right->cnfa, &v->g->cmap, DOMALLOC);
|
||||
if (ISERR())
|
||||
{
|
||||
if (ISERR()) {
|
||||
freedfa(d);
|
||||
return v->err;
|
||||
}
|
||||
MDEBUG(("crev %d\n", t->retry));
|
||||
|
||||
/* pick a tentative midpoint */
|
||||
if (v->mem[t->retry] == 0)
|
||||
{
|
||||
if (v->mem[t->retry] == 0) {
|
||||
mid = shortest(v, d, begin, begin, end, (chr **)NULL, (int *)NULL);
|
||||
if (mid == NULL)
|
||||
{
|
||||
if (mid == NULL) {
|
||||
freedfa(d);
|
||||
freedfa(d2);
|
||||
return REG_NOMATCH;
|
||||
}
|
||||
MDEBUG(("tentative midpoint %ld\n", LOFF(mid)));
|
||||
v->mem[t->retry] = (mid - begin) + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
mid = begin + (v->mem[t->retry] - 1);
|
||||
MDEBUG(("working midpoint %ld\n", LOFF(mid)));
|
||||
}
|
||||
|
||||
/* iterate until satisfaction or failure */
|
||||
for (;;)
|
||||
{
|
||||
for (;;) {
|
||||
/* try this midpoint on for size */
|
||||
er = cdissect(v, t->left, begin, mid);
|
||||
if (er == REG_OKAY &&
|
||||
@@ -919,16 +883,14 @@ crevdissect(struct vars * v,
|
||||
(er = cdissect(v, t->right, mid, end)) ==
|
||||
REG_OKAY)
|
||||
break; /* NOTE BREAK OUT */
|
||||
if (er != REG_OKAY && er != REG_NOMATCH)
|
||||
{
|
||||
if (er != REG_OKAY && er != REG_NOMATCH) {
|
||||
freedfa(d);
|
||||
freedfa(d2);
|
||||
return er;
|
||||
}
|
||||
|
||||
/* that midpoint didn't work, find a new one */
|
||||
if (mid == end)
|
||||
{
|
||||
if (mid == end) {
|
||||
/* all possibilities exhausted */
|
||||
MDEBUG(("%d no midpoint\n", t->retry));
|
||||
freedfa(d);
|
||||
@@ -936,8 +898,7 @@ crevdissect(struct vars * v,
|
||||
return REG_NOMATCH;
|
||||
}
|
||||
mid = shortest(v, d, begin, mid+1, end, (chr **)NULL, (int *)NULL);
|
||||
if (mid == NULL)
|
||||
{
|
||||
if (mid == NULL) {
|
||||
/* failed to find a new one */
|
||||
MDEBUG(("%d failed midpoint\n", t->retry));
|
||||
freedfa(d);
|
||||
@@ -958,13 +919,15 @@ crevdissect(struct vars * v,
|
||||
}
|
||||
|
||||
/*
|
||||
* cbrdissect - determine backref subexpression matches
|
||||
- cbrdissect - determine backref subexpression matches
|
||||
^ static int cbrdissect(struct vars *, struct subre *, chr *, chr *);
|
||||
*/
|
||||
static int /* regexec return code */
|
||||
cbrdissect(struct vars * v,
|
||||
struct subre * t,
|
||||
chr *begin, /* beginning of relevant substring */
|
||||
chr *end) /* end of same */
|
||||
cbrdissect(v, t, begin, end)
|
||||
struct vars *v;
|
||||
struct subre *t;
|
||||
chr *begin; /* beginning of relevant substring */
|
||||
chr *end; /* end of same */
|
||||
{
|
||||
int i;
|
||||
int n = t->subno;
|
||||
@@ -993,8 +956,7 @@ cbrdissect(struct vars * v,
|
||||
v->mem[t->retry] = 1;
|
||||
|
||||
/* special-case zero-length string */
|
||||
if (len == 0)
|
||||
{
|
||||
if (len == 0) {
|
||||
if (begin == end)
|
||||
return REG_OKAY;
|
||||
return REG_NOMATCH;
|
||||
@@ -1008,8 +970,7 @@ cbrdissect(struct vars * v,
|
||||
|
||||
/* count occurrences */
|
||||
i = 0;
|
||||
for (p = begin; p <= stop && (i < max || max == INFINITY); p += len)
|
||||
{
|
||||
for (p = begin; p <= stop && (i < max || max == INFINITY); p += len) {
|
||||
if ((*v->g->compare)(paren, p, len) != 0)
|
||||
break;
|
||||
i++;
|
||||
@@ -1025,21 +986,21 @@ cbrdissect(struct vars * v,
|
||||
}
|
||||
|
||||
/*
|
||||
* caltdissect - determine alternative subexpression matches (w. complications)
|
||||
- caltdissect - determine alternative subexpression matches (w. complications)
|
||||
^ static int caltdissect(struct vars *, struct subre *, chr *, chr *);
|
||||
*/
|
||||
static int /* regexec return code */
|
||||
caltdissect(struct vars * v,
|
||||
struct subre * t,
|
||||
chr *begin, /* beginning of relevant substring */
|
||||
chr *end) /* end of same */
|
||||
caltdissect(v, t, begin, end)
|
||||
struct vars *v;
|
||||
struct subre *t;
|
||||
chr *begin; /* beginning of relevant substring */
|
||||
chr *end; /* end of same */
|
||||
{
|
||||
struct dfa *d;
|
||||
int er;
|
||||
|
||||
# define UNTRIED 0 /* not yet tried at all */
|
||||
# define TRYING 1 /* top matched, trying submatches */
|
||||
#define TRIED 2 /* top didn't match or submatches
|
||||
* exhausted */
|
||||
# define TRIED 2 /* top didn't match or submatches exhausted */
|
||||
|
||||
if (t == NULL)
|
||||
return REG_NOMATCH;
|
||||
@@ -1050,13 +1011,11 @@ caltdissect(struct vars * v,
|
||||
MDEBUG(("calt n%d\n", t->retry));
|
||||
assert(t->left != NULL);
|
||||
|
||||
if (v->mem[t->retry] == UNTRIED)
|
||||
{
|
||||
if (v->mem[t->retry] == UNTRIED) {
|
||||
d = newdfa(v, &t->left->cnfa, &v->g->cmap, DOMALLOC);
|
||||
if (ISERR())
|
||||
return v->err;
|
||||
if (longest(v, d, begin, end, (int *) NULL) != end)
|
||||
{
|
||||
if (longest(v, d, begin, end, (int *)NULL) != end) {
|
||||
freedfa(d);
|
||||
v->mem[t->retry] = TRIED;
|
||||
return caltdissect(v, t->right, begin, end);
|
||||
|
||||
@@ -27,7 +27,6 @@
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $Header: /projects/cvsroot/pgsql-server/src/backend/regex/regfree.c,v 1.17 2003/08/04 00:43:21 momjian Exp $
|
||||
*
|
||||
*
|
||||
* You might think that this could be incorporated into regcomp.c, and
|
||||
@@ -39,17 +38,14 @@
|
||||
|
||||
#include "regguts.h"
|
||||
|
||||
|
||||
/*
|
||||
* pg_regfree - free an RE (generic function, punts to RE-specific function)
|
||||
- regfree - free an RE (generic function, punts to RE-specific function)
|
||||
*
|
||||
* Ignoring invocation with NULL is a convenience.
|
||||
*/
|
||||
void
|
||||
regfree(regex_t *re)
|
||||
{ wx_regfree(re); }
|
||||
void
|
||||
wx_regfree(regex_t *re)
|
||||
VOID
|
||||
regfree(re)
|
||||
regex_t *re;
|
||||
{
|
||||
if (re == NULL)
|
||||
return;
|
||||
|
||||
@@ -26,8 +26,6 @@
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
|
||||
@@ -45,32 +43,52 @@
|
||||
* Things that regcustom.h might override.
|
||||
*/
|
||||
|
||||
/* standard header files (NULL is a reasonable indicator for them) */
|
||||
#ifndef NULL
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
/* assertions */
|
||||
#ifndef __WXWINCE__
|
||||
#ifndef assert
|
||||
# ifndef REG_DEBUG
|
||||
# ifndef NDEBUG
|
||||
# define NDEBUG /* no assertions */
|
||||
# endif
|
||||
#endif
|
||||
#include <assert.h>
|
||||
#endif
|
||||
#else
|
||||
// To do: assertion on WinCE
|
||||
#define assert(x)
|
||||
#endif
|
||||
|
||||
/* voids */
|
||||
#ifndef VOID
|
||||
#define VOID void /* for function return values */
|
||||
#endif
|
||||
#ifndef DISCARD
|
||||
#define DISCARD void /* for throwing values away */
|
||||
#define DISCARD VOID /* for throwing values away */
|
||||
#endif
|
||||
#ifndef PVOID
|
||||
#define PVOID VOID * /* generic pointer */
|
||||
#endif
|
||||
#ifndef VS
|
||||
#define VS(x) ((void *)(x)) /* cast something to generic ptr */
|
||||
#define VS(x) ((PVOID)(x)) /* cast something to generic ptr */
|
||||
#endif
|
||||
#ifndef NOPARMS
|
||||
#define NOPARMS VOID /* for empty parm lists */
|
||||
#endif
|
||||
|
||||
/* const */
|
||||
#ifndef CONST
|
||||
#define CONST const /* for old compilers, might be empty */
|
||||
#endif
|
||||
|
||||
/* function-pointer declarator */
|
||||
#ifndef FUNCPTR
|
||||
#if __STDC__ >= 1
|
||||
#define FUNCPTR(name, args) (*name)args
|
||||
#else
|
||||
#define FUNCPTR(name, args) (*name)()
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* memory allocation */
|
||||
@@ -141,8 +159,7 @@
|
||||
#ifndef BYTBITS
|
||||
#define BYTBITS 8 /* bits in a byt */
|
||||
#endif
|
||||
#define BYTTAB (1<<BYTBITS) /* size of table with one entry per byt
|
||||
* value */
|
||||
#define BYTTAB (1<<BYTBITS) /* size of table with one entry per byt value */
|
||||
#define BYTMASK (BYTTAB-1) /* bit mask for byt */
|
||||
#define NBYTS ((CHRBITS+BYTBITS-1)/BYTBITS)
|
||||
/* the definition of GETCOLOR(), below, assumes NBYTS <= 4 */
|
||||
@@ -155,7 +172,6 @@
|
||||
*/
|
||||
typedef short color; /* colors of characters */
|
||||
typedef int pcolor; /* what color promotes to */
|
||||
|
||||
#define COLORLESS (-1) /* impossible color */
|
||||
#define WHITE 0 /* default color, parent of all others */
|
||||
|
||||
@@ -172,26 +188,21 @@ typedef int pcolor; /* what color promotes to */
|
||||
*/
|
||||
|
||||
/* the tree itself */
|
||||
struct colors
|
||||
{
|
||||
struct colors {
|
||||
color ccolor[BYTTAB];
|
||||
};
|
||||
struct ptrs
|
||||
{
|
||||
struct ptrs {
|
||||
union tree *pptr[BYTTAB];
|
||||
};
|
||||
union tree
|
||||
{
|
||||
union tree {
|
||||
struct colors colors;
|
||||
struct ptrs ptrs;
|
||||
};
|
||||
|
||||
#define tcolor colors.ccolor
|
||||
#define tptr ptrs.pptr
|
||||
|
||||
/* internal per-color structure for the color machinery */
|
||||
struct colordesc
|
||||
{
|
||||
struct colordesc {
|
||||
uchr nchrs; /* number of chars of this color */
|
||||
color sub; /* open subcolor (if any); free chain ptr */
|
||||
# define NOSUB COLORLESS
|
||||
@@ -204,8 +215,7 @@ struct colordesc
|
||||
};
|
||||
|
||||
/* the color map itself */
|
||||
struct colormap
|
||||
{
|
||||
struct colormap {
|
||||
int magic;
|
||||
# define CMMAGIC 0x876
|
||||
struct vars *v; /* for compile error reporting */
|
||||
@@ -241,8 +251,7 @@ struct colormap
|
||||
* Interface definitions for locale-interface functions in locale.c.
|
||||
* Multi-character collating elements (MCCEs) cause most of the trouble.
|
||||
*/
|
||||
struct cvec
|
||||
{
|
||||
struct cvec {
|
||||
int nchrs; /* number of chrs */
|
||||
int chrspace; /* number of chrs possible */
|
||||
chr *chrs; /* pointer to vector of chrs */
|
||||
@@ -269,8 +278,7 @@ struct cvec
|
||||
*/
|
||||
struct state;
|
||||
|
||||
struct arc
|
||||
{
|
||||
struct arc {
|
||||
int type;
|
||||
# define ARCFREE '\0'
|
||||
color co;
|
||||
@@ -282,15 +290,13 @@ struct arc
|
||||
struct arc *colorchain; /* color's arc chain */
|
||||
};
|
||||
|
||||
struct arcbatch
|
||||
{ /* for bulk allocation of arcs */
|
||||
struct arcbatch { /* for bulk allocation of arcs */
|
||||
struct arcbatch *next;
|
||||
# define ABSIZE 10
|
||||
struct arc a[ABSIZE];
|
||||
};
|
||||
|
||||
struct state
|
||||
{
|
||||
struct state {
|
||||
int no;
|
||||
# define FREESTATE (-1)
|
||||
char flag; /* marks special states */
|
||||
@@ -302,13 +308,11 @@ struct state
|
||||
struct state *tmp; /* temporary for traversal algorithms */
|
||||
struct state *next; /* chain for traversing all */
|
||||
struct state *prev; /* back chain */
|
||||
struct arcbatch oas; /* first arcbatch, avoid malloc in easy
|
||||
* case */
|
||||
struct arcbatch oas; /* first arcbatch, avoid malloc in easy case */
|
||||
int noas; /* number of arcs used in first arcbatch */
|
||||
};
|
||||
|
||||
struct nfa
|
||||
{
|
||||
struct nfa {
|
||||
struct state *pre; /* pre-initial state */
|
||||
struct state *init; /* initial state */
|
||||
struct state *final; /* final state */
|
||||
@@ -329,14 +333,12 @@ struct nfa
|
||||
/*
|
||||
* definitions for compacted NFA
|
||||
*/
|
||||
struct carc
|
||||
{
|
||||
struct carc {
|
||||
color co; /* COLORLESS is list terminator */
|
||||
int to; /* state number */
|
||||
};
|
||||
|
||||
struct cnfa
|
||||
{
|
||||
struct cnfa {
|
||||
int nstates; /* number of states */
|
||||
int ncolors; /* number of colors */
|
||||
int flags;
|
||||
@@ -348,7 +350,6 @@ struct cnfa
|
||||
struct carc **states; /* vector of pointers to outarc lists */
|
||||
struct carc *arcs; /* the area for the lists */
|
||||
};
|
||||
|
||||
#define ZAPCNFA(cnfa) ((cnfa).nstates = 0)
|
||||
#define NULLCNFA(cnfa) ((cnfa).nstates == 0)
|
||||
|
||||
@@ -357,10 +358,8 @@ struct cnfa
|
||||
/*
|
||||
* subexpression tree
|
||||
*/
|
||||
struct subre
|
||||
{
|
||||
char op; /* '|', '.' (concat), 'b' (backref), '(',
|
||||
* '=' */
|
||||
struct subre {
|
||||
char op; /* '|', '.' (concat), 'b' (backref), '(', '=' */
|
||||
char flags;
|
||||
# define LONGER 01 /* prefers longer match */
|
||||
# define SHORTER 02 /* prefers shorter match */
|
||||
@@ -380,8 +379,7 @@ struct subre
|
||||
int subno; /* subexpression number (for 'b' and '(') */
|
||||
short min; /* min repetitions, for backref only */
|
||||
short max; /* max repetitions, for backref only */
|
||||
struct subre *left; /* left child, if any (also freelist
|
||||
* chain) */
|
||||
struct subre *left; /* left child, if any (also freelist chain) */
|
||||
struct subre *right; /* right child, if any */
|
||||
struct state *begin; /* outarcs from here... */
|
||||
struct state *end; /* ...ending in inarcs here */
|
||||
@@ -395,9 +393,8 @@ struct subre
|
||||
* table of function pointers for generic manipulation functions
|
||||
* A regex_t's re_fns points to one of these.
|
||||
*/
|
||||
struct fns
|
||||
{
|
||||
void FUNCPTR(free, (regex_t *));
|
||||
struct fns {
|
||||
VOID FUNCPTR(free, (regex_t *));
|
||||
};
|
||||
|
||||
|
||||
@@ -405,8 +402,7 @@ struct fns
|
||||
/*
|
||||
* the insides of a regex_t, hidden behind a void *
|
||||
*/
|
||||
struct guts
|
||||
{
|
||||
struct guts {
|
||||
int magic;
|
||||
# define GUTSMAGIC 0xfed9
|
||||
int cflags; /* copy of compile flags */
|
||||
@@ -416,7 +412,7 @@ struct guts
|
||||
struct cnfa search; /* for fast preliminary search */
|
||||
int ntree;
|
||||
struct colormap cmap;
|
||||
int FUNCPTR(compare, (const chr *, const chr *, size_t));
|
||||
int FUNCPTR(compare, (CONST chr *, CONST chr *, size_t));
|
||||
struct subre *lacons; /* lookahead-constraint vector */
|
||||
int nlacons; /* size of lacons */
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user