summaryrefslogtreecommitdiffstats
path: root/Help/guide/tutorial/Step1/tutorial.cxx
blob: 08323bfac93c25cbea6ed529b35dfe5b36074296 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// A simple program that computes the square root of a number
#include <cmath>
#include <cstdlib>
#include <iostream>
#include <string>

int main(int argc, char* argv[])
{
  if (argc < 2) {
    std::cout << "Usage: " << argv[0] << " number" << std::endl;
    return 1;
  }

  // convert input to double
  const double inputValue = atof(argv[1]);

  // calculate square root
  const double outputValue = sqrt(inputValue);
  std::cout << "The square root of " << inputValue << " is " << outputValue
            << std::endl;
  return 0;
}
ion value='bug_3519357'>bug_3519357 Tcl is a high-level, general-purpose, interpreted, dynamic programming language. It was designed with the goal of being very simple but powerful.
summaryrefslogtreecommitdiffstats
path: root/generic
diff options
context:
space:
mode:
Diffstat (limited to 'generic')
-rw-r--r--generic/README4
-rw-r--r--generic/regc_color.c1253
-rw-r--r--generic/regc_cvec.c131
-rw-r--r--generic/regc_lex.c1830
-rw-r--r--generic/regc_locale.c118
-rw-r--r--generic/regc_nfa.c2631
-rw-r--r--generic/regcomp.c3495
-rw-r--r--generic/regcustom.h137
-rw-r--r--generic/rege_dfa.c1223
-rw-r--r--generic/regerror.c150
-rw-r--r--generic/regex.h159
-rw-r--r--generic/regexec.c1830
-rw-r--r--generic/regfree.c47
-rw-r--r--generic/regfronts.c92
-rw-r--r--generic/regguts.h398
-rw-r--r--generic/tcl.decls477
-rw-r--r--generic/tcl.h2343
-rw-r--r--generic/tclAlloc.c509
-rw-r--r--generic/tclAsync.c203
-rw-r--r--generic/tclBasic.c7591
-rw-r--r--generic/tclBinary.c2351
-rw-r--r--generic/tclCkalloc.c891
-rw-r--r--generic/tclClock.c2239
-rw-r--r--generic/tclCmdAH.c2588
-rw-r--r--generic/tclCmdIL.c4711
-rw-r--r--generic/tclCmdMZ.c6470
-rw-r--r--generic/tclCompCmds.c6484
-rw-r--r--generic/tclCompExpr.c3229
-rw-r--r--generic/tclCompile.c3763
-rw-r--r--generic/tclCompile.h1199
-rw-r--r--generic/tclConfig.c392
-rw-r--r--generic/tclDTrace.d30
-rw-r--r--generic/tclDate.c4363
-rw-r--r--generic/tclDecls.h5415
-rw-r--r--generic/tclDictObj.c3170
-rw-r--r--generic/tclEncoding.c2400
-rw-r--r--generic/tclEnv.c546
-rw-r--r--generic/tclEvent.c1301
-rw-r--r--generic/tclExecute.c10605
-rw-r--r--generic/tclFCmd.c751
-rw-r--r--generic/tclFileName.c2938
-rw-r--r--generic/tclFileSystem.h74
-rw-r--r--generic/tclGet.c347
-rw-r--r--generic/tclGetDate.y1727
-rw-r--r--generic/tclHash.c715
-rw-r--r--generic/tclHistory.c103
-rw-r--r--generic/tclIO.c8848
-rw-r--r--generic/tclIO.h356
-rw-r--r--generic/tclIOCmd.c1728
-rw-r--r--generic/tclIOGT.c1539
-rw-r--r--generic/tclIORChan.c3187
-rw-r--r--generic/tclIOSock.c50
-rw-r--r--generic/tclIOUtil.c6897
-rw-r--r--generic/tclIndexObj.c535
-rw-r--r--generic/tclInitScript.h110
-rw-r--r--generic/tclInt.decls488
-rw-r--r--generic/tclInt.h4753
-rw-r--r--generic/tclIntDecls.h1710
-rw-r--r--generic/tclIntPlatDecls.h782
-rw-r--r--generic/tclInterp.c4194
-rw-r--r--generic/tclLink.c519
-rw-r--r--generic/tclListObj.c2152
-rw-r--r--generic/tclLiteral.c855
-rw-r--r--generic/tclLoad.c839
-rw-r--r--generic/tclLoadNone.c103
-rw-r--r--generic/tclMain.c582
-rw-r--r--generic/tclMath.h25
-rw-r--r--generic/tclNamesp.c6976
-rw-r--r--generic/tclNotify.c629
-rw-r--r--generic/tclObj.c3909
-rw-r--r--generic/tclPanic.c56
-rw-r--r--generic/tclParse.c2393
-rw-r--r--generic/tclParseExpr.c2083
-rw-r--r--generic/tclPathObj.c2756
-rw-r--r--generic/tclPipe.c588
-rw-r--r--generic/tclPkg.c1589
-rw-r--r--generic/tclPkgConfig.c135
-rw-r--r--generic/tclPlatDecls.h133
-rw-r--r--generic/tclPort.h17
-rw-r--r--generic/tclPosixStr.c773
-rw-r--r--generic/tclPreserve.c328
-rw-r--r--generic/tclProc.c3095
-rw-r--r--generic/tclRegexp.c570
-rw-r--r--generic/tclRegexp.h35
-rw-r--r--generic/tclResolve.c450
-rw-r--r--generic/tclResult.c1272
-rw-r--r--generic/tclScan.c1007
-rwxr-xr-xgeneric/tclStrToD.c4991
-rw-r--r--generic/tclStringObj.c2273
-rw-r--r--generic/tclStubInit.c463
-rw-r--r--generic/tclStubLib.c148
-rw-r--r--generic/tclTest.c5768
-rw-r--r--generic/tclTestObj.c615
-rw-r--r--generic/tclTestProcBodyObj.c135
-rw-r--r--generic/tclThread.c354
-rw-r--r--[-rwxr-xr-x]generic/tclThreadAlloc.c736
-rw-r--r--generic/tclThreadJoin.c313
-rw-r--r--generic/tclThreadStorage.c597
-rw-r--r--generic/tclThreadTest.c599
-rw-r--r--generic/tclTimer.c851
-rw-r--r--generic/tclTomMath.decls222
-rw-r--r--generic/tclTomMath.h836
-rw-r--r--generic/tclTomMathDecls.h819
-rw-r--r--generic/tclTomMathInt.h2
-rw-r--r--generic/tclTomMathInterface.c311
-rw-r--r--generic/tclTrace.c3249
-rw-r--r--generic/tclUniData.c6
-rw-r--r--generic/tclUtf.c856
-rw-r--r--generic/tclUtil.c3817
-rw-r--r--generic/tclVar.c6591
-rw-r--r--generic/tommath.h1
111 files changed, 121806 insertions, 75216 deletions
diff --git a/generic/README b/generic/README
index ec6139a..d1c078e 100644
--- a/generic/README
+++ b/generic/README
@@ -1,3 +1,3 @@
This directory contains Tcl source files that work on all the platforms
-where Tcl runs (e.g. UNIX, PCs, and Macintoshes). Platform-specific
-sources are in the directories ../unix, ../win, ../macosx, and ../mac.
+where Tcl runs (e.g. UNIX, PCs, and MacOSX). Platform-specific
+sources are in the directories ../unix, ../win, and ../macosx.
diff --git a/generic/regc_color.c b/generic/regc_color.c
index f6716be..ba1f668 100644
--- a/generic/regc_color.c
+++ b/generic/regc_color.c
@@ -2,24 +2,24 @@
* colorings of characters
* This file is #included by regcomp.c.
*
- * Copyright (c) 1998, 1999 Henry Spencer. All rights reserved.
- *
+ * Copyright (c) 1998, 1999 Henry Spencer. All rights reserved.
+ *
* Development of this software was funded, in part, by Cray Research Inc.,
* UUNET Communications Services Inc., Sun Microsystems Inc., and Scriptics
- * Corporation, none of whom are responsible for the results. The author
- * thanks all of them.
- *
+ * Corporation, none of whom are responsible for the results. The author
+ * thanks all of them.
+ *
* Redistribution and use in source and binary forms -- with or without
* modification -- are permitted for any purpose, provided that
* redistributions in source form retain this entire copyright notice and
* indicate the origin and nature of any modifications.
- *
- * I'd appreciate being given credit for this package in the documentation
- * of software which uses it, but that is not a requirement.
- *
+ *
+ * I'd appreciate being given credit for this package in the documentation of
+ * software which uses it, but that is not a requirement.
+ *
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* HENRY SPENCER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
@@ -28,662 +28,712 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- *
- *
- * Note that there are some incestuous relationships between this code and
- * NFA arc maintenance, which perhaps ought to be cleaned up sometime.
+ * Note that there are some incestuous relationships between this code and NFA
+ * arc maintenance, which perhaps ought to be cleaned up sometime.
*/
-
-
#define CISERR() VISERR(cm->v)
#define CERR(e) VERR(cm->v, (e))
-
-
-
+
/*
- initcm - set up new colormap
^ static VOID initcm(struct vars *, struct colormap *);
*/
-static VOID
-initcm(v, cm)
-struct vars *v;
-struct colormap *cm;
+static void
+initcm(
+ struct vars *v,
+ struct colormap *cm)
{
- int i;
- int j;
- union tree *t;
- union tree *nextt;
- struct colordesc *cd;
-
- cm->magic = CMMAGIC;
- cm->v = v;
-
- cm->ncds = NINLINECDS;
- cm->cd = cm->cdspace;
- cm->max = 0;
- cm->free = 0;
-
- cd = cm->cd; /* cm->cd[WHITE] */
- cd->sub = NOSUB;
- cd->arcs = NULL;
- cd->flags = 0;
- cd->nchrs = CHR_MAX - CHR_MIN + 1;
-
- /* upper levels of tree */
- 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;
+ int i;
+ int j;
+ union tree *t;
+ union tree *nextt;
+ struct colordesc *cd;
+
+ cm->magic = CMMAGIC;
+ cm->v = v;
+
+ cm->ncds = NINLINECDS;
+ cm->cd = cm->cdspace;
+ cm->max = 0;
+ cm->free = 0;
+
+ cd = cm->cd; /* cm->cd[WHITE] */
+ cd->sub = NOSUB;
+ cd->arcs = NULL;
+ cd->flags = 0;
+ cd->nchrs = CHR_MAX - CHR_MIN + 1;
+
+ /*
+ * Upper levels of tree.
+ */
+
+ 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;
}
- /* bottom level is solid white */
- t = &cm->tree[NBYTS-1];
- for (i = BYTTAB-1; i >= 0; i--)
- t->tcolor[i] = WHITE;
- cd->block = t;
-}
+ }
+ /*
+ * Bottom level is solid white.
+ */
+
+ t = &cm->tree[NBYTS-1];
+ for (i=BYTTAB-1 ; i>=0 ; i--) {
+ t->tcolor[i] = WHITE;
+ }
+ cd->block = t;
+}
+
/*
- freecm - free dynamically-allocated things in a colormap
^ static VOID freecm(struct colormap *);
*/
-static VOID
-freecm(cm)
-struct colormap *cm;
+static void
+freecm(
+ struct colormap *cm)
{
- size_t i;
- union tree *cb;
-
- cm->magic = 0;
- if (NBYTS > 1)
- cmtreefree(cm, cm->tree, 0);
- for (i = 1; i <= cm->max; i++) /* skip WHITE */
- if (!UNUSEDCOLOR(&cm->cd[i])) {
- cb = cm->cd[i].block;
- if (cb != NULL)
- FREE(cb);
- }
- if (cm->cd != cm->cdspace)
- FREE(cm->cd);
+ size_t i;
+ union tree *cb;
+
+ cm->magic = 0;
+ if (NBYTS > 1) {
+ cmtreefree(cm, cm->tree, 0);
+ }
+ for (i=1 ; i<=cm->max ; i++) { /* skip WHITE */
+ if (!UNUSEDCOLOR(&cm->cd[i])) {
+ cb = cm->cd[i].block;
+ if (cb != NULL) {
+ FREE(cb);
+ }
+ }
+ }
+ if (cm->cd != cm->cdspace) {
+ FREE(cm->cd);
+ }
}
-
+
/*
- cmtreefree - free a non-terminal part of a colormap tree
^ static VOID cmtreefree(struct colormap *, union tree *, int);
*/
-static VOID
-cmtreefree(cm, tree, level)
-struct colormap *cm;
-union tree *tree;
-int level; /* level number (top == 0) of this block */
+static void
+cmtreefree(
+ struct colormap *cm,
+ union tree *tree,
+ int level) /* level number (top == 0) of this block */
{
- int i;
- union tree *t;
- union tree *fillt = &cm->tree[level+1];
- union tree *cb;
-
- assert(level < NBYTS-1); /* this level has pointers */
- 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 */
- cmtreefree(cm, t, level+1);
- FREE(t);
- } else { /* color block below */
- cb = cm->cd[t->tcolor[0]].block;
- if (t != cb) /* not a solid block */
- FREE(t);
- }
+ int i;
+ union tree *t;
+ union tree *fillt = &cm->tree[level+1];
+ union tree *cb;
+
+ assert(level < NBYTS-1); /* this level has pointers */
+ 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 */
+ cmtreefree(cm, t, level+1);
+ FREE(t);
+ } else { /* color block below */
+ cb = cm->cd[t->tcolor[0]].block;
+ if (t != cb) { /* not a solid block */
+ FREE(t);
}
+ }
}
+ }
}
-
+
/*
- setcolor - set the color of a character in a colormap
^ static color setcolor(struct colormap *, pchr, pcolor);
*/
static color /* previous color */
-setcolor(cm, c, co)
-struct colormap *cm;
-pchr c;
-pcolor co;
+setcolor(
+ struct colormap *cm,
+ pchr c,
+ pcolor co)
{
- uchr uc = c;
- int shift;
- int level;
- int b;
- int bottom;
- union tree *t;
- union tree *newt;
- union tree *fillt;
- union tree *lastt;
- union tree *cb;
- color prev;
-
- assert(cm->magic == CMMAGIC);
- if (CISERR() || co == COLORLESS)
+ uchr uc = c;
+ int shift;
+ int level;
+ int b;
+ int bottom;
+ union tree *t;
+ union tree *newt;
+ union tree *fillt;
+ union tree *lastt;
+ union tree *cb;
+ color prev;
+
+ assert(cm->magic == CMMAGIC);
+ if (CISERR() || co == COLORLESS) {
+ return COLORLESS;
+ }
+
+ t = cm->tree;
+ for (level=0, shift=BYTBITS*(NBYTS-1) ; shift>0; level++, shift-=BYTBITS){
+ b = (uc >> shift) & BYTMASK;
+ lastt = t;
+ t = lastt->tptr[b];
+ assert(t != NULL);
+ 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 */
+ newt = (union tree *) MALLOC((bottom) ?
+ sizeof(struct colors) : sizeof(struct ptrs));
+ if (newt == NULL) {
+ CERR(REG_ESPACE);
return COLORLESS;
-
- t = cm->tree;
- for (level = 0, shift = BYTBITS * (NBYTS - 1); shift > 0;
- level++, shift -= BYTBITS) {
- b = (uc >> shift) & BYTMASK;
- lastt = t;
- t = lastt->tptr[b];
- assert(t != NULL);
- 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 */
- newt = (union tree *)MALLOC((bottom) ?
- sizeof(struct colors) : sizeof(struct ptrs));
- if (newt == NULL) {
- CERR(REG_ESPACE);
- return COLORLESS;
- }
- if (bottom)
- memcpy(VS(newt->tcolor), VS(t->tcolor),
- BYTTAB*sizeof(color));
- else
- memcpy(VS(newt->tptr), VS(t->tptr),
- BYTTAB*sizeof(union tree *));
- t = newt;
- lastt->tptr[b] = t;
- }
+ }
+ if (bottom) {
+ memcpy(newt->tcolor, t->tcolor, BYTTAB*sizeof(color));
+ } else {
+ memcpy(newt->tptr, t->tptr, BYTTAB*sizeof(union tree *));
+ }
+ t = newt;
+ lastt->tptr[b] = t;
}
+ }
- b = uc & BYTMASK;
- prev = t->tcolor[b];
- t->tcolor[b] = (color)co;
- return prev;
+ b = uc & BYTMASK;
+ prev = t->tcolor[b];
+ t->tcolor[b] = (color) co;
+ return prev;
}
-
+
/*
- maxcolor - report largest color number in use
^ static color maxcolor(struct colormap *);
*/
static color
-maxcolor(cm)
-struct colormap *cm;
+maxcolor(
+ struct colormap *cm)
{
- if (CISERR())
- return COLORLESS;
+ if (CISERR()) {
+ return COLORLESS;
+ }
- return (color)cm->max;
+ return (color) cm->max;
}
-
+
/*
- newcolor - find a new color (must be subject of setcolor at once)
- * Beware: may relocate the colordescs.
+ * Beware: may relocate the colordescs.
^ static color newcolor(struct colormap *);
*/
static color /* COLORLESS for error */
-newcolor(cm)
-struct colormap *cm;
+newcolor(
+ struct colormap *cm)
{
- struct colordesc *cd;
- struct colordesc *new;
- size_t n;
-
- if (CISERR())
- return COLORLESS;
-
- 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) {
- cm->max++;
- cd = &cm->cd[cm->max];
+ struct colordesc *cd;
+ size_t n;
+
+ if (CISERR()) {
+ return COLORLESS;
+ }
+
+ 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) {
+ cm->max++;
+ cd = &cm->cd[cm->max];
+ } else {
+ struct colordesc *newCd;
+
+ /*
+ * Oops, must allocate more.
+ */
+
+ n = cm->ncds * 2;
+ if (cm->cd == cm->cdspace) {
+ newCd = (struct colordesc *) MALLOC(n * sizeof(struct colordesc));
+ if (newCd != NULL) {
+ memcpy(newCd, cm->cdspace,
+ cm->ncds * sizeof(struct colordesc));
+ }
} else {
- /* oops, must allocate more */
- n = cm->ncds * 2;
- 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
- new = (struct colordesc *)REALLOC(cm->cd,
- n * sizeof(struct colordesc));
- if (new == NULL) {
- CERR(REG_ESPACE);
- return COLORLESS;
- }
- cm->cd = new;
- cm->ncds = n;
- assert(cm->max < cm->ncds - 1);
- cm->max++;
- cd = &cm->cd[cm->max];
+ newCd = (struct colordesc *)
+ REALLOC(cm->cd, n * sizeof(struct colordesc));
}
-
- cd->nchrs = 0;
- cd->sub = NOSUB;
- cd->arcs = NULL;
- cd->flags = 0;
- cd->block = NULL;
-
- return (color)(cd - cm->cd);
+ if (newCd == NULL) {
+ CERR(REG_ESPACE);
+ return COLORLESS;
+ }
+ cm->cd = newCd;
+ cm->ncds = n;
+ assert(cm->max < cm->ncds - 1);
+ cm->max++;
+ cd = &cm->cd[cm->max];
+ }
+
+ cd->nchrs = 0;
+ cd->sub = NOSUB;
+ cd->arcs = NULL;
+ cd->flags = 0;
+ cd->block = NULL;
+
+ return (color) (cd - cm->cd);
}
-
+
/*
- freecolor - free a color (must have no arcs or subcolor)
^ static VOID freecolor(struct colormap *, pcolor);
*/
-static VOID
-freecolor(cm, co)
-struct colormap *cm;
-pcolor co;
+static void
+freecolor(
+ struct colormap *cm,
+ pcolor co)
{
- struct colordesc *cd = &cm->cd[co];
- color pco, nco; /* for freelist scan */
-
- assert(co >= 0);
- if (co == WHITE)
- return;
-
- assert(cd->arcs == NULL);
- assert(cd->sub == NOSUB);
- assert(cd->nchrs == 0);
- cd->flags = FREECOL;
- if (cd->block != NULL) {
- FREE(cd->block);
- cd->block = NULL; /* just paranoia */
+ struct colordesc *cd = &cm->cd[co];
+ color pco, nco; /* for freelist scan */
+
+ assert(co >= 0);
+ if (co == WHITE) {
+ return;
+ }
+
+ assert(cd->arcs == NULL);
+ assert(cd->sub == NOSUB);
+ assert(cd->nchrs == 0);
+ cd->flags = FREECOL;
+ if (cd->block != NULL) {
+ FREE(cd->block);
+ cd->block = NULL; /* just paranoia */
+ }
+
+ if ((size_t) co == cm->max) {
+ while (cm->max > WHITE && UNUSEDCOLOR(&cm->cd[cm->max])) {
+ 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) {
- assert(cm->free < cm->max);
- pco = cm->free;
- nco = cm->cd[pco].sub;
- while (nco > 0)
- if ((size_t)nco > cm->max) {
- /* take this one out of freelist */
- nco = cm->cd[nco].sub;
- cm->cd[pco].sub = nco;
- } else {
- assert(nco < cm->max);
- pco = nco;
- nco = cm->cd[pco].sub;
- }
+ assert(cm->free >= 0);
+ while ((size_t) cm->free > cm->max) {
+ cm->free = cm->cd[cm->free].sub;
+ }
+ 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) {
+ /*
+ * Take this one out of freelist.
+ */
+
+ nco = cm->cd[nco].sub;
+ cm->cd[pco].sub = nco;
+ } else {
+ assert(nco < cm->max);
+ pco = nco;
+ nco = cm->cd[pco].sub;
}
- } else {
- cd->sub = cm->free;
- cm->free = (color)(cd - cm->cd);
+ }
}
+ } else {
+ cd->sub = cm->free;
+ cm->free = (color) (cd - cm->cd);
+ }
}
-
+
/*
- pseudocolor - allocate a false color, to be managed by other means
^ static color pseudocolor(struct colormap *);
*/
static color
-pseudocolor(cm)
-struct colormap *cm;
+pseudocolor(
+ struct colormap *cm)
{
- color co;
-
- co = newcolor(cm);
- if (CISERR())
- return COLORLESS;
- cm->cd[co].nchrs = 1;
- cm->cd[co].flags = PSEUDO;
- return co;
+ color co;
+
+ co = newcolor(cm);
+ if (CISERR()) {
+ return COLORLESS;
+ }
+ cm->cd[co].nchrs = 1;
+ cm->cd[co].flags = PSEUDO;
+ return co;
}
-
+
/*
- subcolor - allocate a new subcolor (if necessary) to this chr
^ static color subcolor(struct colormap *, pchr c);
*/
static color
-subcolor(cm, c)
-struct colormap *cm;
-pchr c;
+subcolor(
+ struct colormap *cm,
+ pchr c)
{
- color co; /* current color of c */
- color sco; /* new subcolor */
-
- co = GETCOLOR(cm, c);
- sco = newsub(cm, co);
- if (CISERR())
- return COLORLESS;
- assert(sco != COLORLESS);
-
- if (co == sco) /* already in an open subcolor */
- return co; /* rest is redundant */
- cm->cd[co].nchrs--;
- cm->cd[sco].nchrs++;
- setcolor(cm, c, sco);
- return sco;
+ color co; /* current color of c */
+ color sco; /* new subcolor */
+
+ co = GETCOLOR(cm, c);
+ sco = newsub(cm, co);
+ if (CISERR()) {
+ return COLORLESS;
+ }
+ assert(sco != COLORLESS);
+
+ if (co == sco) { /* already in an open subcolor */
+ return co; /* rest is redundant */
+ }
+ cm->cd[co].nchrs--;
+ cm->cd[sco].nchrs++;
+ setcolor(cm, c, sco);
+ return sco;
}
-
+
/*
- newsub - allocate a new subcolor (if necessary) for a color
^ static color newsub(struct colormap *, pcolor);
*/
static color
-newsub(cm, co)
-struct colormap *cm;
-pcolor co;
+newsub(
+ struct colormap *cm,
+ pcolor co)
{
- color sco; /* new subcolor */
-
- sco = cm->cd[co].sub;
- 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) {
- assert(CISERR());
- return COLORLESS;
- }
- cm->cd[co].sub = sco;
- cm->cd[sco].sub = sco; /* open subcolor points to self */
+ color sco; /* new subcolor */
+
+ sco = cm->cd[co].sub;
+ 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) {
+ assert(CISERR());
+ return COLORLESS;
}
- assert(sco != NOSUB);
+ cm->cd[co].sub = sco;
+ cm->cd[sco].sub = sco; /* open subcolor points to self */
+ }
+ assert(sco != NOSUB);
- return sco;
+ return sco;
}
-
+
/*
- 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(v, from, to, lp, rp)
-struct vars *v;
-pchr from;
-pchr to;
-struct state *lp;
-struct state *rp;
+static void
+subrange(
+ struct vars *v,
+ pchr from,
+ pchr to,
+ struct state *lp,
+ struct state *rp)
{
- uchr uf;
- int i;
-
- assert(from <= to);
-
- /* first, align "from" on a tree-block boundary */
- uf = (uchr)from;
- i = (int)( ((uf + BYTTAB-1) & (uchr)~BYTMASK) - uf );
- for (; from <= to && i > 0; i--, from++)
- newarc(v->nfa, PLAIN, subcolor(v->cm, from), lp, rp);
- if (from > to) /* didn't reach a boundary */
- return;
-
- /* deal with whole blocks */
- for (; to - from >= BYTTAB; from += BYTTAB)
- subblock(v, from, lp, rp);
-
- /* clean up any remaining partial table */
- for (; from <= to; from++)
- newarc(v->nfa, PLAIN, subcolor(v->cm, from), lp, rp);
+ uchr uf;
+ int i;
+
+ assert(from <= to);
+
+ /*
+ * First, align "from" on a tree-block boundary
+ */
+
+ uf = (uchr) from;
+ i = (int) (((uf + BYTTAB - 1) & (uchr) ~BYTMASK) - uf);
+ for (; from<=to && i>0; i--, from++) {
+ newarc(v->nfa, PLAIN, subcolor(v->cm, from), lp, rp);
+ }
+ if (from > to) { /* didn't reach a boundary */
+ return;
+ }
+
+ /*
+ * Deal with whole blocks.
+ */
+
+ for (; to-from>=BYTTAB ; from+=BYTTAB) {
+ subblock(v, from, lp, rp);
+ }
+
+ /*
+ * Clean up any remaining partial table.
+ */
+
+ for (; from<=to ; from++) {
+ newarc(v->nfa, PLAIN, subcolor(v->cm, from), lp, rp);
+ }
}
-
+
/*
- 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(v, start, lp, rp)
-struct vars *v;
-pchr start; /* first of BYTTAB chrs */
-struct state *lp;
-struct state *rp;
+static void
+subblock(
+ struct vars *v,
+ pchr start, /* first of BYTTAB chrs */
+ struct state *lp,
+ struct state *rp)
{
- uchr uc = start;
- struct colormap *cm = v->cm;
- int shift;
- int level;
- int i;
- int b;
- union tree *t;
- union tree *cb;
- union tree *fillt;
- union tree *lastt;
- int previ;
- int ndone;
- color co;
- color sco;
-
- assert((uc % BYTTAB) == 0);
-
- /* find its color block, making new pointer blocks as needed */
- t = cm->tree;
- fillt = NULL;
- for (level = 0, shift = BYTBITS * (NBYTS - 1); shift > 0;
- 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 */
- t = (union tree *)MALLOC(sizeof(struct ptrs));
- if (t == NULL) {
- CERR(REG_ESPACE);
- return;
- }
- memcpy(VS(t->tptr), VS(fillt->tptr),
- BYTTAB*sizeof(union tree *));
- lastt->tptr[b] = t;
- }
+ uchr uc = start;
+ struct colormap *cm = v->cm;
+ int shift;
+ int level;
+ int i;
+ int b;
+ union tree *t;
+ union tree *cb;
+ union tree *fillt;
+ union tree *lastt;
+ int previ;
+ int ndone;
+ color co;
+ color sco;
+
+ assert((uc % BYTTAB) == 0);
+
+ /*
+ * Find its color block, making new pointer blocks as needed.
+ */
+
+ t = cm->tree;
+ fillt = NULL;
+ for (level=0, shift=BYTBITS*(NBYTS-1); shift>0; 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 */
+ t = (union tree *) MALLOC(sizeof(struct ptrs));
+ if (t == NULL) {
+ CERR(REG_ESPACE);
+ return;
+ }
+ memcpy(t->tptr, fillt->tptr, BYTTAB*sizeof(union tree *));
+ lastt->tptr[b] = t;
}
+ }
+
+ /*
+ * Special cases: fill block or solid block.
+ */
+ co = t->tcolor[0];
+ cb = cm->cd[co].block;
+ if (t == fillt || t == cb) {
+ /*
+ * Either way, we want a subcolor solid block.
+ */
- /* special cases: fill block or solid block */
- co = t->tcolor[0];
- cb = cm->cd[co].block;
- 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 */
- t = (union tree *)MALLOC(sizeof(struct colors));
- if (t == NULL) {
- CERR(REG_ESPACE);
- return;
- }
- for (i = 0; i < BYTTAB; i++)
- t->tcolor[i] = sco;
- cm->cd[sco].block = t;
- }
- /* find loop must have run at least once */
- lastt->tptr[b] = t;
- newarc(v->nfa, PLAIN, sco, lp, rp);
- cm->cd[co].nchrs -= BYTTAB;
- cm->cd[sco].nchrs += BYTTAB;
+ sco = newsub(cm, co);
+ t = cm->cd[sco].block;
+ if (t == NULL) { /* must set it up */
+ t = (union tree *) MALLOC(sizeof(struct colors));
+ if (t == NULL) {
+ CERR(REG_ESPACE);
return;
+ }
+ for (i=0 ; i<BYTTAB ; i++) {
+ t->tcolor[i] = sco;
+ }
+ cm->cd[sco].block = t;
}
- /* general case, a mixed block to be altered */
- i = 0;
- while (i < BYTTAB) {
- co = t->tcolor[i];
- sco = newsub(cm, co);
- newarc(v->nfa, PLAIN, sco, lp, rp);
- previ = i;
- do {
- t->tcolor[i++] = sco;
- } while (i < BYTTAB && t->tcolor[i] == co);
- ndone = i - previ;
- cm->cd[co].nchrs -= ndone;
- cm->cd[sco].nchrs += ndone;
- }
-}
+ /*
+ * Find loop must have run at least once.
+ */
+
+ lastt->tptr[b] = t;
+ newarc(v->nfa, PLAIN, sco, lp, rp);
+ cm->cd[co].nchrs -= BYTTAB;
+ cm->cd[sco].nchrs += BYTTAB;
+ return;
+ }
+
+ /*
+ * General case, a mixed block to be altered.
+ */
+ i = 0;
+ while (i < BYTTAB) {
+ co = t->tcolor[i];
+ sco = newsub(cm, co);
+ newarc(v->nfa, PLAIN, sco, lp, rp);
+ previ = i;
+ do {
+ t->tcolor[i++] = sco;
+ } while (i < BYTTAB && t->tcolor[i] == co);
+ ndone = i - previ;
+ cm->cd[co].nchrs -= ndone;
+ cm->cd[sco].nchrs += ndone;
+ }
+}
+
/*
- okcolors - promote subcolors to full colors
^ static VOID okcolors(struct nfa *, struct colormap *);
*/
-static VOID
-okcolors(nfa, cm)
-struct nfa *nfa;
-struct colormap *cm;
+static void
+okcolors(
+ struct nfa *nfa,
+ struct colormap *cm)
{
- struct colordesc *cd;
- struct colordesc *end = CDEND(cm);
- struct colordesc *scd;
- struct arc *a;
- color co;
- color sco;
-
- for (cd = cm->cd, co = 0; cd < end; cd++, co++) {
- sco = cd->sub;
- if (UNUSEDCOLOR(cd) || sco == NOSUB) {
- /* has no subcolor, no further action */
- } else if (sco == co) {
- /* is subcolor, let parent deal with it */
- } 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) {
- assert(a->co == co);
- uncolorchain(cm, a);
- a->co = sco;
- colorchain(cm, a);
- }
- freecolor(cm, co);
- } 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) {
- assert(a->co == co);
- newarc(nfa, a->type, sco, a->from, a->to);
- }
- }
+ struct colordesc *cd;
+ struct colordesc *end = CDEND(cm);
+ struct colordesc *scd;
+ struct arc *a;
+ color co;
+ color sco;
+
+ for (cd=cm->cd, co=0 ; cd<end ; cd++, co++) {
+ sco = cd->sub;
+ if (UNUSEDCOLOR(cd) || sco == NOSUB) {
+ /*
+ * Has no subcolor, no further action.
+ */
+ } else if (sco == co) {
+ /*
+ * Is subcolor, let parent deal with it.
+ */
+ } 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) {
+ assert(a->co == co);
+ uncolorchain(cm, a);
+ a->co = sco;
+ colorchain(cm, a);
+ }
+ freecolor(cm, co);
+ } 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) {
+ assert(a->co == co);
+ newarc(nfa, a->type, sco, a->from, a->to);
+ }
}
+ }
}
-
+
/*
- colorchain - add this arc to the color chain of its color
^ static VOID colorchain(struct colormap *, struct arc *);
*/
-static VOID
-colorchain(cm, a)
-struct colormap *cm;
-struct arc *a;
+static void
+colorchain(
+ struct colormap *cm,
+ struct arc *a)
{
- struct colordesc *cd = &cm->cd[a->co];
-
- if (cd->arcs)
- cd->arcs->colorchain_rev = a;
- a->colorchain = cd->arcs;
- a->colorchain_rev = NULL;
- cd->arcs = a;
+ struct colordesc *cd = &cm->cd[a->co];
+
+ if (cd->arcs != NULL) {
+ cd->arcs->colorchainRev = a;
+ }
+ a->colorchain = cd->arcs;
+ a->colorchainRev = NULL;
+ cd->arcs = a;
}
-
+
/*
- uncolorchain - delete this arc from the color chain of its color
^ static VOID uncolorchain(struct colormap *, struct arc *);
*/
-static VOID
-uncolorchain(cm, a)
-struct colormap *cm;
-struct arc *a;
-{
- struct colordesc *cd = &cm->cd[a->co];
- struct arc *aa = a->colorchain_rev;
-
- if (aa == NULL) {
- assert(cd->arcs == a);
- cd->arcs = a->colorchain;
- } else {
- assert(aa->colorchain == a);
- aa->colorchain = a->colorchain;
- }
- if (a->colorchain)
- a->colorchain->colorchain_rev = aa;
- a->colorchain = NULL; /* paranoia */
- a->colorchain_rev = NULL;
-}
-
-/*
- - singleton - is this character in its own color?
- ^ static int singleton(struct colormap *, pchr c);
- */
-static int /* predicate */
-singleton(cm, c)
-struct colormap *cm;
-pchr c;
+static void
+uncolorchain(
+ struct colormap *cm,
+ struct arc *a)
{
- color co; /* color of c */
-
- co = GETCOLOR(cm, c);
- if (cm->cd[co].nchrs == 1 && cm->cd[co].sub == NOSUB)
- return 1;
- return 0;
+ struct colordesc *cd = &cm->cd[a->co];
+ struct arc *aa = a->colorchainRev;
+
+ if (aa == NULL) {
+ assert(cd->arcs == a);
+ cd->arcs = a->colorchain;
+ } else {
+ assert(aa->colorchain == a);
+ aa->colorchain = a->colorchain;
+ }
+ if (a->colorchain != NULL) {
+ a->colorchain->colorchainRev = aa;
+ }
+ a->colorchain = NULL; /* paranoia */
+ a->colorchainRev = NULL;
}
-
+
/*
- 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(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;
+static void
+rainbow(
+ 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);
- color co;
-
- for (cd = cm->cd, co = 0; cd < end && !CISERR(); cd++, co++)
- if (!UNUSEDCOLOR(cd) && cd->sub != co && co != but &&
- !(cd->flags&PSEUDO))
- newarc(nfa, type, co, from, to);
+ struct colordesc *cd;
+ struct colordesc *end = CDEND(cm);
+ color co;
+
+ for (cd=cm->cd, co=0 ; cd<end && !CISERR(); cd++, co++) {
+ if (!UNUSEDCOLOR(cd) && (cd->sub != co) && (co != but)
+ && !(cd->flags&PSEUDO)) {
+ newarc(nfa, type, co, from, to);
+ }
+ }
}
-
+
/*
- 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(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;
+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)
{
- struct colordesc *cd;
- struct colordesc *end = CDEND(cm);
- color co;
-
- assert(of != from);
- for (cd = cm->cd, co = 0; cd < end && !CISERR(); cd++, co++)
- if (!UNUSEDCOLOR(cd) && !(cd->flags&PSEUDO))
- if (findarc(of, PLAIN, co) == NULL)
- newarc(nfa, type, co, from, to);
+ struct colordesc *cd;
+ struct colordesc *end = CDEND(cm);
+ color co;
+
+ assert(of != from);
+ for (cd=cm->cd, co=0 ; cd<end && !CISERR() ; cd++, co++) {
+ if (!UNUSEDCOLOR(cd) && !(cd->flags&PSEUDO)) {
+ if (findarc(of, PLAIN, co) == NULL) {
+ newarc(nfa, type, co, from, to);
+ }
+ }
+ }
}
-
-
-
+
#ifdef REG_DEBUG
/*
^ #ifdef REG_DEBUG
@@ -693,87 +743,106 @@ struct state *to;
- dumpcolors - debugging output
^ static VOID dumpcolors(struct colormap *, FILE *);
*/
-static VOID
-dumpcolors(cm, f)
-struct colormap *cm;
-FILE *f;
+static void
+dumpcolors(
+ struct colormap *cm,
+ FILE *f)
{
- struct colordesc *cd;
- struct colordesc *end;
- color co;
- chr c;
- char *has;
-
- fprintf(f, "max %ld\n", (long)cm->max);
- if (NBYTS > 1)
- 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)) {
- assert(cd->nchrs > 0);
- has = (cd->block != NULL) ? "#" : "";
- if (cd->flags&PSEUDO)
- fprintf(f, "#%2ld%s(ps): ", (long)co, has);
- else
- fprintf(f, "#%2ld%s(%2d): ", (long)co,
- has, cd->nchrs);
- /* it's hard to do this more efficiently */
- for (c = CHR_MIN; c < CHR_MAX; c++)
- if (GETCOLOR(cm, c) == co)
- dumpchr(c, f);
- assert(c == CHR_MAX);
- if (GETCOLOR(cm, c) == co)
- dumpchr(c, f);
- fprintf(f, "\n");
+ struct colordesc *cd;
+ struct colordesc *end;
+ color co;
+ chr c;
+ char *has;
+
+ fprintf(f, "max %ld\n", (long) cm->max);
+ if (NBYTS > 1) {
+ 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)) {
+ assert(cd->nchrs > 0);
+ has = (cd->block != NULL) ? "#" : "";
+ if (cd->flags&PSEUDO) {
+ fprintf(f, "#%2ld%s(ps): ", (long) co, has);
+ } else {
+ fprintf(f, "#%2ld%s(%2d): ", (long) co, has, cd->nchrs);
+ }
+
+ /*
+ * It's hard to do this more efficiently.
+ */
+
+ for (c=CHR_MIN ; c<CHR_MAX ; c++) {
+ if (GETCOLOR(cm, c) == co) {
+ dumpchr(c, f);
}
+ }
+ assert(c == CHR_MAX);
+ if (GETCOLOR(cm, c) == co) {
+ dumpchr(c, f);
+ }
+ fprintf(f, "\n");
+ }
+ }
}
-
+
/*
- fillcheck - check proper filling of a tree
^ static VOID fillcheck(struct colormap *, union tree *, int, FILE *);
*/
-static VOID
-fillcheck(cm, tree, level, f)
-struct colormap *cm;
-union tree *tree;
-int level; /* level number (top == 0) of this block */
-FILE *f;
+static void
+fillcheck(
+ 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--) {
- 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);
+ 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--) {
+ t = tree->tptr[i];
+ if (t == NULL) {
+ fprintf(f, "NULL found in filled tree!\n");
+ } else if (t == fillt) {
+ /* empty body */
+ } else if (level < NBYTS-2) { /* more pointer blocks below */
+ fillcheck(cm, t, level+1, f);
}
+ }
}
-
+
/*
- dumpchr - print a chr
* Kind of char-centric but works well enough for debug use.
^ static VOID dumpchr(pchr, FILE *);
*/
-static VOID
-dumpchr(c, f)
-pchr c;
-FILE *f;
+static void
+dumpchr(
+ pchr c,
+ FILE *f)
{
- if (c == '\\')
- fprintf(f, "\\\\");
- else if (c > ' ' && c <= '~')
- putc((char)c, f);
- else
- fprintf(f, "\\u%04lx", (long)c);
+ if (c == '\\') {
+ fprintf(f, "\\\\");
+ } else if (c > ' ' && c <= '~') {
+ putc((char) c, f);
+ } else {
+ fprintf(f, "\\u%04lx", (long) c);
+ }
}
/*
^ #endif
*/
#endif /* ifdef REG_DEBUG */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/regc_cvec.c b/generic/regc_cvec.c
index 0b976b8..64f34cd 100644
--- a/generic/regc_cvec.c
+++ b/generic/regc_cvec.c
@@ -6,7 +6,7 @@
*
* Development of this software was funded, in part, by Cray Research Inc.,
* UUNET Communications Services Inc., Sun Microsystems Inc., and Scriptics
- * Corporation, none of whom are responsible for the results. The author
+ * Corporation, none of whom are responsible for the results. The author
* thanks all of them.
*
* Redistribution and use in source and binary forms -- with or without
@@ -14,8 +14,8 @@
* redistributions in source form retain this entire copyright notice and
* indicate the origin and nature of any modifications.
*
- * I'd appreciate being given credit for this package in the documentation
- * of software which uses it, but that is not a requirement.
+ * I'd appreciate being given credit for this package in the documentation of
+ * software which uses it, but that is not a requirement.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
@@ -27,149 +27,120 @@
* 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.
- *
*/
/*
+ * Notes:
+ * Only (selected) functions in _this_ file should treat chr* as non-constant.
+ */
+
+/*
- newcvec - allocate a new cvec
- ^ static struct cvec *newcvec(int, int, int);
+ ^ static struct cvec *newcvec(int, int);
*/
static struct cvec *
-newcvec(nchrs, nranges, nmcces)
- int nchrs; /* to hold this many chrs... */
- int nranges; /* ... and this many ranges... */
- int nmcces; /* ... and this many MCCEs */
+newcvec(
+ int nchrs, /* to hold this many chrs... */
+ int nranges) /* ... and this many ranges... */
{
- size_t n;
- size_t nc;
- struct cvec *cv;
+ size_t nc = (size_t)nchrs + (size_t)nranges*2;
+ size_t n = sizeof(struct cvec) + nc*sizeof(chr);
+ struct cvec *cv = (struct cvec *) MALLOC(n);
- 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) {
return NULL;
}
cv->chrspace = nchrs;
- cv->chrs = (chr *)&cv->mcces[nmcces]; /* chrs just after MCCE ptrs */
- cv->mccespace = nmcces;
- cv->ranges = cv->chrs + nchrs + nmcces*(MAXMCCE+1);
+ cv->chrs = (chr *)(((char *)cv)+sizeof(struct cvec));
+ cv->ranges = cv->chrs + nchrs;
cv->rangespace = nranges;
return clearcvec(cv);
}
-
+
/*
- clearcvec - clear a possibly-new cvec
* Returns pointer as convenience.
^ static struct cvec *clearcvec(struct cvec *);
*/
static struct cvec *
-clearcvec(cv)
- struct cvec *cv; /* character vector */
+clearcvec(
+ struct cvec *cv) /* character vector */
{
- int i;
-
assert(cv != NULL);
cv->nchrs = 0;
- assert(cv->chrs == (chr *)&cv->mcces[cv->mccespace]);
- cv->nmcces = 0;
- cv->nmccechrs = 0;
cv->nranges = 0;
- for (i = 0; i < cv->mccespace; i++) {
- cv->mcces[i] = NULL;
- }
-
return cv;
}
-
+
/*
- addchr - add a chr to a cvec
^ static VOID addchr(struct cvec *, pchr);
*/
-static VOID
-addchr(cv, c)
- struct cvec *cv; /* character vector */
- pchr c; /* character to add */
+static void
+addchr(
+ 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
^ static VOID addrange(struct cvec *, pchr, pchr);
*/
-static VOID
-addrange(cv, from, to)
- struct cvec *cv; /* character vector */
- pchr from; /* first character of range */
- pchr to; /* last character of range */
+static void
+addrange(
+ 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;
cv->ranges[cv->nranges*2 + 1] = (chr)to;
cv->nranges++;
}
-
-/*
- - haschr - does a cvec contain this chr?
- ^ static int haschr(struct cvec *, pchr);
- */
-static int /* predicate */
-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) {
- return 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
^ static struct cvec *getcvec(struct vars *, int, int);
*/
static struct cvec *
-getcvec(v, nchrs, nranges)
- struct vars *v; /* context */
- int nchrs; /* to hold this many chrs... */
- int nranges; /* ... and this many ranges... */
+getcvec(
+ struct vars *v, /* context */
+ int nchrs, /* to hold this many chrs... */
+ int nranges) /* ... and this many ranges... */
{
- if (v->cv != NULL && nchrs <= v->cv->chrspace &&
- nranges <= v->cv->rangespace) {
+ if ((v->cv != NULL) && (nchrs <= v->cv->chrspace) &&
+ (nranges <= v->cv->rangespace)) {
return clearcvec(v->cv);
}
if (v->cv != NULL) {
freecvec(v->cv);
}
- v->cv = newcvec(nchrs, nranges, 0);
+ v->cv = newcvec(nchrs, nranges);
if (v->cv == NULL) {
ERR(REG_ESPACE);
}
return v->cv;
}
-
+
/*
- freecvec - free a cvec
^ static VOID freecvec(struct cvec *);
*/
-static VOID
-freecvec(cv)
- struct cvec *cv; /* character vector */
+static void
+freecvec(
+ struct cvec *cv) /* character vector */
{
FREE(cv);
}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/regc_lex.c b/generic/regc_lex.c
index 99497b9..8d07c59 100644
--- a/generic/regc_lex.c
+++ b/generic/regc_lex.c
@@ -3,20 +3,20 @@
* This file is #included by regcomp.c.
*
* Copyright (c) 1998, 1999 Henry Spencer. All rights reserved.
- *
+ *
* Development of this software was funded, in part, by Cray Research Inc.,
* UUNET Communications Services Inc., Sun Microsystems Inc., and Scriptics
* Corporation, none of whom are responsible for the results. The author
- * thanks all of them.
- *
+ * thanks all of them.
+ *
* Redistribution and use in source and binary forms -- with or without
* modification -- are permitted for any purpose, provided that
* redistributions in source form retain this entire copyright notice and
* indicate the origin and nature of any modifications.
- *
- * I'd appreciate being given credit for this package in the documentation
- * of software which uses it, but that is not a requirement.
- *
+ *
+ * I'd appreciate being given credit for this package in the documentation of
+ * software which uses it, but that is not a requirement.
+ *
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
@@ -27,7 +27,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.
- *
*/
/* scanning macros (know about v) */
@@ -35,9 +34,10 @@
#define HAVE(n) (v->stop - v->now >= (n))
#define NEXT1(c) (!ATEOS() && *v->now == CHR(c))
#define NEXT2(a,b) (HAVE(2) && *v->now == CHR(a) && *(v->now+1) == CHR(b))
-#define NEXT3(a,b,c) (HAVE(3) && *v->now == CHR(a) && \
- *(v->now+1) == CHR(b) && \
- *(v->now+2) == CHR(c))
+#define NEXT3(a,b,c) \
+ (HAVE(3) && *v->now == CHR(a) && \
+ *(v->now+1) == CHR(b) && \
+ *(v->now+2) == CHR(c))
#define SET(c) (v->nexttype = (c))
#define SETV(c, n) (v->nexttype = (c), v->nextvalue = (n))
#define RET(c) return (SET(c), 1)
@@ -60,804 +60,907 @@
/* construct pointer past end of chr array */
#define ENDOF(array) ((array) + sizeof(array)/sizeof(chr))
-
+
/*
- lexstart - set up lexical stuff, scan leading options
^ static VOID lexstart(struct vars *);
*/
-static VOID
-lexstart(v)
-struct vars *v;
+static void
+lexstart(
+ struct vars *v)
{
- prefixes(v); /* may turn on new type bits etc. */
- NOERR();
+ prefixes(v); /* may turn on new type bits etc. */
+ NOERR();
- if (v->cflags&REG_QUOTE) {
- assert(!(v->cflags&(REG_ADVANCED|REG_EXPANDED|REG_NEWLINE)));
- INTOCON(L_Q);
- } else if (v->cflags&REG_EXTENDED) {
- assert(!(v->cflags&REG_QUOTE));
- INTOCON(L_ERE);
- } else {
- assert(!(v->cflags&(REG_QUOTE|REG_ADVF)));
- INTOCON(L_BRE);
- }
+ if (v->cflags&REG_QUOTE) {
+ assert(!(v->cflags&(REG_ADVANCED|REG_EXPANDED|REG_NEWLINE)));
+ INTOCON(L_Q);
+ } else if (v->cflags&REG_EXTENDED) {
+ assert(!(v->cflags&REG_QUOTE));
+ INTOCON(L_ERE);
+ } else {
+ assert(!(v->cflags&(REG_QUOTE|REG_ADVF)));
+ INTOCON(L_BRE);
+ }
- v->nexttype = EMPTY; /* remember we were at the start */
- next(v); /* set up the first token */
+ v->nexttype = EMPTY; /* remember we were at the start */
+ next(v); /* set up the first token */
}
-
+
/*
- prefixes - implement various special prefixes
^ static VOID prefixes(struct vars *);
*/
-static VOID
-prefixes(v)
-struct vars *v;
+static void
+prefixes(
+ struct vars *v)
{
- /* literal string doesn't get any of this stuff */
- if (v->cflags&REG_QUOTE)
- return;
+ /*
+ * Literal string doesn't get any of this stuff.
+ */
- /* initial "***" gets special things */
- if (HAVE(4) && NEXT3('*', '*', '*'))
- switch (*(v->now + 3)) {
- case CHR('?'): /* "***?" error, msg shows version */
- ERR(REG_BADPAT);
- return; /* proceed no further */
- break;
- case CHR('='): /* "***=" shifts to literal string */
- NOTE(REG_UNONPOSIX);
- v->cflags |= REG_QUOTE;
- v->cflags &= ~(REG_ADVANCED|REG_EXPANDED|REG_NEWLINE);
- v->now += 4;
- return; /* and there can be no more prefixes */
- break;
- case CHR(':'): /* "***:" shifts to AREs */
- NOTE(REG_UNONPOSIX);
- v->cflags |= REG_ADVANCED;
- v->now += 4;
- break;
- default: /* otherwise *** is just an error */
- ERR(REG_BADRPT);
- return;
- break;
- }
+ if (v->cflags&REG_QUOTE) {
+ return;
+ }
- /* BREs and EREs don't get embedded options */
- if ((v->cflags&REG_ADVANCED) != REG_ADVANCED)
- return;
+ /*
+ * Initial "***" gets special things.
+ */
- /* embedded options (AREs only) */
- if (HAVE(3) && NEXT2('(', '?') && iscalpha(*(v->now + 2))) {
- NOTE(REG_UNONPOSIX);
- v->now += 2;
- for (; !ATEOS() && iscalpha(*v->now); v->now++)
- switch (*v->now) {
- case CHR('b'): /* BREs (but why???) */
- v->cflags &= ~(REG_ADVANCED|REG_QUOTE);
- break;
- case CHR('c'): /* case sensitive */
- v->cflags &= ~REG_ICASE;
- break;
- case CHR('e'): /* plain EREs */
- v->cflags |= REG_EXTENDED;
- v->cflags &= ~(REG_ADVF|REG_QUOTE);
- break;
- case CHR('i'): /* case insensitive */
- v->cflags |= REG_ICASE;
- break;
- case CHR('m'): /* Perloid synonym for n */
- case CHR('n'): /* \n affects ^ $ . [^ */
- v->cflags |= REG_NEWLINE;
- break;
- case CHR('p'): /* ~Perl, \n affects . [^ */
- v->cflags |= REG_NLSTOP;
- v->cflags &= ~REG_NLANCH;
- break;
- case CHR('q'): /* literal string */
- v->cflags |= REG_QUOTE;
- v->cflags &= ~REG_ADVANCED;
- break;
- case CHR('s'): /* single line, \n ordinary */
- v->cflags &= ~REG_NEWLINE;
- break;
- case CHR('t'): /* tight syntax */
- v->cflags &= ~REG_EXPANDED;
- break;
- case CHR('w'): /* weird, \n affects ^ $ only */
- v->cflags &= ~REG_NLSTOP;
- v->cflags |= REG_NLANCH;
- break;
- case CHR('x'): /* expanded syntax */
- v->cflags |= REG_EXPANDED;
- break;
- default:
- ERR(REG_BADOPT);
- return;
- }
- if (!NEXT1(')')) {
- ERR(REG_BADOPT);
- return;
- }
- v->now++;
- if (v->cflags&REG_QUOTE)
- v->cflags &= ~(REG_EXPANDED|REG_NEWLINE);
+ if (HAVE(4) && NEXT3('*', '*', '*')) {
+ switch (*(v->now + 3)) {
+ case CHR('?'): /* "***?" error, msg shows version */
+ ERR(REG_BADPAT);
+ return; /* proceed no further */
+ break;
+ case CHR('='): /* "***=" shifts to literal string */
+ NOTE(REG_UNONPOSIX);
+ v->cflags |= REG_QUOTE;
+ v->cflags &= ~(REG_ADVANCED|REG_EXPANDED|REG_NEWLINE);
+ v->now += 4;
+ return; /* and there can be no more prefixes */
+ break;
+ case CHR(':'): /* "***:" shifts to AREs */
+ NOTE(REG_UNONPOSIX);
+ v->cflags |= REG_ADVANCED;
+ v->now += 4;
+ break;
+ default: /* otherwise *** is just an error */
+ ERR(REG_BADRPT);
+ return;
+ break;
}
-}
+ }
+ /*
+ * BREs and EREs don't get embedded options.
+ */
+
+ if ((v->cflags&REG_ADVANCED) != REG_ADVANCED) {
+ return;
+ }
+
+ /*
+ * Embedded options (AREs only).
+ */
+
+ if (HAVE(3) && NEXT2('(', '?') && iscalpha(*(v->now + 2))) {
+ NOTE(REG_UNONPOSIX);
+ v->now += 2;
+ for (; !ATEOS() && iscalpha(*v->now); v->now++) {
+ switch (*v->now) {
+ case CHR('b'): /* BREs (but why???) */
+ v->cflags &= ~(REG_ADVANCED|REG_QUOTE);
+ break;
+ case CHR('c'): /* case sensitive */
+ v->cflags &= ~REG_ICASE;
+ break;
+ case CHR('e'): /* plain EREs */
+ v->cflags |= REG_EXTENDED;
+ v->cflags &= ~(REG_ADVF|REG_QUOTE);
+ break;
+ case CHR('i'): /* case insensitive */
+ v->cflags |= REG_ICASE;
+ break;
+ case CHR('m'): /* Perloid synonym for n */
+ case CHR('n'): /* \n affects ^ $ . [^ */
+ v->cflags |= REG_NEWLINE;
+ break;
+ case CHR('p'): /* ~Perl, \n affects . [^ */
+ v->cflags |= REG_NLSTOP;
+ v->cflags &= ~REG_NLANCH;
+ break;
+ case CHR('q'): /* literal string */
+ v->cflags |= REG_QUOTE;
+ v->cflags &= ~REG_ADVANCED;
+ break;
+ case CHR('s'): /* single line, \n ordinary */
+ v->cflags &= ~REG_NEWLINE;
+ break;
+ case CHR('t'): /* tight syntax */
+ v->cflags &= ~REG_EXPANDED;
+ break;
+ case CHR('w'): /* weird, \n affects ^ $ only */
+ v->cflags &= ~REG_NLSTOP;
+ v->cflags |= REG_NLANCH;
+ break;
+ case CHR('x'): /* expanded syntax */
+ v->cflags |= REG_EXPANDED;
+ break;
+ default:
+ ERR(REG_BADOPT);
+ return;
+ }
+ }
+ if (!NEXT1(')')) {
+ ERR(REG_BADOPT);
+ return;
+ }
+ v->now++;
+ if (v->cflags&REG_QUOTE) {
+ v->cflags &= ~(REG_EXPANDED|REG_NEWLINE);
+ }
+ }
+}
+
/*
- 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 *, const chr *, const chr *);
*/
-static VOID
-lexnest(v, beginp, endp)
-struct vars *v;
-CONST chr *beginp; /* start of interpolation */
-CONST chr *endp; /* one past end of interpolation */
+static void
+lexnest(
+ struct vars *v,
+ const chr *beginp, /* start of interpolation */
+ const chr *endp) /* one past end of interpolation */
{
- assert(v->savenow == NULL); /* only one level of nesting */
- v->savenow = v->now;
- v->savestop = v->stop;
- v->now = beginp;
- v->stop = endp;
+ assert(v->savenow == NULL); /* only one level of nesting */
+ v->savenow = v->now;
+ v->savestop = v->stop;
+ v->now = beginp;
+ v->stop = endp;
}
-
+
/*
* string constants to interpolate as expansions of things like \d
*/
-static CONST chr backd[] = { /* \d */
- CHR('['), CHR('['), CHR(':'),
- CHR('d'), CHR('i'), CHR('g'), CHR('i'), CHR('t'),
- CHR(':'), CHR(']'), CHR(']')
+
+static const chr backd[] = { /* \d */
+ CHR('['), CHR('['), CHR(':'),
+ CHR('d'), CHR('i'), CHR('g'), CHR('i'), CHR('t'),
+ CHR(':'), CHR(']'), CHR(']')
};
-static CONST chr backD[] = { /* \D */
- CHR('['), CHR('^'), CHR('['), CHR(':'),
- CHR('d'), CHR('i'), CHR('g'), CHR('i'), CHR('t'),
- CHR(':'), CHR(']'), CHR(']')
+static const chr backD[] = { /* \D */
+ CHR('['), CHR('^'), CHR('['), CHR(':'),
+ CHR('d'), CHR('i'), CHR('g'), CHR('i'), CHR('t'),
+ CHR(':'), CHR(']'), CHR(']')
};
-static CONST chr brbackd[] = { /* \d within brackets */
- CHR('['), CHR(':'),
- CHR('d'), CHR('i'), CHR('g'), CHR('i'), CHR('t'),
- CHR(':'), CHR(']')
+static const chr brbackd[] = { /* \d within brackets */
+ CHR('['), CHR(':'),
+ CHR('d'), CHR('i'), CHR('g'), CHR('i'), CHR('t'),
+ CHR(':'), CHR(']')
};
-static CONST chr backs[] = { /* \s */
- CHR('['), CHR('['), CHR(':'),
- CHR('s'), CHR('p'), CHR('a'), CHR('c'), CHR('e'),
- CHR(':'), CHR(']'), CHR(']')
+static const chr backs[] = { /* \s */
+ CHR('['), CHR('['), CHR(':'),
+ CHR('s'), CHR('p'), CHR('a'), CHR('c'), CHR('e'),
+ CHR(':'), CHR(']'), CHR(']')
};
-static CONST chr backS[] = { /* \S */
- CHR('['), CHR('^'), CHR('['), CHR(':'),
- CHR('s'), CHR('p'), CHR('a'), CHR('c'), CHR('e'),
- CHR(':'), CHR(']'), CHR(']')
+static const chr backS[] = { /* \S */
+ CHR('['), CHR('^'), CHR('['), CHR(':'),
+ CHR('s'), CHR('p'), CHR('a'), CHR('c'), CHR('e'),
+ CHR(':'), CHR(']'), CHR(']')
};
-static CONST chr brbacks[] = { /* \s within brackets */
- CHR('['), CHR(':'),
- CHR('s'), CHR('p'), CHR('a'), CHR('c'), CHR('e'),
- CHR(':'), CHR(']')
+static const chr brbacks[] = { /* \s within brackets */
+ CHR('['), CHR(':'),
+ CHR('s'), CHR('p'), CHR('a'), CHR('c'), CHR('e'),
+ CHR(':'), CHR(']')
};
-static CONST chr backw[] = { /* \w */
- CHR('['), CHR('['), CHR(':'),
- CHR('a'), CHR('l'), CHR('n'), CHR('u'), CHR('m'),
- CHR(':'), CHR(']'), CHR('_'), CHR(']')
+static const chr backw[] = { /* \w */
+ CHR('['), CHR('['), CHR(':'),
+ CHR('a'), CHR('l'), CHR('n'), CHR('u'), CHR('m'),
+ CHR(':'), CHR(']'), CHR('_'), CHR(']')
};
-static CONST chr backW[] = { /* \W */
- CHR('['), CHR('^'), CHR('['), CHR(':'),
- CHR('a'), CHR('l'), CHR('n'), CHR('u'), CHR('m'),
- CHR(':'), CHR(']'), CHR('_'), CHR(']')
+static const chr backW[] = { /* \W */
+ CHR('['), CHR('^'), CHR('['), CHR(':'),
+ CHR('a'), CHR('l'), CHR('n'), CHR('u'), CHR('m'),
+ CHR(':'), CHR(']'), CHR('_'), CHR(']')
};
-static CONST chr brbackw[] = { /* \w within brackets */
- CHR('['), CHR(':'),
- CHR('a'), CHR('l'), CHR('n'), CHR('u'), CHR('m'),
- CHR(':'), CHR(']'), CHR('_')
+static const chr brbackw[] = { /* \w within brackets */
+ CHR('['), CHR(':'),
+ CHR('a'), CHR('l'), CHR('n'), CHR('u'), CHR('m'),
+ CHR(':'), CHR(']'), CHR('_')
};
-
+
/*
- 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(v)
-struct vars *v;
+static void
+lexword(
+ struct vars *v)
{
- lexnest(v, backw, ENDOF(backw));
+ lexnest(v, backw, ENDOF(backw));
}
-
+
/*
- next - get next token
^ static int next(struct vars *);
*/
static int /* 1 normal, 0 failure */
-next(v)
-struct vars *v;
+next(
+ struct vars *v)
{
- chr c;
+ chr c;
- /* errors yield an infinite sequence of failures */
- if (ISERR())
- return 0; /* the error has set nexttype to EOS */
+ /*
+ * Errors yield an infinite sequence of failures.
+ */
- /* remember flavor of last token */
- v->lasttype = v->nexttype;
+ if (ISERR()) {
+ return 0; /* the error has set nexttype to EOS */
+ }
- /* REG_BOSONLY */
- if (v->nexttype == EMPTY && (v->cflags&REG_BOSONLY)) {
- /* at start of a REG_BOSONLY RE */
- RETV(SBEGIN, 0); /* same as \A */
- }
+ /*
+ * Remember flavor of last token.
+ */
- /* if we're nested and we've hit end, return to outer level */
- if (v->savenow != NULL && ATEOS()) {
- v->now = v->savenow;
- v->stop = v->savestop;
- v->savenow = v->savestop = NULL;
- }
+ v->lasttype = v->nexttype;
- /* skip white space etc. if appropriate (not in literal or []) */
- if (v->cflags&REG_EXPANDED)
- switch (v->lexcon) {
- case L_ERE:
- case L_BRE:
- case L_EBND:
- case L_BBND:
- skip(v);
- break;
- }
+ /*
+ * REG_BOSONLY
+ */
- /* handle EOS, depending on context */
- if (ATEOS()) {
- switch (v->lexcon) {
- case L_ERE:
- case L_BRE:
- case L_Q:
- RET(EOS);
- break;
- case L_EBND:
- case L_BBND:
- FAILW(REG_EBRACE);
- break;
- case L_BRACK:
- case L_CEL:
- case L_ECL:
- case L_CCL:
- FAILW(REG_EBRACK);
- break;
- }
- assert(NOTREACHED);
+ if (v->nexttype == EMPTY && (v->cflags&REG_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()) {
+ v->now = v->savenow;
+ v->stop = v->savestop;
+ v->savenow = v->savestop = NULL;
+ }
+
+ /*
+ * Skip white space etc. if appropriate (not in literal or [])
+ */
+
+ if (v->cflags&REG_EXPANDED) {
+ switch (v->lexcon) {
+ case L_ERE:
+ case L_BRE:
+ case L_EBND:
+ case L_BBND:
+ skip(v);
+ break;
}
+ }
- /* okay, time to actually get a character */
- c = *v->now++;
+ /*
+ * Handle EOS, depending on context.
+ */
- /* deal with the easy contexts, punt EREs to code below */
+ if (ATEOS()) {
switch (v->lexcon) {
- case L_BRE: /* punt BREs to separate function */
- return brenext(v, c);
- break;
- case L_ERE: /* see below */
- break;
- case L_Q: /* literal strings are easy */
- RETV(PLAIN, c);
- break;
- case L_BBND: /* bounds are fairly simple */
+ case L_ERE:
+ case L_BRE:
+ case L_Q:
+ RET(EOS);
+ break;
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'):
- RETV(DIGIT, (chr)DIGITVAL(c));
- break;
- case CHR(','):
- RET(',');
- break;
- case CHR('}'): /* ERE bound ends with } */
- if (INCON(L_EBND)) {
- INTOCON(L_ERE);
- if ((v->cflags&REG_ADVF) && NEXT1('?')) {
- v->now++;
- NOTE(REG_UNONPOSIX);
- RETV('}', 0);
- }
- RETV('}', 1);
- } else
- FAILW(REG_BADBR);
- break;
- case CHR('\\'): /* BRE bound ends with \} */
- if (INCON(L_BBND) && NEXT1('}')) {
- v->now++;
- INTOCON(L_BRE);
- RET('}');
- } else
- FAILW(REG_BADBR);
- break;
- default:
- FAILW(REG_BADBR);
- break;
- }
- assert(NOTREACHED);
- break;
- case L_BRACK: /* brackets are not too hard */
- switch (c) {
- case CHR(']'):
- if (LASTTYPE('['))
- RETV(PLAIN, c);
- else {
- INTOCON((v->cflags&REG_EXTENDED) ?
- L_ERE : L_BRE);
- RET(']');
- }
- break;
- case CHR('\\'):
- NOTE(REG_UBBS);
- if (!(v->cflags&REG_ADVF))
- RETV(PLAIN, c);
- NOTE(REG_UNONPOSIX);
- if (ATEOS())
- FAILW(REG_EESCAPE);
- (DISCARD)lexescape(v);
- switch (v->nexttype) { /* not all escapes okay here */
- case PLAIN:
- return 1;
- break;
- case CCLASS:
- switch (v->nextvalue) {
- case 'd':
- lexnest(v, brbackd, ENDOF(brbackd));
- break;
- case 's':
- lexnest(v, brbacks, ENDOF(brbacks));
- break;
- case 'w':
- lexnest(v, brbackw, ENDOF(brbackw));
- break;
- default:
- FAILW(REG_EESCAPE);
- break;
- }
- /* lexnest done, back up and try again */
- v->nexttype = v->lasttype;
- return next(v);
- break;
- }
- /* not one of the acceptable escapes */
- FAILW(REG_EESCAPE);
- break;
- case CHR('-'):
- if (LASTTYPE('[') || NEXT1(']'))
- RETV(PLAIN, c);
- else
- RETV(RANGE, c);
- break;
- case CHR('['):
- if (ATEOS())
- FAILW(REG_EBRACK);
- switch (*v->now++) {
- case CHR('.'):
- INTOCON(L_CEL);
- /* might or might not be locale-specific */
- RET(COLLEL);
- break;
- case CHR('='):
- INTOCON(L_ECL);
- NOTE(REG_ULOCALE);
- RET(ECLASS);
- break;
- case CHR(':'):
- INTOCON(L_CCL);
- NOTE(REG_ULOCALE);
- RET(CCLASS);
- break;
- default: /* oops */
- v->now--;
- RETV(PLAIN, c);
- break;
- }
- assert(NOTREACHED);
- break;
- default:
- RETV(PLAIN, c);
- break;
- }
- assert(NOTREACHED);
- break;
- case L_CEL: /* collating elements are easy */
- if (c == CHR('.') && NEXT1(']')) {
- v->now++;
- INTOCON(L_BRACK);
- RETV(END, '.');
- } else
- RETV(PLAIN, c);
- break;
- case L_ECL: /* ditto equivalence classes */
- if (c == CHR('=') && NEXT1(']')) {
- v->now++;
- INTOCON(L_BRACK);
- RETV(END, '=');
- } else
- RETV(PLAIN, c);
- break;
- case L_CCL: /* ditto character classes */
- if (c == CHR(':') && NEXT1(']')) {
- v->now++;
- INTOCON(L_BRACK);
- RETV(END, ':');
- } else
- RETV(PLAIN, c);
- break;
- default:
- assert(NOTREACHED);
- break;
+ case L_BBND:
+ FAILW(REG_EBRACE);
+ break;
+ case L_BRACK:
+ case L_CEL:
+ case L_ECL:
+ case L_CCL:
+ FAILW(REG_EBRACK);
+ break;
}
+ assert(NOTREACHED);
+ }
+
+ /*
+ * Okay, time to actually get a character.
+ */
+
+ c = *v->now++;
- /* that got rid of everything except EREs and AREs */
- assert(INCON(L_ERE));
+ /*
+ * Deal with the easy contexts, punt EREs to code below.
+ */
- /* deal with EREs and AREs, except for backslashes */
+ switch (v->lexcon) {
+ case L_BRE: /* punt BREs to separate function */
+ return brenext(v, c);
+ break;
+ case L_ERE: /* see below */
+ break;
+ case L_Q: /* literal strings are easy */
+ RETV(PLAIN, c);
+ break;
+ case L_BBND: /* bounds are fairly simple */
+ case L_EBND:
switch (c) {
- case CHR('|'):
- RET('|');
- break;
- case CHR('*'):
+ 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)) {
+ INTOCON(L_ERE);
if ((v->cflags&REG_ADVF) && NEXT1('?')) {
- v->now++;
- NOTE(REG_UNONPOSIX);
- RETV('*', 0);
+ v->now++;
+ NOTE(REG_UNONPOSIX);
+ RETV('}', 0);
}
- RETV('*', 1);
+ RETV('}', 1);
+ } else {
+ FAILW(REG_BADBR);
+ }
+ break;
+ case CHR('\\'): /* BRE bound ends with \} */
+ if (INCON(L_BBND) && NEXT1('}')) {
+ v->now++;
+ INTOCON(L_BRE);
+ RET('}');
+ } else {
+ FAILW(REG_BADBR);
+ }
+ break;
+ default:
+ FAILW(REG_BADBR);
+ break;
+ }
+ assert(NOTREACHED);
+ break;
+ case L_BRACK: /* brackets are not too hard */
+ switch (c) {
+ case CHR(']'):
+ if (LASTTYPE('[')) {
+ RETV(PLAIN, c);
+ } else {
+ INTOCON((v->cflags&REG_EXTENDED) ? L_ERE : L_BRE);
+ RET(']');
+ }
+ break;
+ case CHR('\\'):
+ NOTE(REG_UBBS);
+ if (!(v->cflags&REG_ADVF)) {
+ RETV(PLAIN, c);
+ }
+ NOTE(REG_UNONPOSIX);
+ if (ATEOS()) {
+ FAILW(REG_EESCAPE);
+ }
+ (DISCARD)lexescape(v);
+ switch (v->nexttype) { /* not all escapes okay here */
+ case PLAIN:
+ return 1;
break;
- case CHR('+'):
- if ((v->cflags&REG_ADVF) && NEXT1('?')) {
- v->now++;
- NOTE(REG_UNONPOSIX);
- RETV('+', 0);
+ case CCLASS:
+ switch (v->nextvalue) {
+ case 'd':
+ lexnest(v, brbackd, ENDOF(brbackd));
+ break;
+ case 's':
+ lexnest(v, brbacks, ENDOF(brbacks));
+ break;
+ case 'w':
+ lexnest(v, brbackw, ENDOF(brbackw));
+ break;
+ default:
+ FAILW(REG_EESCAPE);
+ break;
}
- RETV('+', 1);
+
+ /*
+ * lexnest() done, back up and try again.
+ */
+
+ v->nexttype = v->lasttype;
+ return next(v);
break;
- case CHR('?'):
- if ((v->cflags&REG_ADVF) && NEXT1('?')) {
- v->now++;
- NOTE(REG_UNONPOSIX);
- RETV('?', 0);
- }
- RETV('?', 1);
+ }
+
+ /*
+ * Not one of the acceptable escapes.
+ */
+
+ FAILW(REG_EESCAPE);
+ break;
+ case CHR('-'):
+ if (LASTTYPE('[') || NEXT1(']')) {
+ RETV(PLAIN, c);
+ } else {
+ RETV(RANGE, c);
+ }
+ break;
+ case CHR('['):
+ if (ATEOS()) {
+ FAILW(REG_EBRACK);
+ }
+ switch (*v->now++) {
+ case CHR('.'):
+ INTOCON(L_CEL);
+
+ /*
+ * Might or might not be locale-specific.
+ */
+
+ RET(COLLEL);
break;
- case CHR('{'): /* bounds start or plain character */
- if (v->cflags&REG_EXPANDED)
- skip(v);
- if (ATEOS() || !iscdigit(*v->now)) {
- NOTE(REG_UBRACES);
- NOTE(REG_UUNSPEC);
- RETV(PLAIN, c);
- } else {
- NOTE(REG_UBOUNDS);
- INTOCON(L_EBND);
- RET('{');
- }
- assert(NOTREACHED);
+ case CHR('='):
+ INTOCON(L_ECL);
+ NOTE(REG_ULOCALE);
+ RET(ECLASS);
break;
- case CHR('('): /* parenthesis, or advanced extension */
- if ((v->cflags&REG_ADVF) && NEXT1('?')) {
- NOTE(REG_UNONPOSIX);
- v->now++;
- switch (*v->now++) {
- case CHR(':'): /* non-capturing paren */
- RETV('(', 0);
- break;
- case CHR('#'): /* comment */
- while (!ATEOS() && *v->now != CHR(')'))
- v->now++;
- if (!ATEOS())
- v->now++;
- assert(v->nexttype == v->lasttype);
- return next(v);
- break;
- case CHR('='): /* positive lookahead */
- NOTE(REG_ULOOKAHEAD);
- RETV(LACON, 1);
- break;
- case CHR('!'): /* negative lookahead */
- NOTE(REG_ULOOKAHEAD);
- RETV(LACON, 0);
- break;
- default:
- FAILW(REG_BADRPT);
- break;
- }
- assert(NOTREACHED);
- }
- if (v->cflags&REG_NOSUB)
- RETV('(', 0); /* all parens non-capturing */
- else
- RETV('(', 1);
+ case CHR(':'):
+ INTOCON(L_CCL);
+ NOTE(REG_ULOCALE);
+ RET(CCLASS);
break;
- case CHR(')'):
- if (LASTTYPE('(')) {
- NOTE(REG_UUNSPEC);
- }
- RETV(')', c);
+ default: /* oops */
+ v->now--;
+ RETV(PLAIN, c);
break;
- case CHR('['): /* easy except for [[:<:]] and [[:>:]] */
- if (HAVE(6) && *(v->now+0) == CHR('[') &&
- *(v->now+1) == CHR(':') &&
- (*(v->now+2) == CHR('<') ||
- *(v->now+2) == CHR('>')) &&
- *(v->now+3) == CHR(':') &&
- *(v->now+4) == CHR(']') &&
- *(v->now+5) == CHR(']')) {
- c = *(v->now+2);
- v->now += 6;
- NOTE(REG_UNONPOSIX);
- RET((c == CHR('<')) ? '<' : '>');
+ }
+ assert(NOTREACHED);
+ break;
+ default:
+ RETV(PLAIN, c);
+ break;
+ }
+ assert(NOTREACHED);
+ break;
+ case L_CEL: /* collating elements are easy */
+ if (c == CHR('.') && NEXT1(']')) {
+ v->now++;
+ INTOCON(L_BRACK);
+ RETV(END, '.');
+ } else {
+ RETV(PLAIN, c);
+ }
+ break;
+ case L_ECL: /* ditto equivalence classes */
+ if (c == CHR('=') && NEXT1(']')) {
+ v->now++;
+ INTOCON(L_BRACK);
+ RETV(END, '=');
+ } else {
+ RETV(PLAIN, c);
+ }
+ break;
+ case L_CCL: /* ditto character classes */
+ if (c == CHR(':') && NEXT1(']')) {
+ v->now++;
+ INTOCON(L_BRACK);
+ RETV(END, ':');
+ } else {
+ RETV(PLAIN, c);
+ }
+ break;
+ default:
+ assert(NOTREACHED);
+ break;
+ }
+
+ /*
+ * That got rid of everything except EREs and AREs.
+ */
+
+ assert(INCON(L_ERE));
+
+ /*
+ * Deal with EREs and AREs, except for backslashes.
+ */
+
+ switch (c) {
+ case CHR('|'):
+ RET('|');
+ break;
+ case CHR('*'):
+ if ((v->cflags&REG_ADVF) && NEXT1('?')) {
+ v->now++;
+ NOTE(REG_UNONPOSIX);
+ RETV('*', 0);
+ }
+ RETV('*', 1);
+ break;
+ case CHR('+'):
+ if ((v->cflags&REG_ADVF) && NEXT1('?')) {
+ v->now++;
+ NOTE(REG_UNONPOSIX);
+ RETV('+', 0);
+ }
+ RETV('+', 1);
+ break;
+ case CHR('?'):
+ if ((v->cflags&REG_ADVF) && NEXT1('?')) {
+ v->now++;
+ NOTE(REG_UNONPOSIX);
+ RETV('?', 0);
+ }
+ RETV('?', 1);
+ break;
+ case CHR('{'): /* bounds start or plain character */
+ if (v->cflags&REG_EXPANDED) {
+ skip(v);
+ }
+ if (ATEOS() || !iscdigit(*v->now)) {
+ NOTE(REG_UBRACES);
+ NOTE(REG_UUNSPEC);
+ RETV(PLAIN, c);
+ } else {
+ NOTE(REG_UBOUNDS);
+ INTOCON(L_EBND);
+ RET('{');
+ }
+ assert(NOTREACHED);
+ break;
+ case CHR('('): /* parenthesis, or advanced extension */
+ if ((v->cflags&REG_ADVF) && NEXT1('?')) {
+ NOTE(REG_UNONPOSIX);
+ v->now++;
+ switch (*v->now++) {
+ case CHR(':'): /* non-capturing paren */
+ RETV('(', 0);
+ break;
+ case CHR('#'): /* comment */
+ while (!ATEOS() && *v->now != CHR(')')) {
+ v->now++;
}
- INTOCON(L_BRACK);
- if (NEXT1('^')) {
- v->now++;
- RETV('[', 0);
+ if (!ATEOS()) {
+ v->now++;
}
- RETV('[', 1);
- break;
- case CHR('.'):
- RET('.');
+ assert(v->nexttype == v->lasttype);
+ return next(v);
break;
- case CHR('^'):
- RET('^');
+ case CHR('='): /* positive lookahead */
+ NOTE(REG_ULOOKAHEAD);
+ RETV(LACON, 1);
break;
- case CHR('$'):
- RET('$');
+ case CHR('!'): /* negative lookahead */
+ NOTE(REG_ULOOKAHEAD);
+ RETV(LACON, 0);
break;
- case CHR('\\'): /* mostly punt backslashes to code below */
- if (ATEOS())
- FAILW(REG_EESCAPE);
- break;
- default: /* ordinary character */
- RETV(PLAIN, c);
+ default:
+ FAILW(REG_BADRPT);
break;
+ }
+ assert(NOTREACHED);
+ }
+ if (v->cflags&REG_NOSUB) {
+ RETV('(', 0); /* all parens non-capturing */
+ } else {
+ RETV('(', 1);
+ }
+ break;
+ case CHR(')'):
+ if (LASTTYPE('(')) {
+ NOTE(REG_UUNSPEC);
+ }
+ RETV(')', c);
+ break;
+ case CHR('['): /* easy except for [[:<:]] and [[:>:]] */
+ if (HAVE(6) && *(v->now+0) == CHR('[') &&
+ *(v->now+1) == CHR(':') &&
+ (*(v->now+2) == CHR('<') || *(v->now+2) == CHR('>')) &&
+ *(v->now+3) == CHR(':') &&
+ *(v->now+4) == CHR(']') &&
+ *(v->now+5) == CHR(']')) {
+ c = *(v->now+2);
+ v->now += 6;
+ NOTE(REG_UNONPOSIX);
+ RET((c == CHR('<')) ? '<' : '>');
+ }
+ INTOCON(L_BRACK);
+ if (NEXT1('^')) {
+ v->now++;
+ RETV('[', 0);
+ }
+ RETV('[', 1);
+ break;
+ case CHR('.'):
+ RET('.');
+ break;
+ case CHR('^'):
+ RET('^');
+ break;
+ case CHR('$'):
+ RET('$');
+ break;
+ case CHR('\\'): /* mostly punt backslashes to code below */
+ if (ATEOS()) {
+ FAILW(REG_EESCAPE);
}
+ break;
+ default: /* ordinary character */
+ RETV(PLAIN, c);
+ break;
+ }
- /* ERE/ARE backslash handling; backslash already eaten */
- assert(!ATEOS());
- if (!(v->cflags&REG_ADVF)) { /* only AREs have non-trivial escapes */
- if (iscalnum(*v->now)) {
- NOTE(REG_UBSALNUM);
- NOTE(REG_UUNSPEC);
- }
- RETV(PLAIN, *v->now++);
+ /*
+ * ERE/ARE backslash handling; backslash already eaten.
+ */
+
+ assert(!ATEOS());
+ if (!(v->cflags&REG_ADVF)) {/* only AREs have non-trivial escapes */
+ if (iscalnum(*v->now)) {
+ NOTE(REG_UBSALNUM);
+ NOTE(REG_UUNSPEC);
}
- (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;
- default:
- assert(NOTREACHED);
- FAILW(REG_ASSERT);
- break;
- }
- /* lexnest done, back up and try again */
- v->nexttype = v->lasttype;
- return next(v);
+ RETV(PLAIN, *v->now++);
+ }
+ (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;
+ default:
+ assert(NOTREACHED);
+ FAILW(REG_ASSERT);
+ break;
}
- /* otherwise, lexescape has already done the work */
- return !ISERR();
-}
+ /* lexnest done, back up and try again */
+ v->nexttype = v->lasttype;
+ return next(v);
+ }
+
+ /*
+ * Otherwise, lexescape has already done the work.
+ */
+ return !ISERR();
+}
+
/*
- 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(v)
-struct vars *v;
+lexescape(
+ struct vars *v)
{
- chr c;
- static CONST chr alert[] = {
- CHR('a'), CHR('l'), CHR('e'), CHR('r'), CHR('t')
- };
- static CONST chr esc[] = {
- CHR('E'), CHR('S'), CHR('C')
- };
- CONST chr *save;
-
- assert(v->cflags&REG_ADVF);
-
- assert(!ATEOS());
- c = *v->now++;
- if (!iscalnum(c))
- RETV(PLAIN, c);
+ chr c;
+ static const chr alert[] = {
+ CHR('a'), CHR('l'), CHR('e'), CHR('r'), CHR('t')
+ };
+ static const chr esc[] = {
+ CHR('E'), CHR('S'), CHR('C')
+ };
+ const chr *save;
- NOTE(REG_UNONPOSIX);
- switch (c) {
- case CHR('a'):
- RETV(PLAIN, chrnamed(v, alert, ENDOF(alert), CHR('\007')));
- break;
- case CHR('A'):
- RETV(SBEGIN, 0);
- break;
- case CHR('b'):
- RETV(PLAIN, CHR('\b'));
- break;
- case CHR('B'):
- RETV(PLAIN, CHR('\\'));
- break;
- case CHR('c'):
- NOTE(REG_UUNPORT);
- if (ATEOS())
- FAILW(REG_EESCAPE);
- RETV(PLAIN, (chr)(*v->now++ & 037));
- break;
- case CHR('d'):
- NOTE(REG_ULOCALE);
- RETV(CCLASS, 'd');
- break;
- case CHR('D'):
- NOTE(REG_ULOCALE);
- RETV(CCLASS, 'D');
- break;
- case CHR('e'):
- NOTE(REG_UUNPORT);
- RETV(PLAIN, chrnamed(v, esc, ENDOF(esc), CHR('\033')));
- break;
- case CHR('f'):
- RETV(PLAIN, CHR('\f'));
- break;
- case CHR('m'):
- RET('<');
- break;
- case CHR('M'):
- RET('>');
- break;
- case CHR('n'):
- RETV(PLAIN, CHR('\n'));
- break;
- case CHR('r'):
- RETV(PLAIN, CHR('\r'));
- break;
- case CHR('s'):
- NOTE(REG_ULOCALE);
- RETV(CCLASS, 's');
- break;
- case CHR('S'):
- NOTE(REG_ULOCALE);
- RETV(CCLASS, 'S');
- break;
- case CHR('t'):
- RETV(PLAIN, CHR('\t'));
- break;
- case CHR('u'):
- c = lexdigits(v, 16, 4, 4);
- if (ISERR())
- FAILW(REG_EESCAPE);
- RETV(PLAIN, c);
- break;
- case CHR('U'):
- c = lexdigits(v, 16, 8, 8);
- if (ISERR())
- FAILW(REG_EESCAPE);
- RETV(PLAIN, c);
- break;
- case CHR('v'):
- RETV(PLAIN, CHR('\v'));
- break;
- case CHR('w'):
- NOTE(REG_ULOCALE);
- RETV(CCLASS, 'w');
- break;
- case CHR('W'):
- NOTE(REG_ULOCALE);
- RETV(CCLASS, 'W');
- break;
- case CHR('x'):
- NOTE(REG_UUNPORT);
- c = lexdigits(v, 16, 1, 255); /* REs >255 long outside spec */
- if (ISERR())
- FAILW(REG_EESCAPE);
- RETV(PLAIN, c);
- break;
- case CHR('y'):
- NOTE(REG_ULOCALE);
- RETV(WBDRY, 0);
- break;
- case CHR('Y'):
- NOTE(REG_ULOCALE);
- RETV(NWBDRY, 0);
- break;
- 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('9'):
- save = v->now;
- v->now--; /* put first digit back */
- 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 > 0 && (int)c <= v->nsubexp)) {
- NOTE(REG_UBACKREF);
- RETV(BACKREF, (chr)c);
- }
- /* oops, doesn't look like it's a backref after all... */
- v->now = save;
- /* and fall through into octal number */
- case CHR('0'):
- NOTE(REG_UUNPORT);
- v->now--; /* put first digit back */
- c = lexdigits(v, 8, 1, 3);
- if (ISERR())
- FAILW(REG_EESCAPE);
- RETV(PLAIN, c);
- break;
- default:
- assert(iscalpha(c));
- FAILW(REG_EESCAPE); /* unknown alphabetic escape */
- break;
+ assert(v->cflags&REG_ADVF);
+
+ assert(!ATEOS());
+ c = *v->now++;
+ if (!iscalnum(c)) {
+ RETV(PLAIN, c);
+ }
+
+ NOTE(REG_UNONPOSIX);
+ switch (c) {
+ case CHR('a'):
+ RETV(PLAIN, chrnamed(v, alert, ENDOF(alert), CHR('\007')));
+ break;
+ case CHR('A'):
+ RETV(SBEGIN, 0);
+ break;
+ case CHR('b'):
+ RETV(PLAIN, CHR('\b'));
+ break;
+ case CHR('B'):
+ RETV(PLAIN, CHR('\\'));
+ break;
+ case CHR('c'):
+ NOTE(REG_UUNPORT);
+ if (ATEOS()) {
+ FAILW(REG_EESCAPE);
}
- assert(NOTREACHED);
-}
+ RETV(PLAIN, (chr)(*v->now++ & 037));
+ break;
+ case CHR('d'):
+ NOTE(REG_ULOCALE);
+ RETV(CCLASS, 'd');
+ break;
+ case CHR('D'):
+ NOTE(REG_ULOCALE);
+ RETV(CCLASS, 'D');
+ break;
+ case CHR('e'):
+ NOTE(REG_UUNPORT);
+ RETV(PLAIN, chrnamed(v, esc, ENDOF(esc), CHR('\033')));
+ break;
+ case CHR('f'):
+ RETV(PLAIN, CHR('\f'));
+ break;
+ case CHR('m'):
+ RET('<');
+ break;
+ case CHR('M'):
+ RET('>');
+ break;
+ case CHR('n'):
+ RETV(PLAIN, CHR('\n'));
+ break;
+ case CHR('r'):
+ RETV(PLAIN, CHR('\r'));
+ break;
+ case CHR('s'):
+ NOTE(REG_ULOCALE);
+ RETV(CCLASS, 's');
+ break;
+ case CHR('S'):
+ NOTE(REG_ULOCALE);
+ RETV(CCLASS, 'S');
+ break;
+ case CHR('t'):
+ RETV(PLAIN, CHR('\t'));
+ break;
+ case CHR('u'):
+ c = lexdigits(v, 16, 4, 4);
+ if (ISERR()) {
+ FAILW(REG_EESCAPE);
+ }
+ RETV(PLAIN, c);
+ break;
+ case CHR('U'):
+ c = lexdigits(v, 16, 8, 8);
+ if (ISERR()) {
+ FAILW(REG_EESCAPE);
+ }
+ RETV(PLAIN, c);
+ break;
+ case CHR('v'):
+ RETV(PLAIN, CHR('\v'));
+ break;
+ case CHR('w'):
+ NOTE(REG_ULOCALE);
+ RETV(CCLASS, 'w');
+ break;
+ case CHR('W'):
+ NOTE(REG_ULOCALE);
+ RETV(CCLASS, 'W');
+ break;
+ case CHR('x'):
+ NOTE(REG_UUNPORT);
+ c = lexdigits(v, 16, 1, 255); /* REs >255 long outside spec */
+ if (ISERR()) {
+ FAILW(REG_EESCAPE);
+ }
+ RETV(PLAIN, c);
+ break;
+ case CHR('y'):
+ NOTE(REG_ULOCALE);
+ RETV(WBDRY, 0);
+ break;
+ case CHR('Y'):
+ NOTE(REG_ULOCALE);
+ RETV(NWBDRY, 0);
+ break;
+ 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('9'):
+ save = v->now;
+ v->now--; /* put first digit back */
+ 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 > 0 && (int)c <= v->nsubexp)) {
+ NOTE(REG_UBACKREF);
+ RETV(BACKREF, (chr)c);
+ }
+
+ /*
+ * Oops, doesn't look like it's a backref after all...
+ */
+ v->now = save;
+
+ /*
+ * And fall through into octal number.
+ */
+
+ case CHR('0'):
+ NOTE(REG_UUNPORT);
+ v->now--; /* put first digit back */
+ c = lexdigits(v, 8, 1, 3);
+ if (ISERR()) {
+ FAILW(REG_EESCAPE);
+ }
+ RETV(PLAIN, c);
+ break;
+ default:
+ assert(iscalpha(c));
+ FAILW(REG_EESCAPE); /* unknown alphabetic escape */
+ break;
+ }
+ assert(NOTREACHED);
+}
+
/*
- 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(v, base, minlen, maxlen)
-struct vars *v;
-int base;
-int minlen;
-int maxlen;
+lexdigits(
+ 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;
-
- n = 0;
- 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'):
- 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;
- default:
- v->now--; /* oops, not a digit at all */
- d = -1;
- break;
- }
+ uchr n; /* unsigned to avoid overflow misbehavior */
+ int len;
+ chr c;
+ int d;
+ CONST uchr ub = (uchr) base;
- if (d >= base) { /* not a plausible digit */
- v->now--;
- d = -1;
- }
- if (d < 0)
- break; /* NOTE BREAK OUT */
- n = n*ub + (uchr)d;
+ n = 0;
+ 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'):
+ 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;
+ default:
+ v->now--; /* oops, not a digit at all */
+ d = -1;
+ break;
}
- if (len < minlen)
- ERR(REG_EESCAPE);
- return (chr)n;
-}
+ if (d >= base) { /* not a plausible digit */
+ v->now--;
+ d = -1;
+ }
+ if (d < 0) {
+ break; /* NOTE BREAK OUT */
+ }
+ n = n*ub + (uchr)d;
+ }
+ if (len < minlen) {
+ ERR(REG_EESCAPE);
+ }
+ return (chr)n;
+}
+
/*
- brenext - get next BRE token
* This is much like EREs except for all the stupid backslashes and the
@@ -865,197 +968,218 @@ int maxlen;
^ static int brenext(struct vars *, pchr);
*/
static int /* 1 normal, 0 failure */
-brenext(v, pc)
-struct vars *v;
-pchr pc;
+brenext(
+ struct vars *v,
+ pchr pc)
{
- chr c = (chr)pc;
+ chr c = (chr)pc;
- switch (c) {
- case CHR('*'):
- if (LASTTYPE(EMPTY) || LASTTYPE('(') || LASTTYPE('^'))
- RETV(PLAIN, c);
- RET('*');
- break;
- case CHR('['):
- if (HAVE(6) && *(v->now+0) == CHR('[') &&
- *(v->now+1) == CHR(':') &&
- (*(v->now+2) == CHR('<') ||
- *(v->now+2) == CHR('>')) &&
- *(v->now+3) == CHR(':') &&
- *(v->now+4) == CHR(']') &&
- *(v->now+5) == CHR(']')) {
- c = *(v->now+2);
- v->now += 6;
- NOTE(REG_UNONPOSIX);
- RET((c == CHR('<')) ? '<' : '>');
- }
- INTOCON(L_BRACK);
- if (NEXT1('^')) {
- v->now++;
- RETV('[', 0);
- }
- RETV('[', 1);
- break;
- case CHR('.'):
- RET('.');
- break;
- case CHR('^'):
- if (LASTTYPE(EMPTY))
- RET('^');
- if (LASTTYPE('(')) {
- NOTE(REG_UUNSPEC);
- RET('^');
- }
- RETV(PLAIN, c);
- break;
- case CHR('$'):
- if (v->cflags&REG_EXPANDED)
- skip(v);
- if (ATEOS())
- RET('$');
- if (NEXT2('\\', ')')) {
- NOTE(REG_UUNSPEC);
- RET('$');
- }
- RETV(PLAIN, c);
- break;
- case CHR('\\'):
- break; /* see below */
- default:
- RETV(PLAIN, c);
- break;
+ switch (c) {
+ case CHR('*'):
+ if (LASTTYPE(EMPTY) || LASTTYPE('(') || LASTTYPE('^')) {
+ RETV(PLAIN, c);
+ }
+ RET('*');
+ break;
+ case CHR('['):
+ if (HAVE(6) && *(v->now+0) == CHR('[') &&
+ *(v->now+1) == CHR(':') &&
+ (*(v->now+2) == CHR('<') || *(v->now+2) == CHR('>')) &&
+ *(v->now+3) == CHR(':') &&
+ *(v->now+4) == CHR(']') &&
+ *(v->now+5) == CHR(']')) {
+ c = *(v->now+2);
+ v->now += 6;
+ NOTE(REG_UNONPOSIX);
+ RET((c == CHR('<')) ? '<' : '>');
+ }
+ INTOCON(L_BRACK);
+ if (NEXT1('^')) {
+ v->now++;
+ RETV('[', 0);
+ }
+ RETV('[', 1);
+ break;
+ case CHR('.'):
+ RET('.');
+ break;
+ case CHR('^'):
+ if (LASTTYPE(EMPTY)) {
+ RET('^');
+ }
+ if (LASTTYPE('(')) {
+ NOTE(REG_UUNSPEC);
+ RET('^');
}
+ RETV(PLAIN, c);
+ break;
+ case CHR('$'):
+ if (v->cflags&REG_EXPANDED) {
+ skip(v);
+ }
+ if (ATEOS()) {
+ RET('$');
+ }
+ if (NEXT2('\\', ')')) {
+ NOTE(REG_UUNSPEC);
+ RET('$');
+ }
+ RETV(PLAIN, c);
+ break;
+ case CHR('\\'):
+ break; /* see below */
+ default:
+ RETV(PLAIN, c);
+ break;
+ }
- assert(c == CHR('\\'));
+ assert(c == CHR('\\'));
- if (ATEOS())
- FAILW(REG_EESCAPE);
+ if (ATEOS()) {
+ FAILW(REG_EESCAPE);
+ }
- c = *v->now++;
- switch (c) {
- case CHR('{'):
- INTOCON(L_BBND);
- NOTE(REG_UBOUNDS);
- RET('{');
- break;
- case CHR('('):
- RETV('(', 1);
- break;
- case CHR(')'):
- RETV(')', c);
- break;
- case CHR('<'):
- NOTE(REG_UNONPOSIX);
- RET('<');
- break;
- case CHR('>'):
- 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('9'):
- NOTE(REG_UBACKREF);
- RETV(BACKREF, (chr)DIGITVAL(c));
- break;
- default:
- if (iscalnum(c)) {
- NOTE(REG_UBSALNUM);
- NOTE(REG_UUNSPEC);
- }
- RETV(PLAIN, c);
- break;
+ c = *v->now++;
+ switch (c) {
+ case CHR('{'):
+ INTOCON(L_BBND);
+ NOTE(REG_UBOUNDS);
+ RET('{');
+ break;
+ case CHR('('):
+ RETV('(', 1);
+ break;
+ case CHR(')'):
+ RETV(')', c);
+ break;
+ case CHR('<'):
+ NOTE(REG_UNONPOSIX);
+ RET('<');
+ break;
+ case CHR('>'):
+ 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('9'):
+ NOTE(REG_UBACKREF);
+ RETV(BACKREF, (chr)DIGITVAL(c));
+ break;
+ default:
+ if (iscalnum(c)) {
+ NOTE(REG_UBSALNUM);
+ NOTE(REG_UUNSPEC);
}
+ RETV(PLAIN, c);
+ break;
+ }
- assert(NOTREACHED);
+ assert(NOTREACHED);
}
-
+
/*
- skip - skip white space and comments in expanded form
^ static VOID skip(struct vars *);
*/
-static VOID
-skip(v)
-struct vars *v;
+static void
+skip(
+ struct vars *v)
{
- CONST chr *start = v->now;
-
- assert(v->cflags&REG_EXPANDED);
-
- for (;;) {
- while (!ATEOS() && iscspace(*v->now))
- v->now++;
- if (ATEOS() || *v->now != CHR('#'))
- break; /* NOTE BREAK OUT */
- assert(NEXT1('#'));
- while (!ATEOS() && *v->now != CHR('\n'))
- v->now++;
- /* leave the newline to be picked up by the iscspace loop */
+ const chr *start = v->now;
+
+ assert(v->cflags&REG_EXPANDED);
+
+ for (;;) {
+ while (!ATEOS() && iscspace(*v->now)) {
+ v->now++;
+ }
+ if (ATEOS() || *v->now != CHR('#')) {
+ break; /* NOTE BREAK OUT */
+ }
+ assert(NEXT1('#'));
+ while (!ATEOS() && *v->now != CHR('\n')) {
+ v->now++;
}
- if (v->now != start)
- NOTE(REG_UNONPOSIX);
-}
+ /*
+ * Leave the newline to be picked up by the iscspace loop.
+ */
+ }
+ if (v->now != start) {
+ NOTE(REG_UNONPOSIX);
+ }
+}
+
/*
- newline - return the chr for a newline
* This helps confine use of CHR to this source file.
^ static chr newline(NOPARMS);
*/
static chr
-newline()
+newline(void)
{
- return CHR('\n');
+ return CHR('\n');
}
-
+
/*
- 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);
+ ^ static const chr *ch(NOPARMS);
^ #endif
*/
#ifdef REG_DEBUG
-static CONST chr *
-ch()
+static const chr *
+ch(void)
{
- static CONST chr chstr[] = { CHR('c'), CHR('h'), CHR('\0') };
+ static const chr chstr[] = { CHR('c'), CHR('h'), CHR('\0') };
- return chstr;
+ 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 *, const chr *, const chr *, pchr);
*/
static chr
-chrnamed(v, startp, endp, lastresort)
-struct vars *v;
-CONST chr *startp; /* start of name */
-CONST chr *endp; /* just past end of name */
-pchr lastresort; /* what to return if name lookup fails */
+chrnamed(
+ struct vars *v,
+ const chr *startp, /* start of name */
+ const chr *endp, /* just past end of name */
+ pchr lastresort) /* what to return if name lookup fails */
{
- celt c;
- int errsave;
- int e;
- struct cvec *cv;
-
- errsave = v->err;
- v->err = 0;
- c = element(v, startp, endp);
- e = v->err;
- v->err = errsave;
-
- if (e != 0)
- return (chr)lastresort;
-
- cv = range(v, c, c, 0);
- if (cv->nchrs == 0)
- return (chr)lastresort;
- return cv->chrs[0];
+ celt c;
+ int errsave;
+ int e;
+ struct cvec *cv;
+
+ errsave = v->err;
+ v->err = 0;
+ c = element(v, startp, endp);
+ e = v->err;
+ v->err = errsave;
+
+ if (e != 0) {
+ return (chr)lastresort;
+ }
+
+ cv = range(v, c, c, 0);
+ if (cv->nchrs == 0) {
+ return (chr)lastresort;
+ }
+ return cv->chrs[0];
}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/regc_locale.c b/generic/regc_locale.c
index 6fd831d..40791f4 100644
--- a/generic/regc_locale.c
+++ b/generic/regc_locale.c
@@ -12,9 +12,9 @@
/* ASCII character-name table */
-static CONST struct cname {
- CONST char *name;
- CONST char code;
+static const struct cname {
+ const char *name;
+ const char code;
} cnames[] = {
{"NUL", '\0'},
{"SOH", '\001'},
@@ -133,7 +133,7 @@ typedef struct crange {
* Unicode: alphabetic characters.
*/
-static CONST crange alphaRangeTable[] = {
+static const crange alphaRangeTable[] = {
{0x41, 0x5a}, {0x61, 0x7a}, {0xc0, 0xd6}, {0xd8, 0xf6},
{0xf8, 0x2c1}, {0x2c6, 0x2d1}, {0x2e0, 0x2e4}, {0x370, 0x374},
{0x37a, 0x37d}, {0x388, 0x38a}, {0x38e, 0x3a1}, {0x3a3, 0x3f5},
@@ -224,7 +224,7 @@ static CONST crange alphaRangeTable[] = {
#define NUM_ALPHA_RANGE (sizeof(alphaRangeTable)/sizeof(crange))
-static CONST chr alphaCharTable[] = {
+static const chr alphaCharTable[] = {
0xaa, 0xb5, 0xba, 0x2ec, 0x2ee, 0x376, 0x377, 0x386, 0x38c,
0x559, 0x66e, 0x66f, 0x6d5, 0x6e5, 0x6e6, 0x6ee, 0x6ef, 0x6ff,
0x710, 0x7b1, 0x7f4, 0x7f5, 0x7fa, 0x81a, 0x824, 0x828, 0x8a0,
@@ -258,7 +258,7 @@ static CONST chr alphaCharTable[] = {
* Unicode: control characters.
*/
-static CONST crange controlRangeTable[] = {
+static const crange controlRangeTable[] = {
{0x7f, 0x9f}, {0x600, 0x604}, {0x200b, 0x200f}, {0x202a, 0x202e},
{0x2060, 0x2064}, {0x206a, 0x206f}, {0xe000, 0xf8ff}, {0xfff9, 0xfffb}
#if TCL_UTF_MAX > 4
@@ -268,7 +268,7 @@ static CONST crange controlRangeTable[] = {
#define NUM_CONTROL_RANGE (sizeof(controlRangeTable)/sizeof(crange))
-static CONST chr controlCharTable[] = {
+static const chr controlCharTable[] = {
0xad, 0x6dd, 0x70f, 0xfeff
#if TCL_UTF_MAX > 4
,0x110bd, 0xe0001
@@ -281,7 +281,7 @@ static CONST chr controlCharTable[] = {
* Unicode: decimal digit characters.
*/
-static CONST crange digitRangeTable[] = {
+static const crange digitRangeTable[] = {
{0x30, 0x39}, {0x660, 0x669}, {0x6f0, 0x6f9}, {0x7c0, 0x7c9},
{0x966, 0x96f}, {0x9e6, 0x9ef}, {0xa66, 0xa6f}, {0xae6, 0xaef},
{0xb66, 0xb6f}, {0xbe6, 0xbef}, {0xc66, 0xc6f}, {0xce6, 0xcef},
@@ -307,7 +307,7 @@ static CONST crange digitRangeTable[] = {
* Unicode: punctuation characters.
*/
-static CONST crange punctRangeTable[] = {
+static const crange punctRangeTable[] = {
{0x21, 0x23}, {0x25, 0x2a}, {0x2c, 0x2f}, {0x5b, 0x5d},
{0x55a, 0x55f}, {0x66a, 0x66d}, {0x700, 0x70d}, {0x7f7, 0x7f9},
{0x830, 0x83e}, {0xf04, 0xf12}, {0xf3a, 0xf3d}, {0xfd0, 0xfd4},
@@ -329,7 +329,7 @@ static CONST crange punctRangeTable[] = {
#define NUM_PUNCT_RANGE (sizeof(punctRangeTable)/sizeof(crange))
-static CONST chr punctCharTable[] = {
+static const chr punctCharTable[] = {
0x3a, 0x3b, 0x3f, 0x40, 0x5f, 0x7b, 0x7d, 0xa1, 0xa7,
0xab, 0xb6, 0xb7, 0xbb, 0xbf, 0x37e, 0x387, 0x589, 0x58a,
0x5be, 0x5c0, 0x5c3, 0x5c6, 0x5f3, 0x5f4, 0x609, 0x60a, 0x60c,
@@ -353,13 +353,13 @@ static CONST chr punctCharTable[] = {
* Unicode: white space characters.
*/
-static CONST crange spaceRangeTable[] = {
+static const crange spaceRangeTable[] = {
{0x9, 0xd}, {0x2000, 0x200a}
};
#define NUM_SPACE_RANGE (sizeof(spaceRangeTable)/sizeof(crange))
-static CONST chr spaceCharTable[] = {
+static const chr spaceCharTable[] = {
0x20, 0xa0, 0x1680, 0x180e, 0x2028, 0x2029, 0x202f, 0x205f, 0x3000
};
@@ -369,7 +369,7 @@ static CONST chr spaceCharTable[] = {
* Unicode: lowercase characters.
*/
-static CONST crange lowerRangeTable[] = {
+static const crange lowerRangeTable[] = {
{0x61, 0x7a}, {0xdf, 0xf6}, {0xf8, 0xff}, {0x17e, 0x180},
{0x199, 0x19b}, {0x1bd, 0x1bf}, {0x233, 0x239}, {0x24f, 0x293},
{0x295, 0x2af}, {0x37b, 0x37d}, {0x3ac, 0x3ce}, {0x3d5, 0x3d7},
@@ -394,7 +394,7 @@ static CONST crange lowerRangeTable[] = {
#define NUM_LOWER_RANGE (sizeof(lowerRangeTable)/sizeof(crange))
-static CONST chr lowerCharTable[] = {
+static const chr lowerCharTable[] = {
0xb5, 0x101, 0x103, 0x105, 0x107, 0x109, 0x10b, 0x10d, 0x10f,
0x111, 0x113, 0x115, 0x117, 0x119, 0x11b, 0x11d, 0x11f, 0x121,
0x123, 0x125, 0x127, 0x129, 0x12b, 0x12d, 0x12f, 0x131, 0x133,
@@ -468,7 +468,7 @@ static CONST chr lowerCharTable[] = {
* Unicode: uppercase characters.
*/
-static CONST crange upperRangeTable[] = {
+static const crange upperRangeTable[] = {
{0x41, 0x5a}, {0xc0, 0xd6}, {0xd8, 0xde}, {0x189, 0x18b},
{0x18e, 0x191}, {0x196, 0x198}, {0x1b1, 0x1b3}, {0x1f6, 0x1f8},
{0x243, 0x246}, {0x388, 0x38a}, {0x391, 0x3a1}, {0x3a3, 0x3ab},
@@ -491,7 +491,7 @@ static CONST crange upperRangeTable[] = {
#define NUM_UPPER_RANGE (sizeof(upperRangeTable)/sizeof(crange))
-static CONST chr upperCharTable[] = {
+static const chr upperCharTable[] = {
0x100, 0x102, 0x104, 0x106, 0x108, 0x10a, 0x10c, 0x10e, 0x110,
0x112, 0x114, 0x116, 0x118, 0x11a, 0x11c, 0x11e, 0x120, 0x122,
0x124, 0x126, 0x128, 0x12a, 0x12c, 0x12e, 0x130, 0x132, 0x134,
@@ -566,7 +566,7 @@ static CONST chr upperCharTable[] = {
* Unicode: unicode print characters excluding space.
*/
-static CONST crange graphRangeTable[] = {
+static const crange graphRangeTable[] = {
{0x21, 0x7e}, {0xa1, 0xac}, {0xae, 0x377}, {0x37a, 0x37e},
{0x384, 0x38a}, {0x38e, 0x3a1}, {0x3a3, 0x527}, {0x531, 0x556},
{0x559, 0x55f}, {0x561, 0x587}, {0x591, 0x5c7}, {0x5d0, 0x5ea},
@@ -682,7 +682,7 @@ static CONST crange graphRangeTable[] = {
#define NUM_GRAPH_RANGE (sizeof(graphRangeTable)/sizeof(crange))
-static CONST chr graphCharTable[] = {
+static const chr graphCharTable[] = {
0x38c, 0x589, 0x58a, 0x58f, 0x85e, 0x8a0, 0x98f, 0x990, 0x9b2,
0x9c7, 0x9c8, 0x9d7, 0x9dc, 0x9dd, 0xa0f, 0xa10, 0xa32, 0xa33,
0xa35, 0xa36, 0xa38, 0xa39, 0xa3c, 0xa47, 0xa48, 0xa51, 0xa5e,
@@ -715,18 +715,18 @@ static CONST chr graphCharTable[] = {
/*
- element - map collating-element name to celt
- ^ static celt element(struct vars *, CONST chr *, CONST chr *);
+ ^ static celt element(struct vars *, const chr *, const chr *);
*/
static celt
-element(v, startp, endp)
- struct vars *v; /* context */
- CONST chr *startp; /* points to start of name */
- CONST chr *endp; /* points just past end of name */
+element(
+ struct vars *v, /* context */
+ const chr *startp, /* points to start of name */
+ const chr *endp) /* points just past end of name */
{
- CONST struct cname *cn;
+ const struct cname *cn;
size_t len;
Tcl_DString ds;
- CONST char *np;
+ const char *np;
/*
* Generic: one-chr names stand for themselves.
@@ -769,11 +769,11 @@ element(v, startp, endp)
^ static struct cvec *range(struct vars *, celt, celt, int);
*/
static struct cvec *
-range(v, a, b, cases)
- struct vars *v; /* context */
- celt a; /* range start */
- celt b; /* range end, might equal a */
- int cases; /* case-independent? */
+range(
+ struct vars *v, /* context */
+ celt a, /* range start */
+ celt b, /* range end, might equal a */
+ int cases) /* case-independent? */
{
int nchrs;
struct cvec *cv;
@@ -826,8 +826,8 @@ range(v, a, b, cases)
^ static int before(celt, celt);
*/
static int /* predicate */
-before(x, y)
- celt x, y; /* collating elements */
+before(
+ celt x, celt y) /* collating elements */
{
if (x < y) {
return 1;
@@ -841,11 +841,11 @@ before(x, y)
^ static struct cvec *eclass(struct vars *, celt, int);
*/
static struct cvec *
-eclass(v, c, cases)
- struct vars *v; /* context */
- celt c; /* Collating element representing
- * the equivalence class. */
- int cases; /* all cases? */
+eclass(
+ struct vars *v, /* context */
+ celt c, /* Collating element representing the
+ * equivalence class. */
+ int cases) /* all cases? */
{
struct cvec *cv;
@@ -880,27 +880,27 @@ eclass(v, c, cases)
/*
- cclass - supply cvec for a character class
* Must include case counterparts on request.
- ^ static struct cvec *cclass(struct vars *, CONST chr *, CONST chr *, int);
+ ^ static struct cvec *cclass(struct vars *, const chr *, const chr *, int);
*/
static struct cvec *
-cclass(v, startp, endp, cases)
- struct vars *v; /* context */
- CONST chr *startp; /* where the name starts */
- CONST chr *endp; /* just past the end of the name */
- int cases; /* case-independent? */
+cclass(
+ struct vars *v, /* context */
+ const chr *startp, /* where the name starts */
+ const chr *endp, /* just past the end of the name */
+ int cases) /* case-independent? */
{
size_t len;
struct cvec *cv = NULL;
Tcl_DString ds;
- CONST char *np;
- CONST char *CONST *namePtr;
+ const char *np;
+ const char *const *namePtr;
int i, index;
/*
* The following arrays define the valid character class names.
*/
- static CONST char *CONST classNames[] = {
+ static const char *const classNames[] = {
"alnum", "alpha", "ascii", "blank", "cntrl", "digit", "graph",
"lower", "print", "punct", "space", "upper", "xdigit", NULL
};
@@ -1119,9 +1119,9 @@ cclass(v, startp, endp, cases)
^ static struct cvec *allcases(struct vars *, pchr);
*/
static struct cvec *
-allcases(v, pc)
- struct vars *v; /* context */
- pchr pc; /* character to get case equivs of */
+allcases(
+ struct vars *v, /* context */
+ pchr pc) /* character to get case equivs of */
{
struct cvec *cv;
chr c = (chr)pc;
@@ -1150,12 +1150,12 @@ allcases(v, pc)
* Note that it does not need to report anything except equal/unequal.
* Note also that the length is exact, and the comparison should not
* stop at embedded NULs!
- ^ static int cmp(CONST chr *, CONST chr *, size_t);
+ ^ static int cmp(const chr *, const chr *, size_t);
*/
-static int /* 0 for equal, nonzero for unequal */
-cmp(x, y, len)
- CONST chr *x, *y; /* strings to compare */
- size_t len; /* exact length of comparison */
+static int /* 0 for equal, nonzero for unequal */
+cmp(
+ const chr *x, const chr *y, /* strings to compare */
+ size_t len) /* exact length of comparison */
{
return memcmp(VS(x), VS(y), len*sizeof(chr));
}
@@ -1166,12 +1166,12 @@ cmp(x, y, len)
* Note that it does not need to report anything except equal/unequal.
* Note also that the length is exact, and the comparison should not
* stop at embedded NULs!
- ^ static int casecmp(CONST chr *, CONST chr *, size_t);
+ ^ static int casecmp(const chr *, const chr *, size_t);
*/
-static int /* 0 for equal, nonzero for unequal */
-casecmp(x, y, len)
- CONST chr *x, *y; /* strings to compare */
- size_t len; /* exact length of comparison */
+static int /* 0 for equal, nonzero for unequal */
+casecmp(
+ const chr *x, const chr *y, /* strings to compare */
+ size_t len) /* exact length of comparison */
{
for (; len > 0; len--, x++, y++) {
if ((*x!=*y) && (Tcl_UniCharToLower(*x) != Tcl_UniCharToLower(*y))) {
diff --git a/generic/regc_nfa.c b/generic/regc_nfa.c
index 48f56a9..19dbe63 100644
--- a/generic/regc_nfa.c
+++ b/generic/regc_nfa.c
@@ -2,24 +2,24 @@
* NFA utilities.
* This file is #included by regcomp.c.
*
- * Copyright (c) 1998, 1999 Henry Spencer. All rights reserved.
- *
+ * Copyright (c) 1998, 1999 Henry Spencer. All rights reserved.
+ *
* Development of this software was funded, in part, by Cray Research Inc.,
* UUNET Communications Services Inc., Sun Microsystems Inc., and Scriptics
- * Corporation, none of whom are responsible for the results. The author
- * thanks all of them.
- *
+ * Corporation, none of whom are responsible for the results. The author
+ * thanks all of them.
+ *
* Redistribution and use in source and binary forms -- with or without
* modification -- are permitted for any purpose, provided that
* redistributions in source form retain this entire copyright notice and
* indicate the origin and nature of any modifications.
- *
- * I'd appreciate being given credit for this package in the documentation
- * of software which uses it, but that is not a requirement.
- *
+ *
+ * I'd appreciate being given credit for this package in the documentation of
+ * software which uses it, but that is not a requirement.
+ *
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* HENRY SPENCER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
@@ -28,471 +28,510 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- *
- *
- * One or two things that technically ought to be in here
- * are actually in color.c, thanks to some incestuous relationships in
- * the color chains.
+ * One or two things that technically ought to be in here are actually in
+ * color.c, thanks to some incestuous relationships in the color chains.
*/
#define NISERR() VISERR(nfa->v)
#define NERR(e) VERR(nfa->v, (e))
-
-
+
/*
- newnfa - set up an NFA
^ static struct nfa *newnfa(struct vars *, struct colormap *, struct nfa *);
*/
static struct nfa * /* the NFA, or NULL */
-newnfa(v, cm, parent)
-struct vars *v;
-struct colormap *cm;
-struct nfa *parent; /* NULL if primary NFA */
+newnfa(
+ struct vars *v,
+ struct colormap *cm,
+ struct nfa *parent) /* NULL if primary NFA */
{
- struct nfa *nfa;
-
- nfa = (struct nfa *)MALLOC(sizeof(struct nfa));
- if (nfa == NULL)
- return NULL;
-
- nfa->states = NULL;
- nfa->slast = NULL;
- nfa->free = NULL;
- nfa->nstates = 0;
- nfa->cm = cm;
- nfa->v = v;
- nfa->size = 0;
- nfa->bos[0] = nfa->bos[1] = COLORLESS;
- nfa->eos[0] = nfa->eos[1] = COLORLESS;
- nfa->parent = parent;
- nfa->post = newfstate(nfa, '@'); /* number 0 */
- nfa->pre = newfstate(nfa, '>'); /* number 1 */
-
- nfa->init = newstate(nfa); /* may become invalid later */
- nfa->final = newstate(nfa);
- if (ISERR()) {
- freenfa(nfa);
- return NULL;
- }
- rainbow(nfa, nfa->cm, PLAIN, COLORLESS, nfa->pre, nfa->init);
- newarc(nfa, '^', 1, nfa->pre, nfa->init);
- newarc(nfa, '^', 0, nfa->pre, nfa->init);
- rainbow(nfa, nfa->cm, PLAIN, COLORLESS, nfa->final, nfa->post);
- newarc(nfa, '$', 1, nfa->final, nfa->post);
- newarc(nfa, '$', 0, nfa->final, nfa->post);
-
- if (ISERR()) {
- freenfa(nfa);
- return NULL;
- }
- return nfa;
-}
+ struct nfa *nfa;
+ nfa = (struct nfa *) MALLOC(sizeof(struct nfa));
+ if (nfa == NULL) {
+ return NULL;
+ }
+
+ nfa->states = NULL;
+ nfa->slast = NULL;
+ nfa->free = NULL;
+ nfa->nstates = 0;
+ nfa->cm = cm;
+ nfa->v = v;
+ nfa->size = 0;
+ nfa->bos[0] = nfa->bos[1] = COLORLESS;
+ nfa->eos[0] = nfa->eos[1] = COLORLESS;
+ nfa->parent = parent; /* Precedes newfstate so parent is valid. */
+ nfa->post = newfstate(nfa, '@'); /* number 0 */
+ nfa->pre = newfstate(nfa, '>'); /* number 1 */
+
+ nfa->init = newstate(nfa); /* May become invalid later. */
+ nfa->final = newstate(nfa);
+ if (ISERR()) {
+ freenfa(nfa);
+ return NULL;
+ }
+ rainbow(nfa, nfa->cm, PLAIN, COLORLESS, nfa->pre, nfa->init);
+ newarc(nfa, '^', 1, nfa->pre, nfa->init);
+ newarc(nfa, '^', 0, nfa->pre, nfa->init);
+ rainbow(nfa, nfa->cm, PLAIN, COLORLESS, nfa->final, nfa->post);
+ newarc(nfa, '$', 1, nfa->final, nfa->post);
+ newarc(nfa, '$', 0, nfa->final, nfa->post);
+
+ if (ISERR()) {
+ freenfa(nfa);
+ return NULL;
+ }
+ return nfa;
+}
+
/*
- - too_many_states - checks if the max states exceeds the compile-time value
- ^ static int too_many_states(struct nfa *);
+ - TooManyStates - checks if the max states exceeds the compile-time value
+ ^ static int TooManyStates(struct nfa *);
*/
static int
-too_many_states(nfa)
-struct nfa *nfa;
+TooManyStates(
+ struct nfa *nfa)
{
- struct nfa *parent = nfa->parent;
- size_t sz = nfa->size;
- while (parent != NULL) {
- sz = parent->size;
- parent = parent->parent;
- }
- if (sz > REG_MAX_STATES)
- return 1;
- return 0;
+ struct nfa *parent = nfa->parent;
+ size_t sz = nfa->size;
+
+ while (parent != NULL) {
+ sz = parent->size;
+ parent = parent->parent;
+ }
+ if (sz > REG_MAX_STATES) {
+ return 1;
+ }
+ return 0;
}
-
+
/*
- - increment_size - increases the tracked size of the NFA and its parents.
- ^ static void increment_size(struct nfa *);
+ - IncrementSize - increases the tracked size of the NFA and its parents.
+ ^ static void IncrementSize(struct nfa *);
*/
static void
-increment_size(nfa)
-struct nfa *nfa;
+IncrementSize(
+ struct nfa *nfa)
{
- struct nfa *parent = nfa->parent;
- nfa->size++;
- while (parent != NULL) {
- parent->size++;
- parent = parent->parent;
- }
-}
+ struct nfa *parent = nfa->parent;
+ nfa->size++;
+ while (parent != NULL) {
+ parent->size++;
+ parent = parent->parent;
+ }
+}
+
/*
- - decrement_size - increases the tracked size of the NFA and its parents.
- ^ static void decrement_size(struct nfa *);
+ - DecrementSize - increases the tracked size of the NFA and its parents.
+ ^ static void DecrementSize(struct nfa *);
*/
static void
-decrement_size(nfa)
-struct nfa *nfa;
+DecrementSize(
+ struct nfa *nfa)
{
- struct nfa *parent = nfa->parent;
- nfa->size--;
- while (parent != NULL) {
- parent->size--;
- parent = parent->parent;
- }
-}
+ struct nfa *parent = nfa->parent;
+ nfa->size--;
+ while (parent != NULL) {
+ parent->size--;
+ parent = parent->parent;
+ }
+}
+
/*
- freenfa - free an entire NFA
^ static VOID freenfa(struct nfa *);
*/
-static VOID
-freenfa(nfa)
-struct nfa *nfa;
+static void
+freenfa(
+ struct nfa *nfa)
{
- struct state *s;
-
- while ((s = nfa->states) != NULL) {
- s->nins = s->nouts = 0; /* don't worry about arcs */
- freestate(nfa, s);
- }
- while ((s = nfa->free) != NULL) {
- nfa->free = s->next;
- destroystate(nfa, s);
- }
+ struct state *s;
- nfa->slast = NULL;
- nfa->nstates = -1;
- nfa->pre = NULL;
- nfa->post = NULL;
- FREE(nfa);
+ while ((s = nfa->states) != NULL) {
+ s->nins = s->nouts = 0; /* don't worry about arcs */
+ freestate(nfa, s);
+ }
+ while ((s = nfa->free) != NULL) {
+ nfa->free = s->next;
+ destroystate(nfa, s);
+ }
+
+ nfa->slast = NULL;
+ nfa->nstates = -1;
+ nfa->pre = NULL;
+ nfa->post = NULL;
+ FREE(nfa);
}
-
+
/*
- newstate - allocate an NFA state, with zero flag value
^ static struct state *newstate(struct nfa *);
*/
static struct state * /* NULL on error */
-newstate(nfa)
-struct nfa *nfa;
+newstate(
+ struct nfa *nfa)
{
- struct state *s;
-
- if (too_many_states(nfa)) {
- /* XXX: add specific error for this */
- NERR(REG_ETOOBIG);
- return NULL;
- }
- if (nfa->free != NULL) {
- s = nfa->free;
- nfa->free = s->next;
- } else {
- s = (struct state *)MALLOC(sizeof(struct state));
- if (s == NULL) {
- NERR(REG_ESPACE);
- return NULL;
- }
- s->oas.next = NULL;
- s->free = NULL;
- s->noas = 0;
- }
+ struct state *s;
- assert(nfa->nstates >= 0);
- s->no = nfa->nstates++;
- s->flag = 0;
- if (nfa->states == NULL)
- nfa->states = s;
- s->nins = 0;
- s->ins = NULL;
- s->nouts = 0;
- s->outs = NULL;
- s->tmp = NULL;
- s->next = NULL;
- if (nfa->slast != NULL) {
- assert(nfa->slast->next == NULL);
- nfa->slast->next = s;
+ if (TooManyStates(nfa)) {
+ /* XXX: add specific error for this */
+ NERR(REG_ETOOBIG);
+ return NULL;
+ }
+ if (nfa->free != NULL) {
+ s = nfa->free;
+ nfa->free = s->next;
+ } else {
+ s = (struct state *) MALLOC(sizeof(struct state));
+ if (s == NULL) {
+ NERR(REG_ESPACE);
+ return NULL;
}
- s->prev = nfa->slast;
- nfa->slast = s;
- /* Track the current size and the parent size */
- increment_size(nfa);
- return s;
+ s->oas.next = NULL;
+ s->free = NULL;
+ s->noas = 0;
+ }
+
+ assert(nfa->nstates >= 0);
+ s->no = nfa->nstates++;
+ s->flag = 0;
+ if (nfa->states == NULL) {
+ nfa->states = s;
+ }
+ s->nins = 0;
+ s->ins = NULL;
+ s->nouts = 0;
+ s->outs = NULL;
+ s->tmp = NULL;
+ s->next = NULL;
+ if (nfa->slast != NULL) {
+ assert(nfa->slast->next == NULL);
+ nfa->slast->next = s;
+ }
+ s->prev = nfa->slast;
+ nfa->slast = s;
+
+ /*
+ * Track the current size and the parent size.
+ */
+
+ IncrementSize(nfa);
+ return s;
}
-
+
/*
- newfstate - allocate an NFA state with a specified flag value
^ static struct state *newfstate(struct nfa *, int flag);
*/
static struct state * /* NULL on error */
-newfstate(nfa, flag)
-struct nfa *nfa;
-int flag;
+newfstate(
+ struct nfa *nfa,
+ int flag)
{
- struct state *s;
+ struct state *s;
- s = newstate(nfa);
- if (s != NULL)
- s->flag = (char)flag;
- return s;
+ s = newstate(nfa);
+ if (s != NULL) {
+ s->flag = (char) flag;
+ }
+ return s;
}
-
+
/*
- dropstate - delete a state's inarcs and outarcs and free it
^ static VOID dropstate(struct nfa *, struct state *);
*/
-static VOID
-dropstate(nfa, s)
-struct nfa *nfa;
-struct state *s;
+static void
+dropstate(
+ struct nfa *nfa,
+ struct state *s)
{
- struct arc *a;
+ struct arc *a;
- while ((a = s->ins) != NULL)
- freearc(nfa, a);
- while ((a = s->outs) != NULL)
- freearc(nfa, a);
- freestate(nfa, s);
+ while ((a = s->ins) != NULL) {
+ freearc(nfa, a);
+ }
+ while ((a = s->outs) != NULL) {
+ freearc(nfa, a);
+ }
+ freestate(nfa, s);
}
-
+
/*
- freestate - free a state, which has no in-arcs or out-arcs
^ static VOID freestate(struct nfa *, struct state *);
*/
-static VOID
-freestate(nfa, s)
-struct nfa *nfa;
-struct state *s;
+static void
+freestate(
+ struct nfa *nfa,
+ struct state *s)
{
- assert(s != NULL);
- assert(s->nins == 0 && s->nouts == 0);
-
- s->no = FREESTATE;
- s->flag = 0;
- if (s->next != NULL)
- s->next->prev = s->prev;
- else {
- assert(s == nfa->slast);
- nfa->slast = s->prev;
- }
- if (s->prev != NULL)
- s->prev->next = s->next;
- else {
- assert(s == nfa->states);
- nfa->states = s->next;
- }
- s->prev = NULL;
- s->next = nfa->free; /* don't delete it, put it on the free list */
- nfa->free = s;
- decrement_size(nfa);
+ assert(s != NULL);
+ assert(s->nins == 0 && s->nouts == 0);
+
+ s->no = FREESTATE;
+ s->flag = 0;
+ if (s->next != NULL) {
+ s->next->prev = s->prev;
+ } else {
+ assert(s == nfa->slast);
+ nfa->slast = s->prev;
+ }
+ if (s->prev != NULL) {
+ s->prev->next = s->next;
+ } else {
+ assert(s == nfa->states);
+ nfa->states = s->next;
+ }
+ s->prev = NULL;
+ s->next = nfa->free; /* don't delete it, put it on the free list */
+ nfa->free = s;
+ DecrementSize(nfa);
}
-
+
/*
- destroystate - really get rid of an already-freed state
^ static VOID destroystate(struct nfa *, struct state *);
*/
-static VOID
-destroystate(nfa, s)
-struct nfa *nfa;
-struct state *s;
+static void
+destroystate(
+ struct nfa *nfa,
+ struct state *s)
{
- struct arcbatch *ab;
- struct arcbatch *abnext;
-
- assert(s->no == FREESTATE);
- for (ab = s->oas.next; ab != NULL; ab = abnext) {
- abnext = ab->next;
- FREE(ab);
- }
- s->ins = NULL;
- s->outs = NULL;
- s->next = NULL;
- FREE(s);
+ struct arcbatch *ab;
+ struct arcbatch *abnext;
+
+ assert(s->no == FREESTATE);
+ for (ab=s->oas.next ; ab!=NULL ; ab=abnext) {
+ abnext = ab->next;
+ FREE(ab);
+ }
+ s->ins = NULL;
+ s->outs = NULL;
+ s->next = NULL;
+ FREE(s);
}
-
+
/*
- newarc - set up a new arc within an NFA
- ^ static VOID newarc(struct nfa *, int, pcolor, struct state *,
+ ^ static VOID newarc(struct nfa *, int, pcolor, struct state *,
^ struct state *);
*/
-static VOID
-newarc(nfa, t, co, from, to)
-struct nfa *nfa;
-int t;
-pcolor co;
-struct state *from;
-struct state *to;
+static void
+newarc(
+ struct nfa *nfa,
+ int t,
+ pcolor co,
+ struct state *from,
+ struct state *to)
{
- struct arc *a;
-
- assert(from != NULL && to != NULL);
+ struct arc *a;
- /* check for duplicates */
- for (a = from->outs; a != NULL; a = a->outchain)
- if (a->to == to && a->co == co && a->type == t)
- return;
-
- a = allocarc(nfa, from);
- if (NISERR())
- return;
- assert(a != NULL);
-
- a->type = t;
- a->co = (color)co;
- a->to = to;
- a->from = from;
-
- /*
- * Put the new arc on the beginning, not the end, of the chains.
- * Not only is this easier, it has the very useful side effect that
- * deleting the most-recently-added arc is the cheapest case rather
- * than the most expensive one.
- */
- a->inchain = to->ins;
- to->ins = a;
- a->outchain = from->outs;
- from->outs = a;
+ assert(from != NULL && to != NULL);
- from->nouts++;
- to->nins++;
+ /*
+ * Check for duplicates.
+ */
- if (COLORED(a) && nfa->parent == NULL)
- colorchain(nfa->cm, a);
+ for (a=from->outs ; a!=NULL ; a=a->outchain) {
+ if (a->to == to && a->co == co && a->type == t) {
+ return;
+ }
+ }
+ a = allocarc(nfa, from);
+ if (NISERR()) {
return;
+ }
+ assert(a != NULL);
+
+ a->type = t;
+ a->co = (color) co;
+ a->to = to;
+ a->from = from;
+
+ /*
+ * Put the new arc on the beginning, not the end, of the chains. Not only
+ * is this easier, it has the very useful side effect that deleting the
+ * most-recently-added arc is the cheapest case rather than the most
+ * expensive one.
+ */
+
+ a->inchain = to->ins;
+ to->ins = a;
+ a->outchain = from->outs;
+ from->outs = a;
+
+ from->nouts++;
+ to->nins++;
+
+ if (COLORED(a) && nfa->parent == NULL) {
+ colorchain(nfa->cm, a);
+ }
}
-
+
/*
- allocarc - allocate a new out-arc within a state
^ static struct arc *allocarc(struct nfa *, struct state *);
*/
static struct arc * /* NULL for failure */
-allocarc(nfa, s)
-struct nfa *nfa;
-struct state *s;
+allocarc(
+ struct nfa *nfa,
+ struct state *s)
{
- struct arc *a;
- struct arcbatch *new;
- int i;
+ struct arc *a;
- /* shortcut */
- if (s->free == NULL && s->noas < ABSIZE) {
- a = &s->oas.a[s->noas];
- s->noas++;
- return a;
- }
+ /*
+ * Shortcut
+ */
- /* if none at hand, get more */
- if (s->free == NULL) {
- new = (struct arcbatch *)MALLOC(sizeof(struct arcbatch));
- if (new == NULL) {
- NERR(REG_ESPACE);
- return NULL;
- }
- new->next = s->oas.next;
- s->oas.next = new;
+ if (s->free == NULL && s->noas < ABSIZE) {
+ a = &s->oas.a[s->noas];
+ s->noas++;
+ return a;
+ }
- for (i = 0; i < ABSIZE; i++) {
- new->a[i].type = 0;
- new->a[i].freechain = &new->a[i+1];
- }
- new->a[ABSIZE-1].freechain = NULL;
- s->free = &new->a[0];
+ /*
+ * if none at hand, get more
+ */
+
+ if (s->free == NULL) {
+ struct arcbatch *newAb = (struct arcbatch *)
+ MALLOC(sizeof(struct arcbatch));
+ int i;
+
+ if (newAb == NULL) {
+ NERR(REG_ESPACE);
+ return NULL;
}
- assert(s->free != NULL);
+ newAb->next = s->oas.next;
+ s->oas.next = newAb;
- a = s->free;
- s->free = a->freechain;
- return a;
+ for (i=0 ; i<ABSIZE ; i++) {
+ newAb->a[i].type = 0;
+ newAb->a[i].freechain = &newAb->a[i+1];
+ }
+ newAb->a[ABSIZE-1].freechain = NULL;
+ s->free = &newAb->a[0];
+ }
+ assert(s->free != NULL);
+
+ a = s->free;
+ s->free = a->freechain;
+ return a;
}
-
+
/*
- freearc - free an arc
^ static VOID freearc(struct nfa *, struct arc *);
*/
-static VOID
-freearc(nfa, victim)
-struct nfa *nfa;
-struct arc *victim;
+static void
+freearc(
+ struct nfa *nfa,
+ struct arc *victim)
{
- struct state *from = victim->from;
- struct state *to = victim->to;
- struct arc *a;
-
- assert(victim->type != 0);
-
- /* take it off color chain if necessary */
- if (COLORED(victim) && nfa->parent == NULL)
- uncolorchain(nfa->cm, victim);
-
- /* take it off source's out-chain */
- assert(from != NULL);
- assert(from->outs != NULL);
- a = from->outs;
- if (a == victim) /* simple case: first in chain */
- from->outs = victim->outchain;
- else {
- for (; a != NULL && a->outchain != victim; a = a->outchain)
- continue;
- assert(a != NULL);
- a->outchain = victim->outchain;
+ struct state *from = victim->from;
+ struct state *to = victim->to;
+ struct arc *a;
+
+ assert(victim->type != 0);
+
+ /*
+ * Take it off color chain if necessary.
+ */
+
+ if (COLORED(victim) && nfa->parent == NULL) {
+ uncolorchain(nfa->cm, victim);
+ }
+
+ /*
+ * Take it off source's out-chain.
+ */
+
+ assert(from != NULL);
+ assert(from->outs != NULL);
+ a = from->outs;
+ if (a == victim) { /* simple case: first in chain */
+ from->outs = victim->outchain;
+ } else {
+ for (; a!=NULL && a->outchain!=victim ; a=a->outchain) {
+ continue;
}
- from->nouts--;
-
- /* take it off target's in-chain */
- assert(to != NULL);
- assert(to->ins != NULL);
- a = to->ins;
- if (a == victim) /* simple case: first in chain */
- to->ins = victim->inchain;
- else {
- for (; a != NULL && a->inchain != victim; a = a->inchain)
- continue;
- assert(a != NULL);
- a->inchain = victim->inchain;
+ assert(a != NULL);
+ a->outchain = victim->outchain;
+ }
+ from->nouts--;
+
+ /*
+ * Take it off target's in-chain.
+ */
+
+ assert(to != NULL);
+ assert(to->ins != NULL);
+ a = to->ins;
+ if (a == victim) { /* simple case: first in chain */
+ to->ins = victim->inchain;
+ } else {
+ for (; a->inchain!=victim ; a=a->inchain) {
+ assert(a->inchain != NULL);
+ continue;
}
- to->nins--;
-
- /* clean up and place on free list */
- victim->type = 0;
- victim->from = NULL; /* precautions... */
- victim->to = NULL;
- victim->inchain = NULL;
- victim->outchain = NULL;
- victim->freechain = from->free;
- from->free = victim;
+ a->inchain = victim->inchain;
+ }
+ to->nins--;
+
+ /*
+ * Clean up and place on free list.
+ */
+
+ victim->type = 0;
+ victim->from = NULL; /* precautions... */
+ victim->to = NULL;
+ victim->inchain = NULL;
+ victim->outchain = NULL;
+ victim->freechain = from->free;
+ from->free = victim;
}
-
+
/*
- findarc - find arc, if any, from given source with given type and color
* If there is more than one such arc, the result is random.
^ static struct arc *findarc(struct state *, int, pcolor);
*/
static struct arc *
-findarc(s, type, co)
-struct state *s;
-int type;
-pcolor co;
+findarc(
+ struct state *s,
+ int type,
+ pcolor co)
{
- struct arc *a;
+ struct arc *a;
- for (a = s->outs; a != NULL; a = a->outchain)
- if (a->type == type && a->co == co)
- return a;
- return NULL;
+ for (a=s->outs ; a!=NULL ; a=a->outchain) {
+ if (a->type == type && a->co == co) {
+ return a;
+ }
+ }
+ return NULL;
}
-
+
/*
- cparc - allocate a new arc within an NFA, copying details from old one
- ^ static VOID cparc(struct nfa *, struct arc *, struct state *,
+ ^ static VOID cparc(struct nfa *, struct arc *, struct state *,
^ struct state *);
*/
-static VOID
-cparc(nfa, oa, from, to)
-struct nfa *nfa;
-struct arc *oa;
-struct state *from;
-struct state *to;
+static void
+cparc(
+ struct nfa *nfa,
+ struct arc *oa,
+ struct state *from,
+ struct state *to)
{
- newarc(nfa, oa->type, oa->co, from, to);
+ newarc(nfa, oa->type, oa->co, from, to);
}
-
+
/*
- moveins - move all in arcs of a state to another state
* You might think this could be done better by just updating the
@@ -501,341 +540,365 @@ struct state *to;
* ones to exploit the suppression built into newarc.
^ static VOID moveins(struct nfa *, struct state *, struct state *);
*/
-static VOID
-moveins(nfa, old, new)
-struct nfa *nfa;
-struct state *old;
-struct state *new;
+static void
+moveins(
+ struct nfa *nfa,
+ struct state *oldState,
+ struct state *newState)
{
- struct arc *a;
+ struct arc *a;
- assert(old != new);
+ assert(oldState != newState);
- while ((a = old->ins) != NULL) {
- cparc(nfa, a, a->from, new);
- freearc(nfa, a);
- }
- assert(old->nins == 0);
- assert(old->ins == NULL);
+ while ((a = oldState->ins) != NULL) {
+ cparc(nfa, a, a->from, newState);
+ freearc(nfa, a);
+ }
+ assert(oldState->nins == 0);
+ assert(oldState->ins == NULL);
}
-
+
/*
- copyins - copy all in arcs of a state to another state
^ static VOID copyins(struct nfa *, struct state *, struct state *);
*/
-static VOID
-copyins(nfa, old, new)
-struct nfa *nfa;
-struct state *old;
-struct state *new;
+static void
+copyins(
+ struct nfa *nfa,
+ struct state *oldState,
+ struct state *newState)
{
- struct arc *a;
+ struct arc *a;
- assert(old != new);
+ assert(oldState != newState);
- for (a = old->ins; a != NULL; a = a->inchain)
- cparc(nfa, a, a->from, new);
+ for (a=oldState->ins ; a!=NULL ; a=a->inchain) {
+ cparc(nfa, a, a->from, newState);
+ }
}
-
+
/*
- moveouts - move all out arcs of a state to another state
^ static VOID moveouts(struct nfa *, struct state *, struct state *);
*/
-static VOID
-moveouts(nfa, old, new)
-struct nfa *nfa;
-struct state *old;
-struct state *new;
+static void
+moveouts(
+ struct nfa *nfa,
+ struct state *oldState,
+ struct state *newState)
{
- struct arc *a;
+ struct arc *a;
- assert(old != new);
+ assert(oldState != newState);
- while ((a = old->outs) != NULL) {
- cparc(nfa, a, new, a->to);
- freearc(nfa, a);
- }
+ while ((a = oldState->outs) != NULL) {
+ cparc(nfa, a, newState, a->to);
+ freearc(nfa, a);
+ }
}
-
+
/*
- copyouts - copy all out arcs of a state to another state
^ static VOID copyouts(struct nfa *, struct state *, struct state *);
*/
-static VOID
-copyouts(nfa, old, new)
-struct nfa *nfa;
-struct state *old;
-struct state *new;
+static void
+copyouts(
+ struct nfa *nfa,
+ struct state *oldState,
+ struct state *newState)
{
- struct arc *a;
+ struct arc *a;
- assert(old != new);
+ assert(oldState != newState);
- for (a = old->outs; a != NULL; a = a->outchain)
- cparc(nfa, a, new, a->to);
+ for (a=oldState->outs ; a!=NULL ; a=a->outchain) {
+ cparc(nfa, a, newState, a->to);
+ }
}
-
+
/*
- cloneouts - copy out arcs of a state to another state pair, modifying type
^ static VOID cloneouts(struct nfa *, struct state *, struct state *,
^ struct state *, int);
*/
-static VOID
-cloneouts(nfa, old, from, to, type)
-struct nfa *nfa;
-struct state *old;
-struct state *from;
-struct state *to;
-int type;
+static void
+cloneouts(
+ struct nfa *nfa,
+ struct state *old,
+ struct state *from,
+ struct state *to,
+ int type)
{
- struct arc *a;
+ struct arc *a;
- assert(old != from);
+ assert(old != from);
- for (a = old->outs; a != NULL; a = a->outchain)
- newarc(nfa, type, a->co, from, to);
+ for (a=old->outs ; a!=NULL ; a=a->outchain) {
+ newarc(nfa, type, a->co, from, to);
+ }
}
-
+
/*
- delsub - delete a sub-NFA, updating subre pointers if necessary
* This uses a recursive traversal of the sub-NFA, marking already-seen
* states using their tmp pointer.
^ static VOID delsub(struct nfa *, struct state *, struct state *);
*/
-static VOID
-delsub(nfa, lp, rp)
-struct nfa *nfa;
-struct state *lp; /* the sub-NFA goes from here... */
-struct state *rp; /* ...to here, *not* inclusive */
+static void
+delsub(
+ struct nfa *nfa,
+ struct state *lp, /* the sub-NFA goes from here... */
+ struct state *rp) /* ...to here, *not* inclusive */
{
- assert(lp != rp);
+ assert(lp != rp);
- rp->tmp = rp; /* mark end */
+ rp->tmp = rp; /* mark end */
- deltraverse(nfa, lp, lp);
- assert(lp->nouts == 0 && rp->nins == 0); /* did the job */
- assert(lp->no != FREESTATE && rp->no != FREESTATE); /* no more */
+ deltraverse(nfa, lp, lp);
+ assert(lp->nouts == 0 && rp->nins == 0); /* did the job */
+ assert(lp->no != FREESTATE && rp->no != FREESTATE); /* no more */
- rp->tmp = NULL; /* unmark end */
- lp->tmp = NULL; /* and begin, marked by deltraverse */
+ rp->tmp = NULL; /* unmark end */
+ lp->tmp = NULL; /* and begin, marked by deltraverse */
}
-
+
/*
- deltraverse - the recursive heart of delsub
* This routine's basic job is to destroy all out-arcs of the state.
^ static VOID deltraverse(struct nfa *, struct state *, struct state *);
*/
-static VOID
-deltraverse(nfa, leftend, s)
-struct nfa *nfa;
-struct state *leftend;
-struct state *s;
+static void
+deltraverse(
+ struct nfa *nfa,
+ struct state *leftend,
+ struct state *s)
{
- struct arc *a;
- struct state *to;
-
- if (s->nouts == 0)
- return; /* nothing to do */
- if (s->tmp != NULL)
- return; /* already in progress */
-
- s->tmp = s; /* mark as in progress */
-
- while ((a = s->outs) != NULL) {
- to = a->to;
- deltraverse(nfa, leftend, to);
- assert(to->nouts == 0 || to->tmp != NULL);
- freearc(nfa, a);
- if (to->nins == 0 && to->tmp == NULL) {
- assert(to->nouts == 0);
- freestate(nfa, to);
- }
+ struct arc *a;
+ struct state *to;
+
+ if (s->nouts == 0) {
+ return; /* nothing to do */
+ }
+ if (s->tmp != NULL) {
+ return; /* already in progress */
+ }
+
+ s->tmp = s; /* mark as in progress */
+
+ while ((a = s->outs) != NULL) {
+ to = a->to;
+ deltraverse(nfa, leftend, to);
+ assert(to->nouts == 0 || to->tmp != NULL);
+ freearc(nfa, a);
+ if (to->nins == 0 && to->tmp == NULL) {
+ assert(to->nouts == 0);
+ freestate(nfa, to);
}
+ }
- assert(s->no != FREESTATE); /* we're still here */
- assert(s == leftend || s->nins != 0); /* and still reachable */
- assert(s->nouts == 0); /* but have no outarcs */
+ assert(s->no != FREESTATE); /* we're still here */
+ assert(s == leftend || s->nins != 0); /* and still reachable */
+ assert(s->nouts == 0); /* but have no outarcs */
- s->tmp = NULL; /* we're done here */
+ s->tmp = NULL; /* we're done here */
}
-
+
/*
- dupnfa - duplicate sub-NFA
- * Another recursive traversal, this time using tmp to point to duplicates
- * as well as mark already-seen states. (You knew there was a reason why
- * it's a state pointer, didn't you? :-))
- ^ static VOID dupnfa(struct nfa *, struct state *, struct state *,
+ * Another recursive traversal, this time using tmp to point to duplicates as
+ * well as mark already-seen states. (You knew there was a reason why it's a
+ * state pointer, didn't you? :-))
+ ^ static VOID dupnfa(struct nfa *, struct state *, struct state *,
^ struct state *, struct state *);
*/
-static VOID
-dupnfa(nfa, start, stop, from, to)
-struct nfa *nfa;
-struct state *start; /* duplicate of subNFA starting here */
-struct state *stop; /* and stopping here */
-struct state *from; /* stringing duplicate from here */
-struct state *to; /* to here */
+static void
+dupnfa(
+ struct nfa *nfa,
+ struct state *start, /* duplicate of subNFA starting here */
+ struct state *stop, /* and stopping here */
+ struct state *from, /* stringing duplicate from here */
+ struct state *to) /* to here */
{
- if (start == stop) {
- newarc(nfa, EMPTY, 0, from, to);
- return;
- }
+ if (start == stop) {
+ newarc(nfa, EMPTY, 0, from, to);
+ return;
+ }
- stop->tmp = to;
- duptraverse(nfa, start, from);
- /* done, except for clearing out the tmp pointers */
+ stop->tmp = to;
+ duptraverse(nfa, start, from);
+ /* done, except for clearing out the tmp pointers */
- stop->tmp = NULL;
- cleartraverse(nfa, start);
+ stop->tmp = NULL;
+ cleartraverse(nfa, start);
}
-
+
/*
- duptraverse - recursive heart of dupnfa
^ static VOID duptraverse(struct nfa *, struct state *, struct state *);
*/
-static VOID
-duptraverse(nfa, s, stmp)
-struct nfa *nfa;
-struct state *s;
-struct state *stmp; /* s's duplicate, or NULL */
+static void
+duptraverse(
+ struct nfa *nfa,
+ struct state *s,
+ struct state *stmp) /* s's duplicate, or NULL */
{
- struct arc *a;
+ struct arc *a;
- if (s->tmp != NULL)
- return; /* already done */
+ if (s->tmp != NULL) {
+ return; /* already done */
+ }
- s->tmp = (stmp == NULL) ? newstate(nfa) : stmp;
- if (s->tmp == NULL) {
- assert(NISERR());
- return;
- }
+ s->tmp = (stmp == NULL) ? newstate(nfa) : stmp;
+ if (s->tmp == NULL) {
+ assert(NISERR());
+ return;
+ }
- for (a = s->outs; a != NULL && !NISERR(); a = a->outchain) {
- duptraverse(nfa, a->to, (struct state *)NULL);
- if (NISERR())
- break;
- assert(a->to->tmp != NULL);
- cparc(nfa, a, s->tmp, a->to->tmp);
+ for (a=s->outs ; a!=NULL && !NISERR() ; a=a->outchain) {
+ duptraverse(nfa, a->to, NULL);
+ if (NISERR()) {
+ break;
}
+ assert(a->to->tmp != NULL);
+ cparc(nfa, a, s->tmp, a->to->tmp);
+ }
}
-
+
/*
- cleartraverse - recursive cleanup for algorithms that leave tmp ptrs set
^ static VOID cleartraverse(struct nfa *, struct state *);
*/
-static VOID
-cleartraverse(nfa, s)
-struct nfa *nfa;
-struct state *s;
+static void
+cleartraverse(
+ struct nfa *nfa,
+ struct state *s)
{
- struct arc *a;
+ struct arc *a;
- if (s->tmp == NULL)
- return;
- s->tmp = NULL;
+ if (s->tmp == NULL) {
+ return;
+ }
+ s->tmp = NULL;
- for (a = s->outs; a != NULL; a = a->outchain)
- cleartraverse(nfa, a->to);
+ for (a=s->outs ; a!=NULL ; a=a->outchain) {
+ cleartraverse(nfa, a->to);
+ }
}
-
+
/*
- specialcolors - fill in special colors for an NFA
^ static VOID specialcolors(struct nfa *);
*/
-static VOID
-specialcolors(nfa)
-struct nfa *nfa;
+static void
+specialcolors(
+ struct nfa *nfa)
{
- /* false colors for BOS, BOL, EOS, EOL */
- if (nfa->parent == NULL) {
- nfa->bos[0] = pseudocolor(nfa->cm);
- nfa->bos[1] = pseudocolor(nfa->cm);
- nfa->eos[0] = pseudocolor(nfa->cm);
- nfa->eos[1] = pseudocolor(nfa->cm);
- } else {
- assert(nfa->parent->bos[0] != COLORLESS);
- nfa->bos[0] = nfa->parent->bos[0];
- assert(nfa->parent->bos[1] != COLORLESS);
- nfa->bos[1] = nfa->parent->bos[1];
- assert(nfa->parent->eos[0] != COLORLESS);
- nfa->eos[0] = nfa->parent->eos[0];
- assert(nfa->parent->eos[1] != COLORLESS);
- nfa->eos[1] = nfa->parent->eos[1];
- }
+ /*
+ * False colors for BOS, BOL, EOS, EOL
+ */
+
+ if (nfa->parent == NULL) {
+ nfa->bos[0] = pseudocolor(nfa->cm);
+ nfa->bos[1] = pseudocolor(nfa->cm);
+ nfa->eos[0] = pseudocolor(nfa->cm);
+ nfa->eos[1] = pseudocolor(nfa->cm);
+ } else {
+ assert(nfa->parent->bos[0] != COLORLESS);
+ nfa->bos[0] = nfa->parent->bos[0];
+ assert(nfa->parent->bos[1] != COLORLESS);
+ nfa->bos[1] = nfa->parent->bos[1];
+ assert(nfa->parent->eos[0] != COLORLESS);
+ nfa->eos[0] = nfa->parent->eos[0];
+ assert(nfa->parent->eos[1] != COLORLESS);
+ nfa->eos[1] = nfa->parent->eos[1];
+ }
}
-
+
/*
- optimize - optimize an NFA
^ static long optimize(struct nfa *, FILE *);
*/
static long /* re_info bits */
-optimize(nfa, f)
-struct nfa *nfa;
-FILE *f; /* for debug output; NULL none */
+optimize(
+ struct nfa *nfa,
+ FILE *f) /* for debug output; NULL none */
{
- int verbose = (f != NULL) ? 1 : 0;
-
- if (verbose)
- fprintf(f, "\ninitial cleanup:\n");
- cleanup(nfa); /* may simplify situation */
- if (verbose)
- dumpnfa(nfa, f);
- if (verbose)
- fprintf(f, "\nempties:\n");
- fixempties(nfa, f); /* get rid of EMPTY arcs */
- if (verbose)
- fprintf(f, "\nconstraints:\n");
- pullback(nfa, f); /* pull back constraints backward */
- pushfwd(nfa, f); /* push fwd constraints forward */
- if (verbose)
- fprintf(f, "\nfinal cleanup:\n");
- cleanup(nfa); /* final tidying */
- return analyze(nfa); /* and analysis */
+ int verbose = (f != NULL) ? 1 : 0;
+
+ if (verbose) {
+ fprintf(f, "\ninitial cleanup:\n");
+ }
+ cleanup(nfa); /* may simplify situation */
+ if (verbose) {
+ dumpnfa(nfa, f);
+ }
+ if (verbose) {
+ fprintf(f, "\nempties:\n");
+ }
+ fixempties(nfa, f); /* get rid of EMPTY arcs */
+ if (verbose) {
+ fprintf(f, "\nconstraints:\n");
+ }
+ pullback(nfa, f); /* pull back constraints backward */
+ pushfwd(nfa, f); /* push fwd constraints forward */
+ if (verbose) {
+ fprintf(f, "\nfinal cleanup:\n");
+ }
+ cleanup(nfa); /* final tidying */
+ return analyze(nfa); /* and analysis */
}
-
+
/*
- pullback - pull back constraints backward to (with luck) eliminate them
^ static VOID pullback(struct nfa *, FILE *);
*/
-static VOID
-pullback(nfa, f)
-struct nfa *nfa;
-FILE *f; /* for debug output; NULL none */
+static void
+pullback(
+ struct nfa *nfa,
+ FILE *f) /* for debug output; NULL none */
{
- struct state *s;
- struct state *nexts;
- struct arc *a;
- struct arc *nexta;
- int progress;
-
- /* find and pull until there are no more */
- do {
- progress = 0;
- for (s = nfa->states; s != NULL && !NISERR(); s = nexts) {
- nexts = s->next;
- for (a = s->outs; a != NULL && !NISERR(); a = nexta) {
- nexta = a->outchain;
- if (a->type == '^' || a->type == BEHIND)
- if (pull(nfa, a))
- progress = 1;
- assert(nexta == NULL || s->no != FREESTATE);
- }
- }
- if (progress && f != NULL)
- dumpnfa(nfa, f);
- } while (progress && !NISERR());
- if (NISERR())
- return;
-
- for (a = nfa->pre->outs; a != NULL; a = nexta) {
+ struct state *s;
+ struct state *nexts;
+ struct arc *a;
+ struct arc *nexta;
+ int progress;
+
+ /*
+ * Find and pull until there are no more.
+ */
+
+ do {
+ progress = 0;
+ for (s=nfa->states ; s!=NULL && !NISERR() ; s=nexts) {
+ nexts = s->next;
+ for (a=s->outs ; a!=NULL && !NISERR() ; a=nexta) {
nexta = a->outchain;
- if (a->type == '^') {
- assert(a->co == 0 || a->co == 1);
- newarc(nfa, PLAIN, nfa->bos[a->co], a->from, a->to);
- freearc(nfa, a);
+ if (a->type == '^' || a->type == BEHIND) {
+ if (pull(nfa, a)) {
+ progress = 1;
+ }
}
+ assert(nexta == NULL || s->no != FREESTATE);
+ }
}
+ if (progress && f != NULL) {
+ dumpnfa(nfa, f);
+ }
+ } while (progress && !NISERR());
+ if (NISERR()) {
+ return;
+ }
+
+ for (a=nfa->pre->outs ; a!=NULL ; a=nexta) {
+ nexta = a->outchain;
+ if (a->type == '^') {
+ assert(a->co == 0 || a->co == 1);
+ newarc(nfa, PLAIN, nfa->bos[a->co], a->from, a->to);
+ freearc(nfa, a);
+ }
+ }
}
-
+
/*
- pull - pull a back constraint backward past its source state
* A significant property of this function is that it deletes at most
@@ -844,136 +907,155 @@ FILE *f; /* for debug output; NULL none */
^ static int pull(struct nfa *, struct arc *);
*/
static int /* 0 couldn't, 1 could */
-pull(nfa, con)
-struct nfa *nfa;
-struct arc *con;
+pull(
+ struct nfa *nfa,
+ struct arc *con)
{
- struct state *from = con->from;
- struct state *to = con->to;
- struct arc *a;
- struct arc *nexta;
- struct state *s;
-
- if (from == to) { /* circular constraint is pointless */
- freearc(nfa, con);
- return 1;
- }
- if (from->flag) /* can't pull back beyond start */
- return 0;
- if (from->nins == 0) { /* unreachable */
- freearc(nfa, con);
- return 1;
- }
+ struct state *from = con->from;
+ struct state *to = con->to;
+ struct arc *a;
+ struct arc *nexta;
+ struct state *s;
+
+ if (from == to) { /* circular constraint is pointless */
+ freearc(nfa, con);
+ return 1;
+ }
+ if (from->flag) { /* can't pull back beyond start */
+ return 0;
+ }
+ if (from->nins == 0) { /* unreachable */
+ freearc(nfa, con);
+ return 1;
+ }
- /*
- * DGP 2007-11-15: Cloning a state with a circular constraint on its
- * list of outs can lead to trouble [Bug 1810038], so get rid of them
- * first.
- */
+ /*
+ * DGP 2007-11-15: Cloning a state with a circular constraint on its list
+ * of outs can lead to trouble [Bug 1810038], so get rid of them first.
+ */
- for (a = from->outs; a != NULL; a = nexta) {
- nexta = a->outchain;
- switch (a->type) {
- case '^':
- case '$':
- case BEHIND:
- case AHEAD:
- if (from == a->to) {
- freearc(nfa, a);
- }
- break;
- }
+ for (a = from->outs; a != NULL; a = nexta) {
+ nexta = a->outchain;
+ switch (a->type) {
+ case '^':
+ case '$':
+ case BEHIND:
+ case AHEAD:
+ if (from == a->to) {
+ freearc(nfa, a);
+ }
+ break;
}
+ }
- /* first, clone from state if necessary to avoid other outarcs */
- if (from->nouts > 1) {
- s = newstate(nfa);
- if (NISERR())
- return 0;
- assert(to != from); /* con is not an inarc */
- copyins(nfa, from, s); /* duplicate inarcs */
- cparc(nfa, con, s, to); /* move constraint arc */
- freearc(nfa, con);
- from = s;
- con = from->outs;
- }
- assert(from->nouts == 1);
+ /*
+ * First, clone from state if necessary to avoid other outarcs.
+ */
- /* propagate the constraint into the from state's inarcs */
- for (a = from->ins; a != NULL; a = nexta) {
- nexta = a->inchain;
- switch (combine(con, a)) {
- case INCOMPATIBLE: /* destroy the arc */
- freearc(nfa, a);
- break;
- case SATISFIED: /* no action needed */
- break;
- case COMPATIBLE: /* swap the two arcs, more or less */
- s = newstate(nfa);
- if (NISERR())
- return 0;
- cparc(nfa, a, s, to); /* anticipate move */
- cparc(nfa, con, a->from, s);
- if (NISERR())
- return 0;
- freearc(nfa, a);
- break;
- default:
- assert(NOTREACHED);
- break;
- }
+ if (from->nouts > 1) {
+ s = newstate(nfa);
+ if (NISERR()) {
+ return 0;
}
+ assert(to != from); /* con is not an inarc */
+ copyins(nfa, from, s); /* duplicate inarcs */
+ cparc(nfa, con, s, to); /* move constraint arc */
+ freearc(nfa, con);
+ from = s;
+ con = from->outs;
+ }
+ assert(from->nouts == 1);
+
+ /*
+ * Propagate the constraint into the from state's inarcs.
+ */
+
+ for (a=from->ins ; a!=NULL ; a=nexta) {
+ nexta = a->inchain;
+ switch (combine(con, a)) {
+ case INCOMPATIBLE: /* destroy the arc */
+ freearc(nfa, a);
+ break;
+ case SATISFIED: /* no action needed */
+ break;
+ case COMPATIBLE: /* swap the two arcs, more or less */
+ s = newstate(nfa);
+ if (NISERR()) {
+ return 0;
+ }
+ cparc(nfa, a, s, to); /* anticipate move */
+ cparc(nfa, con, a->from, s);
+ if (NISERR()) {
+ return 0;
+ }
+ freearc(nfa, a);
+ break;
+ default:
+ assert(NOTREACHED);
+ break;
+ }
+ }
- /* remaining inarcs, if any, incorporate the constraint */
- moveins(nfa, from, to);
- dropstate(nfa, from); /* will free the constraint */
- return 1;
-}
+ /*
+ * Remaining inarcs, if any, incorporate the constraint.
+ */
+ moveins(nfa, from, to);
+ dropstate(nfa, from); /* will free the constraint */
+ return 1;
+}
+
/*
- pushfwd - push forward constraints forward to (with luck) eliminate them
^ static VOID pushfwd(struct nfa *, FILE *);
*/
-static VOID
-pushfwd(nfa, f)
-struct nfa *nfa;
-FILE *f; /* for debug output; NULL none */
+static void
+pushfwd(
+ struct nfa *nfa,
+ FILE *f) /* for debug output; NULL none */
{
- struct state *s;
- struct state *nexts;
- struct arc *a;
- struct arc *nexta;
- int progress;
-
- /* find and push until there are no more */
- do {
- progress = 0;
- for (s = nfa->states; s != NULL && !NISERR(); s = nexts) {
- nexts = s->next;
- for (a = s->ins; a != NULL && !NISERR(); a = nexta) {
- nexta = a->inchain;
- if (a->type == '$' || a->type == AHEAD)
- if (push(nfa, a))
- progress = 1;
- assert(nexta == NULL || s->no != FREESTATE);
- }
- }
- if (progress && f != NULL)
- dumpnfa(nfa, f);
- } while (progress && !NISERR());
- if (NISERR())
- return;
-
- for (a = nfa->post->ins; a != NULL; a = nexta) {
+ struct state *s;
+ struct state *nexts;
+ struct arc *a;
+ struct arc *nexta;
+ int progress;
+
+ /*
+ * Find and push until there are no more.
+ */
+
+ do {
+ progress = 0;
+ for (s=nfa->states ; s!=NULL && !NISERR() ; s=nexts) {
+ nexts = s->next;
+ for (a = s->ins; a != NULL && !NISERR(); a = nexta) {
nexta = a->inchain;
- if (a->type == '$') {
- assert(a->co == 0 || a->co == 1);
- newarc(nfa, PLAIN, nfa->eos[a->co], a->from, a->to);
- freearc(nfa, a);
+ if (a->type == '$' || a->type == AHEAD) {
+ if (push(nfa, a)) {
+ progress = 1;
+ }
}
+ assert(nexta == NULL || s->no != FREESTATE);
+ }
+ }
+ if (progress && f != NULL) {
+ dumpnfa(nfa, f);
}
+ } while (progress && !NISERR());
+ if (NISERR()) {
+ return;
+ }
+
+ for (a = nfa->post->ins; a != NULL; a = nexta) {
+ nexta = a->inchain;
+ if (a->type == '$') {
+ assert(a->co == 0 || a->co == 1);
+ newarc(nfa, PLAIN, nfa->eos[a->co], a->from, a->to);
+ freearc(nfa, a);
+ }
+ }
}
-
+
/*
- push - push a forward constraint forward past its destination state
* A significant property of this function is that it deletes at most
@@ -982,94 +1064,106 @@ FILE *f; /* for debug output; NULL none */
^ static int push(struct nfa *, struct arc *);
*/
static int /* 0 couldn't, 1 could */
-push(nfa, con)
-struct nfa *nfa;
-struct arc *con;
+push(
+ struct nfa *nfa,
+ struct arc *con)
{
- struct state *from = con->from;
- struct state *to = con->to;
- struct arc *a;
- struct arc *nexta;
- struct state *s;
-
- if (to == from) { /* circular constraint is pointless */
- freearc(nfa, con);
- return 1;
- }
- if (to->flag) /* can't push forward beyond end */
- return 0;
- if (to->nouts == 0) { /* dead end */
- freearc(nfa, con);
- return 1;
+ struct state *from = con->from;
+ struct state *to = con->to;
+ struct arc *a;
+ struct arc *nexta;
+ struct state *s;
+
+ if (to == from) { /* circular constraint is pointless */
+ freearc(nfa, con);
+ return 1;
+ }
+ if (to->flag) { /* can't push forward beyond end */
+ return 0;
+ }
+ if (to->nouts == 0) { /* dead end */
+ freearc(nfa, con);
+ return 1;
+ }
+
+ /*
+ * DGP 2007-11-15: Here we duplicate the same protections as appear
+ * in pull() above to avoid troubles with cloning a state with a
+ * circular constraint on its list of ins. It is not clear whether
+ * this is necessary, or is protecting against a "can't happen".
+ * Any test case that actually leads to a freearc() call here would
+ * be a welcome addition to the test suite.
+ */
+
+ for (a = to->ins; a != NULL; a = nexta) {
+ nexta = a->inchain;
+ switch (a->type) {
+ case '^':
+ case '$':
+ case BEHIND:
+ case AHEAD:
+ if (a->from == to) {
+ freearc(nfa, a);
+ }
+ break;
}
+ }
+ /*
+ * First, clone to state if necessary to avoid other inarcs.
+ */
- /*
- * DGP 2007-11-15: Here we duplicate the same protections as appear
- * in pull() above to avoid troubles with cloning a state with a
- * circular constraint on its list of ins. It is not clear whether
- * this is necessary, or is protecting against a "can't happen".
- * Any test case that actually leads to a freearc() call here would
- * be a welcome addition to the test suite.
- */
-
- for (a = to->ins; a != NULL; a = nexta) {
- nexta = a->inchain;
- switch (a->type) {
- case '^':
- case '$':
- case BEHIND:
- case AHEAD:
- if (a->from == to) {
- freearc(nfa, a);
- }
- break;
- }
+ if (to->nins > 1) {
+ s = newstate(nfa);
+ if (NISERR()) {
+ return 0;
}
-
- /* first, clone to state if necessary to avoid other inarcs */
- if (to->nins > 1) {
- s = newstate(nfa);
- if (NISERR())
- return 0;
- copyouts(nfa, to, s); /* duplicate outarcs */
- cparc(nfa, con, from, s); /* move constraint */
- freearc(nfa, con);
- to = s;
- con = to->ins;
+ copyouts(nfa, to, s); /* duplicate outarcs */
+ cparc(nfa, con, from, s); /* move constraint */
+ freearc(nfa, con);
+ to = s;
+ con = to->ins;
+ }
+ assert(to->nins == 1);
+
+ /*
+ * Propagate the constraint into the to state's outarcs.
+ */
+
+ for (a = to->outs; a != NULL; a = nexta) {
+ nexta = a->outchain;
+ switch (combine(con, a)) {
+ case INCOMPATIBLE: /* destroy the arc */
+ freearc(nfa, a);
+ break;
+ case SATISFIED: /* no action needed */
+ break;
+ case COMPATIBLE: /* swap the two arcs, more or less */
+ s = newstate(nfa);
+ if (NISERR()) {
+ return 0;
+ }
+ cparc(nfa, con, s, a->to); /* anticipate move */
+ cparc(nfa, a, from, s);
+ if (NISERR()) {
+ return 0;
+ }
+ freearc(nfa, a);
+ break;
+ default:
+ assert(NOTREACHED);
+ break;
}
- assert(to->nins == 1);
+ }
- /* propagate the constraint into the to state's outarcs */
- for (a = to->outs; a != NULL; a = nexta) {
- nexta = a->outchain;
- switch (combine(con, a)) {
- case INCOMPATIBLE: /* destroy the arc */
- freearc(nfa, a);
- break;
- case SATISFIED: /* no action needed */
- break;
- case COMPATIBLE: /* swap the two arcs, more or less */
- s = newstate(nfa);
- if (NISERR())
- return 0;
- cparc(nfa, con, s, a->to); /* anticipate move */
- cparc(nfa, a, from, s);
- if (NISERR())
- return 0;
- freearc(nfa, a);
- break;
- default:
- assert(NOTREACHED);
- break;
- }
- }
+ /*
+ * Remaining outarcs, if any, incorporate the constraint.
+ */
- /* remaining outarcs, if any, incorporate the constraint */
- moveouts(nfa, to, from);
- dropstate(nfa, to); /* will free the constraint */
- return 1;
+ moveouts(nfa, to, from);
+ dropstate(nfa, to); /* will free the constraint */
+ return 1;
}
-
+
/*
- combine - constraint lands on an arc, what happens?
^ #def INCOMPATIBLE 1 // destroys arc
@@ -1078,397 +1172,450 @@ struct arc *con;
^ static int combine(struct arc *, struct arc *);
*/
static int
-combine(con, a)
-struct arc *con;
-struct arc *a;
+combine(
+ struct arc *con,
+ struct arc *a)
{
-# define CA(ct,at) (((ct)<<CHAR_BIT) | (at))
-
- switch (CA(con->type, a->type)) {
- case CA('^', PLAIN): /* newlines are handled separately */
- case CA('$', PLAIN):
- return INCOMPATIBLE;
- break;
- case CA(AHEAD, PLAIN): /* color constraints meet colors */
- case CA(BEHIND, PLAIN):
- if (con->co == a->co)
- return SATISFIED;
- return INCOMPATIBLE;
- break;
- case CA('^', '^'): /* collision, similar constraints */
- case CA('$', '$'):
- case CA(AHEAD, AHEAD):
- case CA(BEHIND, BEHIND):
- if (con->co == a->co) /* true duplication */
- return SATISFIED;
- return INCOMPATIBLE;
- break;
- case CA('^', BEHIND): /* collision, dissimilar constraints */
- case CA(BEHIND, '^'):
- case CA('$', AHEAD):
- case CA(AHEAD, '$'):
- return INCOMPATIBLE;
- break;
- case CA('^', '$'): /* constraints passing each other */
- case CA('^', AHEAD):
- case CA(BEHIND, '$'):
- case CA(BEHIND, AHEAD):
- case CA('$', '^'):
- case CA('$', BEHIND):
- case CA(AHEAD, '^'):
- case CA(AHEAD, BEHIND):
- case CA('^', LACON):
- case CA(BEHIND, LACON):
- case CA('$', LACON):
- case CA(AHEAD, LACON):
- return COMPATIBLE;
- break;
+#define CA(ct,at) (((ct)<<CHAR_BIT) | (at))
+
+ switch (CA(con->type, a->type)) {
+ case CA('^', PLAIN): /* newlines are handled separately */
+ case CA('$', PLAIN):
+ return INCOMPATIBLE;
+ break;
+ case CA(AHEAD, PLAIN): /* color constraints meet colors */
+ case CA(BEHIND, PLAIN):
+ if (con->co == a->co) {
+ return SATISFIED;
+ }
+ return INCOMPATIBLE;
+ break;
+ case CA('^', '^'): /* collision, similar constraints */
+ case CA('$', '$'):
+ case CA(AHEAD, AHEAD):
+ case CA(BEHIND, BEHIND):
+ if (con->co == a->co) { /* true duplication */
+ return SATISFIED;
}
- assert(NOTREACHED);
- return INCOMPATIBLE; /* for benefit of blind compilers */
+ return INCOMPATIBLE;
+ break;
+ case CA('^', BEHIND): /* collision, dissimilar constraints */
+ case CA(BEHIND, '^'):
+ case CA('$', AHEAD):
+ case CA(AHEAD, '$'):
+ return INCOMPATIBLE;
+ break;
+ case CA('^', '$'): /* constraints passing each other */
+ case CA('^', AHEAD):
+ case CA(BEHIND, '$'):
+ case CA(BEHIND, AHEAD):
+ case CA('$', '^'):
+ case CA('$', BEHIND):
+ case CA(AHEAD, '^'):
+ case CA(AHEAD, BEHIND):
+ case CA('^', LACON):
+ case CA(BEHIND, LACON):
+ case CA('$', LACON):
+ case CA(AHEAD, LACON):
+ return COMPATIBLE;
+ break;
+ }
+ assert(NOTREACHED);
+ return INCOMPATIBLE; /* for benefit of blind compilers */
}
-
+
/*
- fixempties - get rid of EMPTY arcs
^ static VOID fixempties(struct nfa *, FILE *);
*/
-static VOID
-fixempties(nfa, f)
-struct nfa *nfa;
-FILE *f; /* for debug output; NULL none */
+static void
+fixempties(
+ struct nfa *nfa,
+ FILE *f) /* for debug output; NULL none */
{
- struct state *s;
- struct state *nexts;
- struct arc *a;
- struct arc *nexta;
- int progress;
-
- /* find and eliminate empties until there are no more */
- do {
- progress = 0;
- for (s = nfa->states; s != NULL && !NISERR()
- && s->no != FREESTATE; s = nexts) {
- nexts = s->next;
- for (a = s->outs; a != NULL && !NISERR(); a = nexta) {
- nexta = a->outchain;
- if (a->type == EMPTY && unempty(nfa, a))
- progress = 1;
- assert(nexta == NULL || s->no != FREESTATE);
- }
+ struct state *s;
+ struct state *nexts;
+ struct arc *a;
+ struct arc *nexta;
+ int progress;
+
+ /*
+ * Find and eliminate empties until there are no more.
+ */
+
+ do {
+ progress = 0;
+ for (s = nfa->states; s != NULL && !NISERR()
+ && s->no != FREESTATE; s = nexts) {
+ nexts = s->next;
+ for (a = s->outs; a != NULL && !NISERR(); a = nexta) {
+ nexta = a->outchain;
+ if (a->type == EMPTY && unempty(nfa, a)) {
+ progress = 1;
}
- if (progress && f != NULL)
- dumpnfa(nfa, f);
- } while (progress && !NISERR());
+ assert(nexta == NULL || s->no != FREESTATE);
+ }
+ }
+ if (progress && f != NULL) {
+ dumpnfa(nfa, f);
+ }
+ } while (progress && !NISERR());
}
-
+
/*
- unempty - optimize out an EMPTY arc, if possible
- * Actually, as it stands this function always succeeds, but the return
- * value is kept with an eye on possible future changes.
+ * Actually, as it stands this function always succeeds, but the return value
+ * is kept with an eye on possible future changes.
^ static int unempty(struct nfa *, struct arc *);
*/
static int /* 0 couldn't, 1 could */
-unempty(nfa, a)
-struct nfa *nfa;
-struct arc *a;
+unempty(
+ struct nfa *nfa,
+ struct arc *a)
{
- struct state *from = a->from;
- struct state *to = a->to;
- int usefrom; /* work on from, as opposed to to? */
+ struct state *from = a->from;
+ struct state *to = a->to;
+ int usefrom; /* work on from, as opposed to to? */
- assert(a->type == EMPTY);
- assert(from != nfa->pre && to != nfa->post);
+ assert(a->type == EMPTY);
+ assert(from != nfa->pre && to != nfa->post);
- if (from == to) { /* vacuous loop */
- freearc(nfa, a);
- return 1;
+ if (from == to) { /* vacuous loop */
+ freearc(nfa, a);
+ return 1;
+ }
+
+ /*
+ * Decide which end to work on.
+ */
+
+ usefrom = 1; /* default: attack from */
+ if (from->nouts > to->nins) {
+ usefrom = 0;
+ } else if (from->nouts == to->nins) {
+ /*
+ * Decide on secondary issue: move/copy fewest arcs.
+ */
+
+ if (from->nins > to->nouts) {
+ usefrom = 0;
}
+ }
- /* decide which end to work on */
- usefrom = 1; /* default: attack from */
- if (from->nouts > to->nins)
- usefrom = 0;
- else if (from->nouts == to->nins) {
- /* decide on secondary issue: move/copy fewest arcs */
- if (from->nins > to->nouts)
- usefrom = 0;
+ freearc(nfa, a);
+ if (usefrom) {
+ if (from->nouts == 0) {
+ /*
+ * Was the state's only outarc.
+ */
+
+ moveins(nfa, from, to);
+ freestate(nfa, from);
+ } else {
+ copyins(nfa, from, to);
}
-
- freearc(nfa, a);
- if (usefrom) {
- if (from->nouts == 0) {
- /* was the state's only outarc */
- moveins(nfa, from, to);
- freestate(nfa, from);
- } else
- copyins(nfa, from, to);
+ } else {
+ if (to->nins == 0) {
+ /*
+ * Was the state's only inarc.
+ */
+
+ moveouts(nfa, to, from);
+ freestate(nfa, to);
} else {
- if (to->nins == 0) {
- /* was the state's only inarc */
- moveouts(nfa, to, from);
- freestate(nfa, to);
- } else
- copyouts(nfa, to, from);
+ copyouts(nfa, to, from);
}
+ }
- return 1;
+ return 1;
}
-
+
/*
- cleanup - clean up NFA after optimizations
^ static VOID cleanup(struct nfa *);
*/
-static VOID
-cleanup(nfa)
-struct nfa *nfa;
+static void
+cleanup(
+ struct nfa *nfa)
{
- struct state *s;
- struct state *nexts;
- int n;
-
- /* clear out unreachable or dead-end states */
- /* use pre to mark reachable, then post to mark can-reach-post */
- markreachable(nfa, nfa->pre, (struct state *)NULL, nfa->pre);
- markcanreach(nfa, nfa->post, nfa->pre, nfa->post);
- for (s = nfa->states; s != NULL; s = nexts) {
- nexts = s->next;
- if (s->tmp != nfa->post && !s->flag)
- dropstate(nfa, s);
+ struct state *s;
+ struct state *nexts;
+ int n;
+
+ /*
+ * Clear out unreachable or dead-end states. Use pre to mark reachable,
+ * then post to mark can-reach-post.
+ */
+
+ markreachable(nfa, nfa->pre, NULL, nfa->pre);
+ markcanreach(nfa, nfa->post, nfa->pre, nfa->post);
+ for (s = nfa->states; s != NULL; s = nexts) {
+ nexts = s->next;
+ if (s->tmp != nfa->post && !s->flag) {
+ dropstate(nfa, s);
}
- assert(nfa->post->nins == 0 || nfa->post->tmp == nfa->post);
- cleartraverse(nfa, nfa->pre);
- assert(nfa->post->nins == 0 || nfa->post->tmp == NULL);
- /* the nins==0 (final unreachable) case will be caught later */
-
- /* renumber surviving states */
- n = 0;
- for (s = nfa->states; s != NULL; s = s->next)
- s->no = n++;
- nfa->nstates = n;
+ }
+ assert(nfa->post->nins == 0 || nfa->post->tmp == nfa->post);
+ cleartraverse(nfa, nfa->pre);
+ assert(nfa->post->nins == 0 || nfa->post->tmp == NULL);
+ /* the nins==0 (final unreachable) case will be caught later */
+
+ /*
+ * Renumber surviving states.
+ */
+
+ n = 0;
+ for (s = nfa->states; s != NULL; s = s->next) {
+ s->no = n++;
+ }
+ nfa->nstates = n;
}
-
+
/*
- markreachable - recursive marking of reachable states
^ static VOID markreachable(struct nfa *, struct state *, struct state *,
^ struct state *);
*/
-static VOID
-markreachable(nfa, s, okay, mark)
-struct nfa *nfa;
-struct state *s;
-struct state *okay; /* consider only states with this mark */
-struct state *mark; /* the value to mark with */
+static void
+markreachable(
+ struct nfa *nfa,
+ struct state *s,
+ struct state *okay, /* consider only states with this mark */
+ struct state *mark) /* the value to mark with */
{
- struct arc *a;
+ struct arc *a;
- if (s->tmp != okay)
- return;
- s->tmp = mark;
+ if (s->tmp != okay) {
+ return;
+ }
+ s->tmp = mark;
- for (a = s->outs; a != NULL; a = a->outchain)
- markreachable(nfa, a->to, okay, mark);
+ for (a = s->outs; a != NULL; a = a->outchain) {
+ markreachable(nfa, a->to, okay, mark);
+ }
}
-
+
/*
- markcanreach - recursive marking of states which can reach here
^ static VOID markcanreach(struct nfa *, struct state *, struct state *,
^ struct state *);
*/
-static VOID
-markcanreach(nfa, s, okay, mark)
-struct nfa *nfa;
-struct state *s;
-struct state *okay; /* consider only states with this mark */
-struct state *mark; /* the value to mark with */
+static void
+markcanreach(
+ struct nfa *nfa,
+ struct state *s,
+ struct state *okay, /* consider only states with this mark */
+ struct state *mark) /* the value to mark with */
{
- struct arc *a;
+ struct arc *a;
- if (s->tmp != okay)
- return;
- s->tmp = mark;
+ if (s->tmp != okay) {
+ return;
+ }
+ s->tmp = mark;
- for (a = s->ins; a != NULL; a = a->inchain)
- markcanreach(nfa, a->from, okay, mark);
+ for (a = s->ins; a != NULL; a = a->inchain) {
+ markcanreach(nfa, a->from, okay, mark);
+ }
}
-
+
/*
- analyze - ascertain potentially-useful facts about an optimized NFA
^ static long analyze(struct nfa *);
*/
static long /* re_info bits to be ORed in */
-analyze(nfa)
-struct nfa *nfa;
+analyze(
+ struct nfa *nfa)
{
- struct arc *a;
- struct arc *aa;
-
- if (nfa->pre->outs == NULL)
- return REG_UIMPOSSIBLE;
- for (a = nfa->pre->outs; a != NULL; a = a->outchain)
- for (aa = a->to->outs; aa != NULL; aa = aa->outchain)
- if (aa->to == nfa->post)
- return REG_UEMPTYMATCH;
- return 0;
+ struct arc *a;
+ struct arc *aa;
+
+ if (nfa->pre->outs == NULL) {
+ return REG_UIMPOSSIBLE;
+ }
+ for (a = nfa->pre->outs; a != NULL; a = a->outchain) {
+ for (aa = a->to->outs; aa != NULL; aa = aa->outchain) {
+ if (aa->to == nfa->post) {
+ return REG_UEMPTYMATCH;
+ }
+ }
+ }
+ return 0;
}
-
+
/*
- compact - compact an NFA
^ static VOID compact(struct nfa *, struct cnfa *);
*/
-static VOID
-compact(nfa, cnfa)
-struct nfa *nfa;
-struct cnfa *cnfa;
+static void
+compact(
+ struct nfa *nfa,
+ struct cnfa *cnfa)
{
- struct state *s;
- struct arc *a;
- size_t nstates;
- size_t narcs;
- struct carc *ca;
- struct carc *first;
-
- assert (!NISERR());
-
- nstates = 0;
- narcs = 0;
- for (s = nfa->states; s != NULL; s = s->next) {
- nstates++;
- narcs += 1 + s->nouts + 1;
- /* 1 as a fake for flags, nouts for arcs, 1 as endmarker */
+ struct state *s;
+ struct arc *a;
+ size_t nstates;
+ size_t narcs;
+ struct carc *ca;
+ struct carc *first;
+
+ assert(!NISERR());
+
+ nstates = 0;
+ narcs = 0;
+ for (s = nfa->states; s != NULL; s = s->next) {
+ nstates++;
+ narcs += 1 + s->nouts + 1;
+ /* 1 as a fake for flags, nouts for arcs, 1 as endmarker */
+ }
+
+ cnfa->states = (struct carc **) MALLOC(nstates * sizeof(struct carc *));
+ cnfa->arcs = (struct carc *) MALLOC(narcs * sizeof(struct carc));
+ if (cnfa->states == NULL || cnfa->arcs == NULL) {
+ if (cnfa->states != NULL) {
+ FREE(cnfa->states);
}
-
- cnfa->states = (struct carc **)MALLOC(nstates * sizeof(struct carc *));
- cnfa->arcs = (struct carc *)MALLOC(narcs * sizeof(struct carc));
- if (cnfa->states == NULL || cnfa->arcs == NULL) {
- if (cnfa->states != NULL)
- FREE(cnfa->states);
- if (cnfa->arcs != NULL)
- FREE(cnfa->arcs);
- NERR(REG_ESPACE);
- return;
+ if (cnfa->arcs != NULL) {
+ FREE(cnfa->arcs);
}
- cnfa->nstates = nstates;
- cnfa->pre = nfa->pre->no;
- cnfa->post = nfa->post->no;
- cnfa->bos[0] = nfa->bos[0];
- cnfa->bos[1] = nfa->bos[1];
- cnfa->eos[0] = nfa->eos[0];
- cnfa->eos[1] = nfa->eos[1];
- cnfa->ncolors = maxcolor(nfa->cm) + 1;
- cnfa->flags = 0;
-
- ca = cnfa->arcs;
- for (s = nfa->states; s != NULL; s = s->next) {
- assert((size_t)s->no < nstates);
- cnfa->states[s->no] = ca;
- ca->co = 0; /* clear and skip flags "arc" */
+ NERR(REG_ESPACE);
+ return;
+ }
+ cnfa->nstates = nstates;
+ cnfa->pre = nfa->pre->no;
+ cnfa->post = nfa->post->no;
+ cnfa->bos[0] = nfa->bos[0];
+ cnfa->bos[1] = nfa->bos[1];
+ cnfa->eos[0] = nfa->eos[0];
+ cnfa->eos[1] = nfa->eos[1];
+ cnfa->ncolors = maxcolor(nfa->cm) + 1;
+ cnfa->flags = 0;
+
+ ca = cnfa->arcs;
+ for (s = nfa->states; s != NULL; s = s->next) {
+ assert((size_t) s->no < nstates);
+ cnfa->states[s->no] = ca;
+ ca->co = 0; /* clear and skip flags "arc" */
+ ca++;
+ first = ca;
+ for (a = s->outs; a != NULL; a = a->outchain) {
+ switch (a->type) {
+ case PLAIN:
+ ca->co = a->co;
+ ca->to = a->to->no;
ca++;
- first = ca;
- for (a = s->outs; a != NULL; a = a->outchain)
- switch (a->type) {
- case PLAIN:
- ca->co = a->co;
- ca->to = a->to->no;
- ca++;
- break;
- case LACON:
- assert(s->no != cnfa->pre);
- ca->co = (color)(cnfa->ncolors + a->co);
- ca->to = a->to->no;
- ca++;
- cnfa->flags |= HASLACONS;
- break;
- default:
- assert(NOTREACHED);
- break;
- }
- carcsort(first, ca-1);
- ca->co = COLORLESS;
- ca->to = 0;
+ break;
+ case LACON:
+ assert(s->no != cnfa->pre);
+ ca->co = (color) (cnfa->ncolors + a->co);
+ ca->to = a->to->no;
ca++;
+ cnfa->flags |= HASLACONS;
+ break;
+ default:
+ assert(NOTREACHED);
+ break;
+ }
}
- assert(ca == &cnfa->arcs[narcs]);
- assert(cnfa->nstates != 0);
-
- /* mark no-progress states */
- for (a = nfa->pre->outs; a != NULL; a = a->outchain)
- cnfa->states[a->to->no]->co = 1;
- cnfa->states[nfa->pre->no]->co = 1;
+ carcsort(first, ca-1);
+ ca->co = COLORLESS;
+ ca->to = 0;
+ ca++;
+ }
+ assert(ca == &cnfa->arcs[narcs]);
+ assert(cnfa->nstates != 0);
+
+ /*
+ * Mark no-progress states.
+ */
+
+ for (a = nfa->pre->outs; a != NULL; a = a->outchain) {
+ cnfa->states[a->to->no]->co = 1;
+ }
+ cnfa->states[nfa->pre->no]->co = 1;
}
-
+
/*
- carcsort - sort compacted-NFA arcs by color
* Really dumb algorithm, but if the list is long enough for that to matter,
* you're in real trouble anyway.
^ static VOID carcsort(struct carc *, struct carc *);
*/
-static VOID
-carcsort(first, last)
-struct carc *first;
-struct carc *last;
+static void
+carcsort(
+ struct carc *first,
+ struct carc *last)
{
- struct carc *p;
- struct carc *q;
- struct carc tmp;
-
- if (last - first <= 1)
- return;
-
- for (p = first; p <= last; p++)
- for (q = p; q <= last; q++)
- if (p->co > q->co ||
- (p->co == q->co && p->to > q->to)) {
- assert(p != q);
- tmp = *p;
- *p = *q;
- *q = tmp;
- }
-}
+ struct carc *p;
+ struct carc *q;
+ struct carc tmp;
+ if (last - first <= 1) {
+ return;
+ }
+
+ for (p = first; p <= last; p++) {
+ for (q = p; q <= last; q++) {
+ if (p->co > q->co || (p->co == q->co && p->to > q->to)) {
+ assert(p != q);
+ tmp = *p;
+ *p = *q;
+ *q = tmp;
+ }
+ }
+ }
+}
+
/*
- freecnfa - free a compacted NFA
^ static VOID freecnfa(struct cnfa *);
*/
-static VOID
-freecnfa(cnfa)
-struct cnfa *cnfa;
+static void
+freecnfa(
+ struct cnfa *cnfa)
{
- assert(cnfa->nstates != 0); /* not empty already */
- cnfa->nstates = 0;
- FREE(cnfa->states);
- FREE(cnfa->arcs);
+ assert(cnfa->nstates != 0); /* not empty already */
+ cnfa->nstates = 0;
+ FREE(cnfa->states);
+ FREE(cnfa->arcs);
}
-
+
/*
- dumpnfa - dump an NFA in human-readable form
^ static VOID dumpnfa(struct nfa *, FILE *);
*/
-static VOID
-dumpnfa(nfa, f)
-struct nfa *nfa;
-FILE *f;
+static void
+dumpnfa(
+ struct nfa *nfa,
+ FILE *f)
{
#ifdef REG_DEBUG
- struct state *s;
-
- fprintf(f, "pre %d, post %d", nfa->pre->no, nfa->post->no);
- if (nfa->bos[0] != COLORLESS)
- fprintf(f, ", bos [%ld]", (long)nfa->bos[0]);
- if (nfa->bos[1] != COLORLESS)
- fprintf(f, ", bol [%ld]", (long)nfa->bos[1]);
- if (nfa->eos[0] != COLORLESS)
- fprintf(f, ", eos [%ld]", (long)nfa->eos[0]);
- if (nfa->eos[1] != COLORLESS)
- fprintf(f, ", eol [%ld]", (long)nfa->eos[1]);
- fprintf(f, "\n");
- for (s = nfa->states; s != NULL; s = s->next)
- dumpstate(s, f);
- if (nfa->parent == NULL)
- dumpcolors(nfa->cm, f);
- fflush(f);
+ struct state *s;
+
+ fprintf(f, "pre %d, post %d", nfa->pre->no, nfa->post->no);
+ if (nfa->bos[0] != COLORLESS) {
+ fprintf(f, ", bos [%ld]", (long) nfa->bos[0]);
+ }
+ if (nfa->bos[1] != COLORLESS) {
+ fprintf(f, ", bol [%ld]", (long) nfa->bos[1]);
+ }
+ if (nfa->eos[0] != COLORLESS) {
+ fprintf(f, ", eos [%ld]", (long) nfa->eos[0]);
+ }
+ if (nfa->eos[1] != COLORLESS) {
+ fprintf(f, ", eol [%ld]", (long) nfa->eos[1]);
+ }
+ fprintf(f, "\n");
+ for (s = nfa->states; s != NULL; s = s->next) {
+ dumpstate(s, f);
+ }
+ if (nfa->parent == NULL) {
+ dumpcolors(nfa->cm, f);
+ }
+ fflush(f);
#endif
}
-
+
#ifdef REG_DEBUG /* subordinates of dumpnfa */
/*
^ #ifdef REG_DEBUG
@@ -1478,165 +1625,185 @@ FILE *f;
- dumpstate - dump an NFA state in human-readable form
^ static VOID dumpstate(struct state *, FILE *);
*/
-static VOID
-dumpstate(s, f)
-struct state *s;
-FILE *f;
+static void
+dumpstate(
+ struct state *s,
+ FILE *f)
{
- struct arc *a;
-
- fprintf(f, "%d%s%c", s->no, (s->tmp != NULL) ? "T" : "",
- (s->flag) ? s->flag : '.');
- if (s->prev != NULL && s->prev->next != s)
- fprintf(f, "\tstate chain bad\n");
- if (s->nouts == 0)
- fprintf(f, "\tno out arcs\n");
- else
- dumparcs(s, f);
- fflush(f);
- for (a = s->ins; a != NULL; a = a->inchain) {
- if (a->to != s)
- fprintf(f, "\tlink from %d to %d on %d's in-chain\n",
- a->from->no, a->to->no, s->no);
+ struct arc *a;
+
+ fprintf(f, "%d%s%c", s->no, (s->tmp != NULL) ? "T" : "",
+ (s->flag) ? s->flag : '.');
+ if (s->prev != NULL && s->prev->next != s) {
+ fprintf(f, "\tstate chain bad\n");
+ }
+ if (s->nouts == 0) {
+ fprintf(f, "\tno out arcs\n");
+ } else {
+ dumparcs(s, f);
+ }
+ fflush(f);
+ for (a = s->ins; a != NULL; a = a->inchain) {
+ if (a->to != s) {
+ fprintf(f, "\tlink from %d to %d on %d's in-chain\n",
+ a->from->no, a->to->no, s->no);
}
+ }
}
-
+
/*
- dumparcs - dump out-arcs in human-readable form
^ static VOID dumparcs(struct state *, FILE *);
*/
-static VOID
-dumparcs(s, f)
-struct state *s;
-FILE *f;
+static void
+dumparcs(
+ struct state *s,
+ FILE *f)
{
- int pos;
+ int pos;
- assert(s->nouts > 0);
- /* printing arcs in reverse order is usually clearer */
- pos = dumprarcs(s->outs, s, f, 1);
- if (pos != 1)
- fprintf(f, "\n");
+ assert(s->nouts > 0);
+ /* printing arcs in reverse order is usually clearer */
+ pos = dumprarcs(s->outs, s, f, 1);
+ if (pos != 1) {
+ fprintf(f, "\n");
+ }
}
-
+
/*
- dumprarcs - dump remaining outarcs, recursively, in reverse order
^ static int dumprarcs(struct arc *, struct state *, FILE *, int);
*/
static int /* resulting print position */
-dumprarcs(a, s, f, pos)
-struct arc *a;
-struct state *s;
-FILE *f;
-int pos; /* initial print position */
+dumprarcs(
+ struct arc *a,
+ struct state *s,
+ FILE *f,
+ int pos) /* initial print position */
{
- if (a->outchain != NULL)
- pos = dumprarcs(a->outchain, s, f, pos);
- dumparc(a, s, f);
- if (pos == 5) {
- fprintf(f, "\n");
- pos = 1;
- } else
- pos++;
- return pos;
+ if (a->outchain != NULL) {
+ pos = dumprarcs(a->outchain, s, f, pos);
+ }
+ dumparc(a, s, f);
+ if (pos == 5) {
+ fprintf(f, "\n");
+ pos = 1;
+ } else {
+ pos++;
+ }
+ return pos;
}
-
+
/*
- dumparc - dump one outarc in readable form, including prefixing tab
^ static VOID dumparc(struct arc *, struct state *, FILE *);
*/
-static VOID
-dumparc(a, s, f)
-struct arc *a;
-struct state *s;
-FILE *f;
+static void
+dumparc(
+ struct arc *a,
+ struct state *s,
+ FILE *f)
{
- struct arc *aa;
- struct arcbatch *ab;
-
- fprintf(f, "\t");
- switch (a->type) {
- case PLAIN:
- fprintf(f, "[%ld]", (long)a->co);
- break;
- case AHEAD:
- fprintf(f, ">%ld>", (long)a->co);
- break;
- case BEHIND:
- fprintf(f, "<%ld<", (long)a->co);
- break;
- case LACON:
- fprintf(f, ":%ld:", (long)a->co);
- break;
- case '^':
- case '$':
- fprintf(f, "%c%d", a->type, (int)a->co);
- break;
- case EMPTY:
- break;
- default:
- fprintf(f, "0x%x/0%lo", a->type, (long)a->co);
- break;
+ struct arc *aa;
+ struct arcbatch *ab;
+
+ fprintf(f, "\t");
+ switch (a->type) {
+ case PLAIN:
+ fprintf(f, "[%ld]", (long) a->co);
+ break;
+ case AHEAD:
+ fprintf(f, ">%ld>", (long) a->co);
+ break;
+ case BEHIND:
+ fprintf(f, "<%ld<", (long) a->co);
+ break;
+ case LACON:
+ fprintf(f, ":%ld:", (long) a->co);
+ break;
+ case '^':
+ case '$':
+ fprintf(f, "%c%d", a->type, (int) a->co);
+ break;
+ case EMPTY:
+ break;
+ default:
+ fprintf(f, "0x%x/0%lo", a->type, (long) a->co);
+ break;
+ }
+ if (a->from != s) {
+ fprintf(f, "?%d?", a->from->no);
+ }
+ for (ab = &a->from->oas; ab != NULL; ab = ab->next) {
+ for (aa = &ab->a[0]; aa < &ab->a[ABSIZE]; aa++) {
+ if (aa == a) {
+ break; /* NOTE BREAK OUT */
+ }
}
- if (a->from != s)
- fprintf(f, "?%d?", a->from->no);
- for (ab = &a->from->oas; ab != NULL; ab = ab->next) {
- for (aa = &ab->a[0]; aa < &ab->a[ABSIZE]; aa++)
- if (aa == a)
- break; /* NOTE BREAK OUT */
- if (aa < &ab->a[ABSIZE]) /* propagate break */
- break; /* NOTE BREAK OUT */
+ if (aa < &ab->a[ABSIZE]) { /* propagate break */
+ break; /* NOTE BREAK OUT */
}
- if (ab == NULL)
- fprintf(f, "?!?"); /* not in allocated space */
- fprintf(f, "->");
- if (a->to == NULL) {
- fprintf(f, "NULL");
- return;
+ }
+ if (ab == NULL) {
+ fprintf(f, "?!?"); /* not in allocated space */
+ }
+ fprintf(f, "->");
+ if (a->to == NULL) {
+ fprintf(f, "NULL");
+ return;
+ }
+ fprintf(f, "%d", a->to->no);
+ for (aa = a->to->ins; aa != NULL; aa = aa->inchain) {
+ if (aa == a) {
+ break; /* NOTE BREAK OUT */
}
- fprintf(f, "%d", a->to->no);
- for (aa = a->to->ins; aa != NULL; aa = aa->inchain)
- if (aa == a)
- break; /* NOTE BREAK OUT */
- if (aa == NULL)
- fprintf(f, "?!?"); /* missing from in-chain */
+ }
+ if (aa == NULL) {
+ fprintf(f, "?!?"); /* missing from in-chain */
+ }
}
/*
^ #endif
*/
#endif /* ifdef REG_DEBUG */
-
+
/*
- dumpcnfa - dump a compacted NFA in human-readable form
^ static VOID dumpcnfa(struct cnfa *, FILE *);
*/
-static VOID
-dumpcnfa(cnfa, f)
-struct cnfa *cnfa;
-FILE *f;
+static void
+dumpcnfa(
+ struct cnfa *cnfa,
+ FILE *f)
{
#ifdef REG_DEBUG
- int st;
-
- fprintf(f, "pre %d, post %d", cnfa->pre, cnfa->post);
- if (cnfa->bos[0] != COLORLESS)
- fprintf(f, ", bos [%ld]", (long)cnfa->bos[0]);
- if (cnfa->bos[1] != COLORLESS)
- fprintf(f, ", bol [%ld]", (long)cnfa->bos[1]);
- if (cnfa->eos[0] != COLORLESS)
- fprintf(f, ", eos [%ld]", (long)cnfa->eos[0]);
- if (cnfa->eos[1] != COLORLESS)
- fprintf(f, ", eol [%ld]", (long)cnfa->eos[1]);
- if (cnfa->flags&HASLACONS)
- fprintf(f, ", haslacons");
- fprintf(f, "\n");
- for (st = 0; st < cnfa->nstates; st++)
- dumpcstate(st, cnfa->states[st], cnfa, f);
- fflush(f);
+ int st;
+
+ fprintf(f, "pre %d, post %d", cnfa->pre, cnfa->post);
+ if (cnfa->bos[0] != COLORLESS) {
+ fprintf(f, ", bos [%ld]", (long) cnfa->bos[0]);
+ }
+ if (cnfa->bos[1] != COLORLESS) {
+ fprintf(f, ", bol [%ld]", (long) cnfa->bos[1]);
+ }
+ if (cnfa->eos[0] != COLORLESS) {
+ fprintf(f, ", eos [%ld]", (long) cnfa->eos[0]);
+ }
+ if (cnfa->eos[1] != COLORLESS) {
+ fprintf(f, ", eol [%ld]", (long) cnfa->eos[1]);
+ }
+ if (cnfa->flags&HASLACONS) {
+ fprintf(f, ", haslacons");
+ }
+ fprintf(f, "\n");
+ for (st = 0; st < cnfa->nstates; st++) {
+ dumpcstate(st, cnfa->states[st], cnfa, f);
+ }
+ fflush(f);
#endif
}
-
+
#ifdef REG_DEBUG /* subordinates of dumpcnfa */
/*
^ #ifdef REG_DEBUG
@@ -1646,36 +1813,46 @@ FILE *f;
- dumpcstate - dump a compacted-NFA state in human-readable form
^ static VOID dumpcstate(int, struct carc *, struct cnfa *, FILE *);
*/
-static VOID
-dumpcstate(st, ca, cnfa, f)
-int st;
-struct carc *ca;
-struct cnfa *cnfa;
-FILE *f;
+static void
+dumpcstate(
+ int st,
+ struct carc *ca,
+ struct cnfa *cnfa,
+ FILE *f)
{
- int i;
- int pos;
-
- fprintf(f, "%d%s", st, (ca[0].co) ? ":" : ".");
- pos = 1;
- for (i = 1; ca[i].co != COLORLESS; i++) {
- if (ca[i].co < cnfa->ncolors)
- fprintf(f, "\t[%ld]->%d", (long)ca[i].co, ca[i].to);
- else
- fprintf(f, "\t:%ld:->%d", (long)ca[i].co-cnfa->ncolors,
- ca[i].to);
- if (pos == 5) {
- fprintf(f, "\n");
- pos = 1;
- } else
- pos++;
+ int i;
+ int pos;
+
+ fprintf(f, "%d%s", st, (ca[0].co) ? ":" : ".");
+ pos = 1;
+ for (i = 1; ca[i].co != COLORLESS; i++) {
+ if (ca[i].co < cnfa->ncolors) {
+ fprintf(f, "\t[%ld]->%d", (long) ca[i].co, ca[i].to);
+ } else {
+ fprintf(f, "\t:%ld:->%d", (long) ca[i].co-cnfa->ncolors,ca[i].to);
}
- if (i == 1 || pos != 1)
- fprintf(f, "\n");
- fflush(f);
+ if (pos == 5) {
+ fprintf(f, "\n");
+ pos = 1;
+ } else {
+ pos++;
+ }
+ }
+ if (i == 1 || pos != 1) {
+ fprintf(f, "\n");
+ }
+ fflush(f);
}
/*
^ #endif
*/
#endif /* ifdef REG_DEBUG */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/regcomp.c b/generic/regcomp.c
index a1fe5bc..6dea04b 100644
--- a/generic/regcomp.c
+++ b/generic/regcomp.c
@@ -2,11 +2,11 @@
* re_*comp and friends - compile REs
* This file #includes several others (see the bottom).
*
- * Copyright (c) 1998, 1999 Henry Spencer. All rights reserved.
+ * Copyright (c) 1998, 1999 Henry Spencer. All rights reserved.
*
* Development of this software was funded, in part, by Cray Research Inc.,
* UUNET Communications Services Inc., Sun Microsystems Inc., and Scriptics
- * Corporation, none of whom are responsible for the results. The author
+ * Corporation, none of whom are responsible for the results. The author
* thanks all of them.
*
* Redistribution and use in source and binary forms -- with or without
@@ -14,12 +14,12 @@
* redistributions in source form retain this entire copyright notice and
* indicate the origin and nature of any modifications.
*
- * I'd appreciate being given credit for this package in the documentation
- * of software which uses it, but that is not a requirement.
+ * I'd appreciate being given credit for this package in the documentation of
+ * software which uses it, but that is not a requirement.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* HENRY SPENCER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
@@ -38,198 +38,189 @@
/* =====^!^===== begin forwards =====^!^===== */
/* automatically gathered by fwd; do not hand-edit */
/* === regcomp.c === */
-int compile _ANSI_ARGS_((regex_t *, CONST chr *, size_t, int));
-static VOID moresubs _ANSI_ARGS_((struct vars *, int));
-static int freev _ANSI_ARGS_((struct vars *, int));
-static VOID makesearch _ANSI_ARGS_((struct vars *, struct nfa *));
-static struct subre *parse _ANSI_ARGS_((struct vars *, int, int, struct state *, struct state *));
-static struct subre *parsebranch _ANSI_ARGS_((struct vars *, int, int, struct state *, struct state *, int));
-static VOID parseqatom _ANSI_ARGS_((struct vars *, int, int, struct state *, struct state *, struct subre *));
-static VOID nonword _ANSI_ARGS_((struct vars *, int, struct state *, struct state *));
-static VOID word _ANSI_ARGS_((struct vars *, int, struct state *, struct state *));
-static int scannum _ANSI_ARGS_((struct vars *));
-static VOID repeat _ANSI_ARGS_((struct vars *, struct state *, struct state *, int, int));
-static VOID bracket _ANSI_ARGS_((struct vars *, struct state *, struct state *));
-static VOID cbracket _ANSI_ARGS_((struct vars *, struct state *, struct state *));
-static VOID brackpart _ANSI_ARGS_((struct vars *, struct state *, struct state *));
-static CONST chr *scanplain _ANSI_ARGS_((struct vars *));
-static VOID onechr _ANSI_ARGS_((struct vars *, pchr, struct state *, struct state *));
-static VOID dovec _ANSI_ARGS_((struct vars *, struct cvec *, struct state *, struct state *));
-static celt nextleader _ANSI_ARGS_((struct vars *, pchr, pchr));
-static VOID wordchrs _ANSI_ARGS_((struct vars *));
-static struct subre *subre _ANSI_ARGS_((struct vars *, int, int, struct state *, struct state *));
-static VOID freesubre _ANSI_ARGS_((struct vars *, struct subre *));
-static VOID freesrnode _ANSI_ARGS_((struct vars *, struct subre *));
-static VOID optst _ANSI_ARGS_((struct vars *, struct subre *));
-static int numst _ANSI_ARGS_((struct subre *, int));
-static VOID markst _ANSI_ARGS_((struct subre *));
-static VOID cleanst _ANSI_ARGS_((struct vars *));
-static long nfatree _ANSI_ARGS_((struct vars *, struct subre *, FILE *));
-static long nfanode _ANSI_ARGS_((struct vars *, struct subre *, FILE *));
-static int newlacon _ANSI_ARGS_((struct vars *, struct state *, struct state *, int));
-static VOID freelacons _ANSI_ARGS_((struct subre *, int));
-static VOID rfree _ANSI_ARGS_((regex_t *));
-static VOID dump _ANSI_ARGS_((regex_t *, FILE *));
-static VOID dumpst _ANSI_ARGS_((struct subre *, FILE *, int));
-static VOID stdump _ANSI_ARGS_((struct subre *, FILE *, int));
-static char *stid _ANSI_ARGS_((struct subre *, char *, size_t));
+int compile(regex_t *, const chr *, size_t, int);
+static void moresubs(struct vars *, int);
+static int freev(struct vars *, int);
+static void makesearch(struct vars *, struct nfa *);
+static struct subre *parse(struct vars *, int, int, struct state *, struct state *);
+static struct subre *parsebranch(struct vars *, int, int, struct state *, struct state *, int);
+static void parseqatom(struct vars *, int, int, struct state *, struct state *, struct subre *);
+static void nonword(struct vars *, int, struct state *, struct state *);
+static void word(struct vars *, int, struct state *, struct state *);
+static int scannum(struct vars *);
+static void repeat(struct vars *, struct state *, struct state *, int, int);
+static void bracket(struct vars *, struct state *, struct state *);
+static void cbracket(struct vars *, struct state *, struct state *);
+static void brackpart(struct vars *, struct state *, struct state *);
+static const chr *scanplain(struct vars *);
+static void onechr(struct vars *, pchr, struct state *, struct state *);
+static void dovec(struct vars *, struct cvec *, struct state *, struct state *);
+static void wordchrs(struct vars *);
+static struct subre *subre(struct vars *, int, int, struct state *, struct state *);
+static void freesubre(struct vars *, struct subre *);
+static void freesrnode(struct vars *, struct subre *);
+static void optst(struct vars *, struct subre *);
+static int numst(struct subre *, int);
+static void markst(struct subre *);
+static void cleanst(struct vars *);
+static long nfatree(struct vars *, struct subre *, FILE *);
+static long nfanode(struct vars *, struct subre *, FILE *);
+static int newlacon(struct vars *, struct state *, struct state *, int);
+static void freelacons(struct subre *, int);
+static void rfree(regex_t *);
+static void dump(regex_t *, FILE *);
+static void dumpst(struct subre *, FILE *, int);
+static void stdump(struct subre *, FILE *, int);
+static const char *stid(struct subre *, char *, size_t);
/* === regc_lex.c === */
-static VOID lexstart _ANSI_ARGS_((struct vars *));
-static VOID prefixes _ANSI_ARGS_((struct vars *));
-static VOID lexnest _ANSI_ARGS_((struct vars *, CONST chr *, CONST chr *));
-static VOID lexword _ANSI_ARGS_((struct vars *));
-static int next _ANSI_ARGS_((struct vars *));
-static int lexescape _ANSI_ARGS_((struct vars *));
-static chr lexdigits _ANSI_ARGS_((struct vars *, int, int, int));
-static int brenext _ANSI_ARGS_((struct vars *, pchr));
-static VOID skip _ANSI_ARGS_((struct vars *));
-static chr newline _ANSI_ARGS_((NOPARMS));
+static void lexstart(struct vars *);
+static void prefixes(struct vars *);
+static void lexnest(struct vars *, const chr *, const chr *);
+static void lexword(struct vars *);
+static int next(struct vars *);
+static int lexescape(struct vars *);
+static chr lexdigits(struct vars *, int, int, int);
+static int brenext(struct vars *, pchr);
+static void skip(struct vars *);
+static chr newline(NOPARMS);
#ifdef REG_DEBUG
-static CONST chr *ch _ANSI_ARGS_((NOPARMS));
+static const chr *ch(NOPARMS);
#endif
-static chr chrnamed _ANSI_ARGS_((struct vars *, CONST chr *, CONST chr *, pchr));
+static chr chrnamed(struct vars *, const chr *, const chr *, pchr);
/* === regc_color.c === */
-static VOID initcm _ANSI_ARGS_((struct vars *, struct colormap *));
-static VOID freecm _ANSI_ARGS_((struct colormap *));
-static VOID cmtreefree _ANSI_ARGS_((struct colormap *, union tree *, int));
-static color setcolor _ANSI_ARGS_((struct colormap *, pchr, pcolor));
-static color maxcolor _ANSI_ARGS_((struct colormap *));
-static color newcolor _ANSI_ARGS_((struct colormap *));
-static VOID freecolor _ANSI_ARGS_((struct colormap *, pcolor));
-static color pseudocolor _ANSI_ARGS_((struct colormap *));
-static color subcolor _ANSI_ARGS_((struct colormap *, pchr c));
-static color newsub _ANSI_ARGS_((struct colormap *, pcolor));
-static VOID subrange _ANSI_ARGS_((struct vars *, pchr, pchr, struct state *, struct state *));
-static VOID subblock _ANSI_ARGS_((struct vars *, pchr, struct state *, struct state *));
-static VOID okcolors _ANSI_ARGS_((struct nfa *, struct colormap *));
-static VOID colorchain _ANSI_ARGS_((struct colormap *, struct arc *));
-static VOID uncolorchain _ANSI_ARGS_((struct colormap *, struct arc *));
-static int singleton _ANSI_ARGS_((struct colormap *, pchr c));
-static VOID rainbow _ANSI_ARGS_((struct nfa *, struct colormap *, int, pcolor, struct state *, struct state *));
-static VOID colorcomplement _ANSI_ARGS_((struct nfa *, struct colormap *, int, struct state *, struct state *, struct state *));
+static void initcm(struct vars *, struct colormap *);
+static void freecm(struct colormap *);
+static void cmtreefree(struct colormap *, union tree *, int);
+static color setcolor(struct colormap *, pchr, pcolor);
+static color maxcolor(struct colormap *);
+static color newcolor(struct colormap *);
+static void freecolor(struct colormap *, pcolor);
+static color pseudocolor(struct colormap *);
+static color subcolor(struct colormap *, pchr c);
+static color newsub(struct colormap *, pcolor);
+static void subrange(struct vars *, pchr, pchr, struct state *, struct state *);
+static void subblock(struct vars *, pchr, struct state *, struct state *);
+static void okcolors(struct nfa *, struct colormap *);
+static void colorchain(struct colormap *, struct arc *);
+static void uncolorchain(struct colormap *, struct arc *);
+static void rainbow(struct nfa *, struct colormap *, int, pcolor, struct state *, struct state *);
+static void colorcomplement(struct nfa *, struct colormap *, int, struct state *, struct state *, struct state *);
#ifdef REG_DEBUG
-static VOID dumpcolors _ANSI_ARGS_((struct colormap *, FILE *));
-static VOID fillcheck _ANSI_ARGS_((struct colormap *, union tree *, int, FILE *));
-static VOID dumpchr _ANSI_ARGS_((pchr, FILE *));
+static void dumpcolors(struct colormap *, FILE *);
+static void fillcheck(struct colormap *, union tree *, int, FILE *);
+static void dumpchr(pchr, FILE *);
#endif
/* === regc_nfa.c === */
-static struct nfa *newnfa _ANSI_ARGS_((struct vars *, struct colormap *, struct nfa *));
-static VOID freenfa _ANSI_ARGS_((struct nfa *));
-static struct state *newstate _ANSI_ARGS_((struct nfa *));
-static struct state *newfstate _ANSI_ARGS_((struct nfa *, int flag));
-static VOID dropstate _ANSI_ARGS_((struct nfa *, struct state *));
-static VOID freestate _ANSI_ARGS_((struct nfa *, struct state *));
-static VOID destroystate _ANSI_ARGS_((struct nfa *, struct state *));
-static VOID newarc _ANSI_ARGS_((struct nfa *, int, pcolor, struct state *, struct state *));
-static struct arc *allocarc _ANSI_ARGS_((struct nfa *, struct state *));
-static VOID freearc _ANSI_ARGS_((struct nfa *, struct arc *));
-static struct arc *findarc _ANSI_ARGS_((struct state *, int, pcolor));
-static VOID cparc _ANSI_ARGS_((struct nfa *, struct arc *, struct state *, struct state *));
-static VOID moveins _ANSI_ARGS_((struct nfa *, struct state *, struct state *));
-static VOID copyins _ANSI_ARGS_((struct nfa *, struct state *, struct state *));
-static VOID moveouts _ANSI_ARGS_((struct nfa *, struct state *, struct state *));
-static VOID copyouts _ANSI_ARGS_((struct nfa *, struct state *, struct state *));
-static VOID cloneouts _ANSI_ARGS_((struct nfa *, struct state *, struct state *, struct state *, int));
-static VOID delsub _ANSI_ARGS_((struct nfa *, struct state *, struct state *));
-static VOID deltraverse _ANSI_ARGS_((struct nfa *, struct state *, struct state *));
-static VOID dupnfa _ANSI_ARGS_((struct nfa *, struct state *, struct state *, struct state *, struct state *));
-static VOID duptraverse _ANSI_ARGS_((struct nfa *, struct state *, struct state *));
-static VOID cleartraverse _ANSI_ARGS_((struct nfa *, struct state *));
-static VOID specialcolors _ANSI_ARGS_((struct nfa *));
-static long optimize _ANSI_ARGS_((struct nfa *, FILE *));
-static VOID pullback _ANSI_ARGS_((struct nfa *, FILE *));
-static int pull _ANSI_ARGS_((struct nfa *, struct arc *));
-static VOID pushfwd _ANSI_ARGS_((struct nfa *, FILE *));
-static int push _ANSI_ARGS_((struct nfa *, struct arc *));
+static struct nfa *newnfa(struct vars *, struct colormap *, struct nfa *);
+static void freenfa(struct nfa *);
+static struct state *newstate(struct nfa *);
+static struct state *newfstate(struct nfa *, int flag);
+static void dropstate(struct nfa *, struct state *);
+static void freestate(struct nfa *, struct state *);
+static void destroystate(struct nfa *, struct state *);
+static void newarc(struct nfa *, int, pcolor, struct state *, struct state *);
+static struct arc *allocarc(struct nfa *, struct state *);
+static void freearc(struct nfa *, struct arc *);
+static struct arc *findarc(struct state *, int, pcolor);
+static void cparc(struct nfa *, struct arc *, struct state *, struct state *);
+static void moveins(struct nfa *, struct state *, struct state *);
+static void copyins(struct nfa *, struct state *, struct state *);
+static void moveouts(struct nfa *, struct state *, struct state *);
+static void copyouts(struct nfa *, struct state *, struct state *);
+static void cloneouts(struct nfa *, struct state *, struct state *, struct state *, int);
+static void delsub(struct nfa *, struct state *, struct state *);
+static void deltraverse(struct nfa *, struct state *, struct state *);
+static void dupnfa(struct nfa *, struct state *, struct state *, struct state *, struct state *);
+static void duptraverse(struct nfa *, struct state *, struct state *);
+static void cleartraverse(struct nfa *, struct state *);
+static void specialcolors(struct nfa *);
+static long optimize(struct nfa *, FILE *);
+static void pullback(struct nfa *, FILE *);
+static int pull(struct nfa *, struct arc *);
+static void pushfwd(struct nfa *, FILE *);
+static int push(struct nfa *, struct arc *);
#define INCOMPATIBLE 1 /* destroys arc */
#define SATISFIED 2 /* constraint satisfied */
#define COMPATIBLE 3 /* compatible but not satisfied yet */
-static int combine _ANSI_ARGS_((struct arc *, struct arc *));
-static VOID fixempties _ANSI_ARGS_((struct nfa *, FILE *));
-static int unempty _ANSI_ARGS_((struct nfa *, struct arc *));
-static VOID cleanup _ANSI_ARGS_((struct nfa *));
-static VOID markreachable _ANSI_ARGS_((struct nfa *, struct state *, struct state *, struct state *));
-static VOID markcanreach _ANSI_ARGS_((struct nfa *, struct state *, struct state *, struct state *));
-static long analyze _ANSI_ARGS_((struct nfa *));
-static VOID compact _ANSI_ARGS_((struct nfa *, struct cnfa *));
-static VOID carcsort _ANSI_ARGS_((struct carc *, struct carc *));
-static VOID freecnfa _ANSI_ARGS_((struct cnfa *));
-static VOID dumpnfa _ANSI_ARGS_((struct nfa *, FILE *));
+static int combine(struct arc *, struct arc *);
+static void fixempties(struct nfa *, FILE *);
+static int unempty(struct nfa *, struct arc *);
+static void cleanup(struct nfa *);
+static void markreachable(struct nfa *, struct state *, struct state *, struct state *);
+static void markcanreach(struct nfa *, struct state *, struct state *, struct state *);
+static long analyze(struct nfa *);
+static void compact(struct nfa *, struct cnfa *);
+static void carcsort(struct carc *, struct carc *);
+static void freecnfa(struct cnfa *);
+static void dumpnfa(struct nfa *, FILE *);
#ifdef REG_DEBUG
-static VOID dumpstate _ANSI_ARGS_((struct state *, FILE *));
-static VOID dumparcs _ANSI_ARGS_((struct state *, FILE *));
-static int dumprarcs _ANSI_ARGS_((struct arc *, struct state *, FILE *, int));
-static VOID dumparc _ANSI_ARGS_((struct arc *, struct state *, FILE *));
+static void dumpstate(struct state *, FILE *);
+static void dumparcs(struct state *, FILE *);
+static int dumprarcs(struct arc *, struct state *, FILE *, int);
+static void dumparc(struct arc *, struct state *, FILE *);
#endif
-static VOID dumpcnfa _ANSI_ARGS_((struct cnfa *, FILE *));
+static void dumpcnfa(struct cnfa *, FILE *);
#ifdef REG_DEBUG
-static VOID dumpcstate _ANSI_ARGS_((int, struct carc *, struct cnfa *, FILE *));
+static void dumpcstate(int, struct carc *, struct cnfa *, FILE *);
#endif
/* === regc_cvec.c === */
-static struct cvec *newcvec _ANSI_ARGS_((int, int, int));
-static struct cvec *clearcvec _ANSI_ARGS_((struct cvec *));
-static VOID addchr _ANSI_ARGS_((struct cvec *, pchr));
-static VOID addrange _ANSI_ARGS_((struct cvec *, pchr, pchr));
-static int haschr _ANSI_ARGS_((struct cvec *, pchr));
-static struct cvec *getcvec _ANSI_ARGS_((struct vars *, int, int));
-static VOID freecvec _ANSI_ARGS_((struct cvec *));
+static struct cvec *clearcvec(struct cvec *);
+static void addchr(struct cvec *, pchr);
+static void addrange(struct cvec *, pchr, pchr);
+static struct cvec *newcvec(int, int);
+static struct cvec *getcvec(struct vars *, int, int);
+static void freecvec(struct cvec *);
/* === regc_locale.c === */
-static celt element _ANSI_ARGS_((struct vars *, CONST chr *, CONST chr *));
-static struct cvec *range _ANSI_ARGS_((struct vars *, celt, celt, int));
-static int before _ANSI_ARGS_((celt, celt));
-static struct cvec *eclass _ANSI_ARGS_((struct vars *, celt, int));
-static struct cvec *cclass _ANSI_ARGS_((struct vars *, CONST chr *, CONST chr *, int));
-static struct cvec *allcases _ANSI_ARGS_((struct vars *, pchr));
-static int cmp _ANSI_ARGS_((CONST chr *, CONST chr *, size_t));
-static int casecmp _ANSI_ARGS_((CONST chr *, CONST chr *, size_t));
+static celt element(struct vars *, const chr *, const chr *);
+static struct cvec *range(struct vars *, celt, celt, int);
+static int before(celt, celt);
+static struct cvec *eclass(struct vars *, celt, int);
+static struct cvec *cclass(struct vars *, const chr *, const chr *, int);
+static struct cvec *allcases(struct vars *, pchr);
+static int cmp(const chr *, const chr *, size_t);
+static int casecmp(const chr *, const chr *, size_t);
/* automatically gathered by fwd; do not hand-edit */
/* =====^!^===== end forwards =====^!^===== */
-
-
-
+
/* internal variables, bundled for easy passing around */
struct vars {
- regex_t *re;
- CONST chr *now; /* scan pointer into string */
- CONST chr *stop; /* end of string */
- CONST chr *savenow; /* saved now and stop for "subroutine call" */
- CONST chr *savestop;
- int err; /* error code (0 if none) */
- int cflags; /* copy of compile flags */
- int lasttype; /* type of previous token */
- int nexttype; /* type of next token */
- chr nextvalue; /* value (if any) of next token */
- int lexcon; /* lexical context type (see lex.c) */
- int nsubexp; /* subexpression count */
- struct subre **subs; /* subRE pointer vector */
- size_t nsubs; /* length of vector */
- struct subre *sub10[10]; /* initial vector, enough for most */
- struct nfa *nfa; /* the NFA */
- struct colormap *cm; /* character color map */
- color nlcolor; /* color of newline */
- struct state *wordchrs; /* state in nfa holding word-char outarcs */
- struct subre *tree; /* subexpression tree */
- struct subre *treechain; /* all tree nodes allocated */
- struct subre *treefree; /* any free tree nodes */
- int ntree; /* number of tree nodes */
- struct cvec *cv; /* interface cvec */
- struct cvec *cv2; /* utility cvec */
- struct cvec *mcces; /* collating-element information */
-# define ISCELEADER(v,c) (v->mcces != NULL && haschr(v->mcces, (c)))
- struct state *mccepbegin; /* in nfa, start of MCCE prototypes */
- struct state *mccepend; /* in nfa, end of MCCE prototypes */
- struct subre *lacons; /* lookahead-constraint vector */
- int nlacons; /* size of lacons */
+ regex_t *re;
+ const chr *now; /* scan pointer into string */
+ const chr *stop; /* end of string */
+ const chr *savenow; /* saved now and stop for "subroutine call" */
+ const chr *savestop;
+ int err; /* error code (0 if none) */
+ int cflags; /* copy of compile flags */
+ int lasttype; /* type of previous token */
+ int nexttype; /* type of next token */
+ chr nextvalue; /* value (if any) of next token */
+ int lexcon; /* lexical context type (see lex.c) */
+ int nsubexp; /* subexpression count */
+ struct subre **subs; /* subRE pointer vector */
+ size_t nsubs; /* length of vector */
+ struct subre *sub10[10]; /* initial vector, enough for most */
+ struct nfa *nfa; /* the NFA */
+ struct colormap *cm; /* character color map */
+ color nlcolor; /* color of newline */
+ struct state *wordchrs; /* state in nfa holding word-char outarcs */
+ struct subre *tree; /* subexpression tree */
+ struct subre *treechain; /* all tree nodes allocated */
+ struct subre *treefree; /* any free tree nodes */
+ int ntree; /* number of tree nodes */
+ struct cvec *cv; /* interface cvec */
+ struct cvec *cv2; /* utility cvec */
+ struct subre *lacons; /* lookahead-constraint vector */
+ int nlacons; /* size of lacons */
};
/* parsing macros; most know that `v' is the struct vars pointer */
#define NEXT() (next(v)) /* advance by one token */
#define SEE(t) (v->nexttype == (t)) /* is next token this? */
#define EAT(t) (SEE(t) && next(v)) /* if next is this, swallow it */
-#define VISERR(vv) ((vv)->err != 0) /* have we seen an error yet? */
+#define VISERR(vv) ((vv)->err != 0)/* have we seen an error yet? */
#define ISERR() VISERR(v)
-#define VERR(vv,e) ((vv)->nexttype = EOS, ((vv)->err) ? (vv)->err :\
- ((vv)->err = (e)))
+#define VERR(vv,e) \
+ ((vv)->nexttype = EOS, ((vv)->err) ? (vv)->err : ((vv)->err = (e)))
#define ERR(e) VERR(v, e) /* record an error */
#define NOERR() {if (ISERR()) return;} /* if error seen, return */
#define NOERRN() {if (ISERR()) return NULL;} /* NOERR with retval */
@@ -259,387 +250,459 @@ struct vars {
#define PREFER 'P' /* length preference */
/* is an arc colored, and hence on a color chain? */
-#define COLORED(a) ((a)->type == PLAIN || (a)->type == AHEAD || \
- (a)->type == BEHIND)
-
-
+#define COLORED(a) \
+ ((a)->type == PLAIN || (a)->type == AHEAD || (a)->type == BEHIND)
/* static function list */
static struct fns functions = {
- rfree, /* regfree insides */
+ rfree, /* regfree insides */
};
-
-
-
+
/*
- compile - compile regular expression
- ^ int compile(regex_t *, CONST chr *, size_t, int);
+ ^ int compile(regex_t *, const chr *, size_t, int);
*/
int
-compile(re, string, len, flags)
-regex_t *re;
-CONST chr *string;
-size_t len;
-int flags;
+compile(
+ regex_t *re,
+ const chr *string,
+ size_t len,
+ int flags)
{
- struct vars var;
- struct vars *v = &var;
- struct guts *g;
- int i;
- size_t j;
- FILE *debug = (flags&REG_PROGRESS) ? stdout : (FILE *)NULL;
-# define CNOERR() { if (ISERR()) return freev(v, v->err); }
-
- /* sanity checks */
-
- if (re == NULL || string == NULL)
- return REG_INVARG;
- if ((flags&REG_QUOTE) &&
- (flags&(REG_ADVANCED|REG_EXPANDED|REG_NEWLINE)))
- return REG_INVARG;
- if (!(flags&REG_EXTENDED) && (flags&REG_ADVF))
- return REG_INVARG;
-
- /* initial setup (after which freev() is callable) */
- v->re = re;
- v->now = (chr *)string;
- v->stop = v->now + len;
- v->savenow = v->savestop = NULL;
- v->err = 0;
- v->cflags = flags;
- v->nsubexp = 0;
- v->subs = v->sub10;
- v->nsubs = 10;
- for (j = 0; j < v->nsubs; j++)
- v->subs[j] = NULL;
- v->nfa = NULL;
- v->cm = NULL;
- v->nlcolor = COLORLESS;
- v->wordchrs = NULL;
- v->tree = NULL;
- v->treechain = NULL;
- v->treefree = NULL;
- v->cv = NULL;
- v->cv2 = NULL;
- v->mcces = NULL;
- v->lacons = NULL;
- v->nlacons = 0;
- re->re_magic = REMAGIC;
- re->re_info = 0; /* bits get set during parse */
- re->re_csize = sizeof(chr);
- re->re_guts = NULL;
- re->re_fns = VS(&functions);
-
- /* more complex setup, malloced things */
- re->re_guts = VS(MALLOC(sizeof(struct guts)));
- if (re->re_guts == NULL)
- return freev(v, REG_ESPACE);
- g = (struct guts *)re->re_guts;
- g->tree = NULL;
- initcm(v, &g->cmap);
- v->cm = &g->cmap;
- g->lacons = NULL;
- g->nlacons = 0;
- ZAPCNFA(g->search);
- v->nfa = newnfa(v, v->cm, (struct nfa *)NULL);
- CNOERR();
- v->cv = newcvec(100, 20, 10);
- if (v->cv == NULL)
- return freev(v, REG_ESPACE);
- CNOERR();
-
- /* parsing */
- lexstart(v); /* also handles prefixes */
- if ((v->cflags&REG_NLSTOP) || (v->cflags&REG_NLANCH)) {
- /* assign newline a unique color */
- v->nlcolor = subcolor(v->cm, newline());
- okcolors(v->nfa, v->cm);
- }
- CNOERR();
- v->tree = parse(v, EOS, PLAIN, v->nfa->init, v->nfa->final);
- assert(SEE(EOS)); /* even if error; ISERR() => SEE(EOS) */
- CNOERR();
- assert(v->tree != NULL);
-
- /* finish setup of nfa and its subre tree */
- specialcolors(v->nfa);
- CNOERR();
- if (debug != NULL) {
- fprintf(debug, "\n\n\n========= RAW ==========\n");
- dumpnfa(v->nfa, debug);
- dumpst(v->tree, debug, 1);
- }
- optst(v, v->tree);
- v->ntree = numst(v->tree, 1);
- markst(v->tree);
- cleanst(v);
+ AllocVars(v);
+ struct guts *g;
+ int i;
+ size_t j;
+ FILE *debug = (flags&REG_PROGRESS) ? stdout : NULL;
+#define CNOERR() { if (ISERR()) return freev(v, v->err); }
+
+ /*
+ * Sanity checks.
+ */
+
+ if (re == NULL || string == NULL) {
+ FreeVars(v);
+ return REG_INVARG;
+ }
+ if ((flags&REG_QUOTE) && (flags&(REG_ADVANCED|REG_EXPANDED|REG_NEWLINE))) {
+ FreeVars(v);
+ return REG_INVARG;
+ }
+ if (!(flags&REG_EXTENDED) && (flags&REG_ADVF)) {
+ FreeVars(v);
+ return REG_INVARG;
+ }
+
+ /*
+ * Initial setup (after which freev() is callable).
+ */
+
+ v->re = re;
+ v->now = string;
+ v->stop = v->now + len;
+ v->savenow = v->savestop = NULL;
+ v->err = 0;
+ v->cflags = flags;
+ v->nsubexp = 0;
+ v->subs = v->sub10;
+ v->nsubs = 10;
+ for (j = 0; j < v->nsubs; j++) {
+ v->subs[j] = NULL;
+ }
+ v->nfa = NULL;
+ v->cm = NULL;
+ v->nlcolor = COLORLESS;
+ v->wordchrs = NULL;
+ v->tree = NULL;
+ v->treechain = NULL;
+ v->treefree = NULL;
+ v->cv = NULL;
+ v->cv2 = NULL;
+ v->lacons = NULL;
+ v->nlacons = 0;
+ re->re_magic = REMAGIC;
+ re->re_info = 0; /* bits get set during parse */
+ re->re_csize = sizeof(chr);
+ re->re_guts = NULL;
+ re->re_fns = VS(&functions);
+
+ /*
+ * More complex setup, malloced things.
+ */
+
+ re->re_guts = VS(MALLOC(sizeof(struct guts)));
+ if (re->re_guts == NULL) {
+ return freev(v, REG_ESPACE);
+ }
+ g = (struct guts *) re->re_guts;
+ g->tree = NULL;
+ initcm(v, &g->cmap);
+ v->cm = &g->cmap;
+ g->lacons = NULL;
+ g->nlacons = 0;
+ ZAPCNFA(g->search);
+ v->nfa = newnfa(v, v->cm, NULL);
+ CNOERR();
+ v->cv = newcvec(100, 20);
+ if (v->cv == NULL) {
+ return freev(v, REG_ESPACE);
+ }
+
+ /*
+ * Parsing.
+ */
+
+ lexstart(v); /* also handles prefixes */
+ if ((v->cflags&REG_NLSTOP) || (v->cflags&REG_NLANCH)) {
+ /*
+ * Assign newline a unique color.
+ */
+
+ v->nlcolor = subcolor(v->cm, newline());
+ okcolors(v->nfa, v->cm);
+ }
+ CNOERR();
+ v->tree = parse(v, EOS, PLAIN, v->nfa->init, v->nfa->final);
+ assert(SEE(EOS)); /* even if error; ISERR() => SEE(EOS) */
+ CNOERR();
+ assert(v->tree != NULL);
+
+ /*
+ * Finish setup of nfa and its subre tree.
+ */
+
+ specialcolors(v->nfa);
+ CNOERR();
+ if (debug != NULL) {
+ fprintf(debug, "\n\n\n========= RAW ==========\n");
+ dumpnfa(v->nfa, debug);
+ dumpst(v->tree, debug, 1);
+ }
+ optst(v, v->tree);
+ v->ntree = numst(v->tree, 1);
+ markst(v->tree);
+ cleanst(v);
+ if (debug != NULL) {
+ fprintf(debug, "\n\n\n========= TREE FIXED ==========\n");
+ dumpst(v->tree, debug, 1);
+ }
+
+ /*
+ * Build compacted NFAs for tree and lacons.
+ */
+
+ re->re_info |= nfatree(v, v->tree, debug);
+ CNOERR();
+ assert(v->nlacons == 0 || v->lacons != NULL);
+ for (i = 1; i < v->nlacons; i++) {
if (debug != NULL) {
- fprintf(debug, "\n\n\n========= TREE FIXED ==========\n");
- dumpst(v->tree, debug, 1);
+ fprintf(debug, "\n\n\n========= LA%d ==========\n", i);
}
+ nfanode(v, &v->lacons[i], debug);
+ }
+ CNOERR();
+ if (v->tree->flags&SHORTER) {
+ NOTE(REG_USHORTEST);
+ }
- /* build compacted NFAs for tree and lacons */
- re->re_info |= nfatree(v, v->tree, debug);
- CNOERR();
- assert(v->nlacons == 0 || v->lacons != NULL);
- for (i = 1; i < v->nlacons; i++) {
- if (debug != NULL)
- fprintf(debug, "\n\n\n========= LA%d ==========\n", i);
- nfanode(v, &v->lacons[i], debug);
- }
- CNOERR();
- if (v->tree->flags&SHORTER)
- NOTE(REG_USHORTEST);
-
- /* build compacted NFAs for tree, lacons, fast search */
- if (debug != NULL)
- fprintf(debug, "\n\n\n========= SEARCH ==========\n");
- /* can sacrifice main NFA now, so use it as work area */
- (DISCARD)optimize(v->nfa, debug);
- CNOERR();
- makesearch(v, v->nfa);
- CNOERR();
- compact(v->nfa, &g->search);
- CNOERR();
-
- /* looks okay, package it up */
- re->re_nsub = v->nsubexp;
- v->re = NULL; /* freev no longer frees re */
- g->magic = GUTSMAGIC;
- g->cflags = v->cflags;
- g->info = re->re_info;
- g->nsub = re->re_nsub;
- g->tree = v->tree;
- v->tree = NULL;
- g->ntree = v->ntree;
- g->compare = (v->cflags&REG_ICASE) ? casecmp : cmp;
- g->lacons = v->lacons;
- v->lacons = NULL;
- g->nlacons = v->nlacons;
-
- if (flags&REG_DUMP)
- dump(re, stdout);
-
- assert(v->err == 0);
- return freev(v, 0);
-}
+ /*
+ * Build compacted NFAs for tree, lacons, fast search.
+ */
+ if (debug != NULL) {
+ fprintf(debug, "\n\n\n========= SEARCH ==========\n");
+ }
+
+ /*
+ * Can sacrifice main NFA now, so use it as work area.
+ */
+
+ (DISCARD) optimize(v->nfa, debug);
+ CNOERR();
+ makesearch(v, v->nfa);
+ CNOERR();
+ compact(v->nfa, &g->search);
+ CNOERR();
+
+ /*
+ * Looks okay, package it up.
+ */
+
+ re->re_nsub = v->nsubexp;
+ v->re = NULL; /* freev no longer frees re */
+ g->magic = GUTSMAGIC;
+ g->cflags = v->cflags;
+ g->info = re->re_info;
+ g->nsub = re->re_nsub;
+ g->tree = v->tree;
+ v->tree = NULL;
+ g->ntree = v->ntree;
+ g->compare = (v->cflags&REG_ICASE) ? casecmp : cmp;
+ g->lacons = v->lacons;
+ v->lacons = NULL;
+ g->nlacons = v->nlacons;
+
+ if (flags&REG_DUMP) {
+ dump(re, stdout);
+ }
+
+ assert(v->err == 0);
+ return freev(v, 0);
+}
+
/*
- moresubs - enlarge subRE vector
- ^ static VOID moresubs(struct vars *, int);
+ ^ static void moresubs(struct vars *, int);
*/
-static VOID
-moresubs(v, wanted)
-struct vars *v;
-int wanted; /* want enough room for this one */
+static void
+moresubs(
+ struct vars *v,
+ int wanted) /* want enough room for this one */
{
- struct subre **p;
- size_t n;
-
- assert(wanted > 0 && (size_t)wanted >= v->nsubs);
- n = (size_t)wanted * 3 / 2 + 1;
- if (v->subs == v->sub10) {
- p = (struct subre **)MALLOC(n * sizeof(struct subre *));
- if (p != NULL)
- memcpy(VS(p), VS(v->subs),
- v->nsubs * sizeof(struct subre *));
- } else
- p = (struct subre **)REALLOC(v->subs, n*sizeof(struct subre *));
- if (p == NULL) {
- ERR(REG_ESPACE);
- return;
+ struct subre **p;
+ size_t n;
+
+ assert(wanted > 0 && (size_t)wanted >= v->nsubs);
+ n = (size_t)wanted * 3 / 2 + 1;
+ if (v->subs == v->sub10) {
+ p = (struct subre **) MALLOC(n * sizeof(struct subre *));
+ if (p != NULL) {
+ memcpy(p, v->subs, v->nsubs * sizeof(struct subre *));
}
- v->subs = p;
- for (p = &v->subs[v->nsubs]; v->nsubs < n; p++, v->nsubs++)
- *p = NULL;
- assert(v->nsubs == n);
- assert((size_t)wanted < v->nsubs);
+ } else {
+ p = (struct subre **) REALLOC(v->subs, n*sizeof(struct subre *));
+ }
+ if (p == NULL) {
+ ERR(REG_ESPACE);
+ return;
+ }
+
+ v->subs = p;
+ for (p = &v->subs[v->nsubs]; v->nsubs < n; p++, v->nsubs++) {
+ *p = NULL;
+ }
+ assert(v->nsubs == n);
+ assert((size_t)wanted < v->nsubs);
}
-
+
/*
- freev - free vars struct's substructures where necessary
- * Optionally does error-number setting, and always returns error code
- * (if any), to make error-handling code terser.
+ * Optionally does error-number setting, and always returns error code (if
+ * any), to make error-handling code terser.
^ static int freev(struct vars *, int);
*/
static int
-freev(v, err)
-struct vars *v;
-int err;
+freev(
+ struct vars *v,
+ int err)
{
- if (v->re != NULL)
- rfree(v->re);
- if (v->subs != v->sub10)
- FREE(v->subs);
- if (v->nfa != NULL)
- freenfa(v->nfa);
- if (v->tree != NULL)
- freesubre(v, v->tree);
- if (v->treechain != NULL)
- cleanst(v);
- if (v->cv != NULL)
- freecvec(v->cv);
- if (v->cv2 != NULL)
- freecvec(v->cv2);
- if (v->mcces != NULL)
- freecvec(v->mcces);
- if (v->lacons != NULL)
- freelacons(v->lacons, v->nlacons);
- ERR(err); /* nop if err==0 */
-
- return v->err;
+ register int ret;
+
+ if (v->re != NULL) {
+ rfree(v->re);
+ }
+ if (v->subs != v->sub10) {
+ FREE(v->subs);
+ }
+ if (v->nfa != NULL) {
+ freenfa(v->nfa);
+ }
+ if (v->tree != NULL) {
+ freesubre(v, v->tree);
+ }
+ if (v->treechain != NULL) {
+ cleanst(v);
+ }
+ if (v->cv != NULL) {
+ freecvec(v->cv);
+ }
+ if (v->cv2 != NULL) {
+ freecvec(v->cv2);
+ }
+ if (v->lacons != NULL) {
+ freelacons(v->lacons, v->nlacons);
+ }
+ ERR(err); /* nop if err==0 */
+
+ ret = v->err;
+ FreeVars(v);
+ return ret;
}
-
+
/*
- makesearch - turn an NFA into a search NFA (implicit prepend of .*?)
* NFA must have been optimize()d already.
- ^ static VOID makesearch(struct vars *, struct nfa *);
+ ^ static void makesearch(struct vars *, struct nfa *);
*/
-static VOID
-makesearch(v, nfa)
-struct vars *v;
-struct nfa *nfa;
+static void
+makesearch(
+ struct vars *v,
+ struct nfa *nfa)
{
- struct arc *a;
- struct arc *b;
- struct state *pre = nfa->pre;
- struct state *s;
- struct state *s2;
- struct state *slist;
-
- /* no loops are needed if it's anchored */
- for (a = pre->outs; a != NULL; a = a->outchain) {
- assert(a->type == PLAIN);
- if (a->co != nfa->bos[0] && a->co != nfa->bos[1])
- break;
- }
- if (a != NULL) {
- /* add implicit .* in front */
- rainbow(nfa, v->cm, PLAIN, COLORLESS, pre, pre);
+ struct arc *a, *b;
+ struct state *pre = nfa->pre;
+ struct state *s, *s2, *slist;
- /* and ^* and \A* too -- not always necessary, but harmless */
- newarc(nfa, PLAIN, nfa->bos[0], pre, pre);
- newarc(nfa, PLAIN, nfa->bos[1], pre, pre);
+ /*
+ * No loops are needed if it's anchored.
+ */
+
+ for (a = pre->outs; a != NULL; a = a->outchain) {
+ assert(a->type == PLAIN);
+ if (a->co != nfa->bos[0] && a->co != nfa->bos[1]) {
+ break;
}
+ }
+ if (a != NULL) {
+ /*
+ * Add implicit .* in front.
+ */
+
+ rainbow(nfa, v->cm, PLAIN, COLORLESS, pre, pre);
/*
- * Now here's the subtle part. Because many REs have no lookback
- * constraints, often knowing when you were in the pre state tells
- * you little; it's the next state(s) that are informative. But
- * some of them may have other inarcs, i.e. it may be possible to
- * make actual progress and then return to one of them. We must
- * de-optimize such cases, splitting each such state into progress
- * and no-progress states.
+ * And ^* and \A* too -- not always necessary, but harmless.
*/
- /* first, make a list of the states */
- slist = NULL;
- for (a = pre->outs; a != NULL; a = a->outchain) {
- s = a->to;
- for (b = s->ins; b != NULL; b = b->inchain)
- if (b->from != pre)
- break;
- if (b != NULL) { /* must be split */
- if (s->tmp == NULL) { /* if not already in the list */
- /* (fixes bugs 505048, 230589, */
- /* 840258, 504785) */
- s->tmp = slist;
- slist = s;
- }
- }
+ newarc(nfa, PLAIN, nfa->bos[0], pre, pre);
+ newarc(nfa, PLAIN, nfa->bos[1], pre, pre);
+ }
+
+ /*
+ * Now here's the subtle part. Because many REs have no lookback
+ * constraints, often knowing when you were in the pre state tells you
+ * little; it's the next state(s) that are informative. But some of them
+ * may have other inarcs, i.e. it may be possible to make actual progress
+ * and then return to one of them. We must de-optimize such cases,
+ * splitting each such state into progress and no-progress states.
+ */
+
+ /*
+ * First, make a list of the states.
+ */
+
+ slist = NULL;
+ for (a=pre->outs ; a!=NULL ; a=a->outchain) {
+ s = a->to;
+ for (b=s->ins ; b!=NULL ; b=b->inchain) {
+ if (b->from != pre) {
+ break;
+ }
+ }
+ if (b != NULL && s->tmp == NULL) {
+ /*
+ * Must be split if not already in the list (fixes bugs 505048,
+ * 230589, 840258, 504785).
+ */
+
+ s->tmp = slist;
+ slist = s;
}
+ }
- /* do the splits */
- for (s = slist; s != NULL; s = s2) {
- s2 = newstate(nfa);
- copyouts(nfa, s, s2);
- for (a = s->ins; a != NULL; a = b) {
- b = a->inchain;
- if (a->from != pre) {
- cparc(nfa, a, a->from, s2);
- freearc(nfa, a);
- }
- }
- s2 = s->tmp;
- s->tmp = NULL; /* clean up while we're at it */
+ /*
+ * Do the splits.
+ */
+
+ for (s=slist ; s!=NULL ; s=s2) {
+ s2 = newstate(nfa);
+
+ copyouts(nfa, s, s2);
+ for (a=s->ins ; a!=NULL ; a=b) {
+ b = a->inchain;
+
+ if (a->from != pre) {
+ cparc(nfa, a, a->from, s2);
+ freearc(nfa, a);
+ }
}
+ s2 = s->tmp;
+ s->tmp = NULL; /* clean up while we're at it */
+ }
}
-
+
/*
- parse - parse an RE
- * This is actually just the top level, which parses a bunch of branches
- * tied together with '|'. They appear in the tree as the left children
- * of a chain of '|' subres.
+ * This is actually just the top level, which parses a bunch of branches tied
+ * together with '|'. They appear in the tree as the left children of a chain
+ * of '|' subres.
^ static struct subre *parse(struct vars *, int, int, struct state *,
^ struct state *);
*/
static struct subre *
-parse(v, stopper, type, init, final)
-struct vars *v;
-int stopper; /* EOS or ')' */
-int type; /* LACON (lookahead subRE) or PLAIN */
-struct state *init; /* initial state */
-struct state *final; /* final state */
+parse(
+ struct vars *v,
+ int stopper, /* EOS or ')' */
+ int type, /* LACON (lookahead subRE) or PLAIN */
+ struct state *init, /* initial state */
+ struct state *final) /* final state */
{
- struct state *left; /* scaffolding for branch */
- struct state *right;
- struct subre *branches; /* top level */
- struct subre *branch; /* current branch */
- struct subre *t; /* temporary */
- int firstbranch; /* is this the first branch? */
-
- assert(stopper == ')' || stopper == EOS);
-
- branches = subre(v, '|', LONGER, init, final);
+ struct state *left, *right; /* scaffolding for branch */
+ struct subre *branches; /* top level */
+ struct subre *branch; /* current branch */
+ struct subre *t; /* temporary */
+ int firstbranch; /* is this the first branch? */
+
+ assert(stopper == ')' || stopper == EOS);
+
+ branches = subre(v, '|', LONGER, init, final);
+ NOERRN();
+ branch = branches;
+ firstbranch = 1;
+ do { /* a branch */
+ if (!firstbranch) {
+ /*
+ * Need a place to hang the branch.
+ */
+
+ branch->right = subre(v, '|', LONGER, init, final);
+ NOERRN();
+ branch = branch->right;
+ }
+ firstbranch = 0;
+ left = newstate(v->nfa);
+ right = newstate(v->nfa);
NOERRN();
- branch = branches;
- firstbranch = 1;
- do { /* a branch */
- if (!firstbranch) {
- /* need a place to hang it */
- branch->right = subre(v, '|', LONGER, init, final);
- NOERRN();
- branch = branch->right;
- }
- firstbranch = 0;
- left = newstate(v->nfa);
- right = newstate(v->nfa);
- NOERRN();
- EMPTYARC(init, left);
- EMPTYARC(right, final);
- NOERRN();
- branch->left = parsebranch(v, stopper, type, left, right, 0);
- NOERRN();
- branch->flags |= UP(branch->flags | branch->left->flags);
- if ((branch->flags &~ branches->flags) != 0) /* new flags */
- for (t = branches; t != branch; t = t->right)
- t->flags |= branch->flags;
- } while (EAT('|'));
- assert(SEE(stopper) || SEE(EOS));
-
- if (!SEE(stopper)) {
- assert(stopper == ')' && SEE(EOS));
- ERR(REG_EPAREN);
+ EMPTYARC(init, left);
+ EMPTYARC(right, final);
+ NOERRN();
+ branch->left = parsebranch(v, stopper, type, left, right, 0);
+ NOERRN();
+ branch->flags |= UP(branch->flags | branch->left->flags);
+ if ((branch->flags &~ branches->flags) != 0) { /* new flags */
+ for (t = branches; t != branch; t = t->right) {
+ t->flags |= branch->flags;
+ }
}
+ } while (EAT('|'));
+ assert(SEE(stopper) || SEE(EOS));
- /* optimize out simple cases */
- if (branch == branches) { /* only one branch */
- assert(branch->right == NULL);
- t = branch->left;
- branch->left = NULL;
- freesubre(v, branches);
- branches = t;
- } else if (!MESSY(branches->flags)) { /* no interesting innards */
- freesubre(v, branches->left);
- branches->left = NULL;
- freesubre(v, branches->right);
- branches->right = NULL;
- branches->op = '=';
- }
+ if (!SEE(stopper)) {
+ assert(stopper == ')' && SEE(EOS));
+ ERR(REG_EPAREN);
+ }
- return branches;
-}
+ /*
+ * Optimize out simple cases.
+ */
+ if (branch == branches) { /* only one branch */
+ assert(branch->right == NULL);
+ t = branch->left;
+ branch->left = NULL;
+ freesubre(v, branches);
+ branches = t;
+ } else if (!MESSY(branches->flags)) { /* no interesting innards */
+ freesubre(v, branches->left);
+ branches->left = NULL;
+ freesubre(v, branches->right);
+ branches->right = NULL;
+ branches->op = '=';
+ }
+
+ return branches;
+}
+
/*
- parsebranch - parse one branch of an RE
* This mostly manages concatenation, working closely with parseqatom().
@@ -649,1458 +712,1446 @@ struct state *final; /* final state */
^ struct state *, int);
*/
static struct subre *
-parsebranch(v, stopper, type, left, right, partial)
-struct vars *v;
-int stopper; /* EOS or ')' */
-int type; /* LACON (lookahead subRE) or PLAIN */
-struct state *left; /* leftmost state */
-struct state *right; /* rightmost state */
-int partial; /* is this only part of a branch? */
+parsebranch(
+ struct vars *v,
+ int stopper, /* EOS or ')' */
+ int type, /* LACON (lookahead subRE) or PLAIN */
+ struct state *left, /* leftmost state */
+ struct state *right, /* rightmost state */
+ int partial) /* is this only part of a branch? */
{
- struct state *lp; /* left end of current construct */
- int seencontent; /* is there anything in this branch yet? */
- struct subre *t;
-
- lp = left;
- seencontent = 0;
- t = subre(v, '=', 0, left, right); /* op '=' is tentative */
- NOERRN();
- while (!SEE('|') && !SEE(stopper) && !SEE(EOS)) {
- if (seencontent) { /* implicit concat operator */
- lp = newstate(v->nfa);
- NOERRN();
- moveins(v->nfa, right, lp);
- }
- seencontent = 1;
-
- /* NB, recursion in parseqatom() may swallow rest of branch */
- parseqatom(v, stopper, type, lp, right, t);
+ struct state *lp; /* left end of current construct */
+ int seencontent; /* is there anything in this branch yet? */
+ struct subre *t;
+
+ lp = left;
+ seencontent = 0;
+ t = subre(v, '=', 0, left, right); /* op '=' is tentative */
+ NOERRN();
+ while (!SEE('|') && !SEE(stopper) && !SEE(EOS)) {
+ if (seencontent) { /* implicit concat operator */
+ lp = newstate(v->nfa);
+ NOERRN();
+ moveins(v->nfa, right, lp);
}
+ seencontent = 1;
- if (!seencontent) { /* empty branch */
- if (!partial)
- NOTE(REG_UUNSPEC);
- assert(lp == left);
- EMPTYARC(left, right);
+ /* NB, recursion in parseqatom() may swallow rest of branch */
+ parseqatom(v, stopper, type, lp, right, t);
+ }
+
+ if (!seencontent) { /* empty branch */
+ if (!partial) {
+ NOTE(REG_UUNSPEC);
}
+ assert(lp == left);
+ EMPTYARC(left, right);
+ }
- return t;
+ return t;
}
-
+
/*
- parseqatom - parse one quantified atom or constraint of an RE
- * The bookkeeping near the end cooperates very closely with parsebranch();
- * in particular, it contains a recursion that can involve parsing the rest
- * of the branch, making this function's name somewhat inaccurate.
- ^ static VOID parseqatom(struct vars *, int, int, struct state *,
+ * The bookkeeping near the end cooperates very closely with parsebranch(); in
+ * particular, it contains a recursion that can involve parsing the rest of
+ * the branch, making this function's name somewhat inaccurate.
+ ^ static void parseqatom(struct vars *, int, int, struct state *,
^ struct state *, struct subre *);
*/
-static VOID
-parseqatom(v, stopper, type, lp, rp, top)
-struct vars *v;
-int stopper; /* EOS or ')' */
-int type; /* LACON (lookahead subRE) or PLAIN */
-struct state *lp; /* left state to hang it on */
-struct state *rp; /* right state to hang it on */
-struct subre *top; /* subtree top */
+static void
+parseqatom(
+ struct vars *v,
+ int stopper, /* EOS or ')' */
+ int type, /* LACON (lookahead subRE) or PLAIN */
+ struct state *lp, /* left state to hang it on */
+ struct state *rp, /* right state to hang it on */
+ struct subre *top) /* subtree top */
{
- struct state *s; /* temporaries for new states */
- struct state *s2;
-# define ARCV(t, val) newarc(v->nfa, t, val, lp, rp)
- int m, n;
- struct subre *atom; /* atom's subtree */
- struct subre *t;
- int cap; /* capturing parens? */
- int pos; /* positive lookahead? */
- int subno; /* capturing-parens or backref number */
- int atomtype;
- int qprefer; /* quantifier short/long preference */
- int f;
- struct subre **atomp; /* where the pointer to atom is */
-
- /* initial bookkeeping */
- atom = NULL;
- assert(lp->nouts == 0); /* must string new code */
- assert(rp->nins == 0); /* between lp and rp */
- subno = 0; /* just to shut lint up */
-
- /* an atom or constraint... */
- atomtype = v->nexttype;
- switch (atomtype) {
+ struct state *s; /* temporaries for new states */
+ struct state *s2;
+#define ARCV(t, val) newarc(v->nfa, t, val, lp, rp)
+ int m, n;
+ struct subre *atom; /* atom's subtree */
+ struct subre *t;
+ int cap; /* capturing parens? */
+ int pos; /* positive lookahead? */
+ int subno; /* capturing-parens or backref number */
+ int atomtype;
+ int qprefer; /* quantifier short/long preference */
+ int f;
+ struct subre **atomp; /* where the pointer to atom is */
+
+ /*
+ * Initial bookkeeping.
+ */
+
+ atom = NULL;
+ assert(lp->nouts == 0); /* must string new code */
+ assert(rp->nins == 0); /* between lp and rp */
+ subno = 0; /* just to shut lint up */
+
+ /*
+ * An atom or constraint...
+ */
+
+ atomtype = v->nexttype;
+ switch (atomtype) {
/* first, constraints, which end by returning */
- case '^':
- ARCV('^', 1);
- if (v->cflags&REG_NLANCH)
- ARCV(BEHIND, v->nlcolor);
- NEXT();
- return;
- break;
- case '$':
- ARCV('$', 1);
- if (v->cflags&REG_NLANCH)
- ARCV(AHEAD, v->nlcolor);
- NEXT();
- return;
- break;
- case SBEGIN:
- ARCV('^', 1); /* BOL */
- ARCV('^', 0); /* or BOS */
- NEXT();
- return;
- break;
- case SEND:
- ARCV('$', 1); /* EOL */
- ARCV('$', 0); /* or EOS */
- NEXT();
- return;
- break;
- case '<':
- wordchrs(v); /* does NEXT() */
- s = newstate(v->nfa);
- NOERR();
- nonword(v, BEHIND, lp, s);
- word(v, AHEAD, s, rp);
- return;
- break;
- case '>':
- wordchrs(v); /* does NEXT() */
- s = newstate(v->nfa);
- NOERR();
- word(v, BEHIND, lp, s);
- nonword(v, AHEAD, s, rp);
- return;
- break;
- case WBDRY:
- wordchrs(v); /* does NEXT() */
- s = newstate(v->nfa);
- NOERR();
- nonword(v, BEHIND, lp, s);
- word(v, AHEAD, s, rp);
- s = newstate(v->nfa);
- NOERR();
- word(v, BEHIND, lp, s);
- nonword(v, AHEAD, s, rp);
- return;
- break;
- case NWBDRY:
- wordchrs(v); /* does NEXT() */
- s = newstate(v->nfa);
- NOERR();
- word(v, BEHIND, lp, s);
- word(v, AHEAD, s, rp);
- s = newstate(v->nfa);
- NOERR();
- nonword(v, BEHIND, lp, s);
- nonword(v, AHEAD, s, rp);
- return;
- break;
- case LACON: /* lookahead constraint */
- pos = v->nextvalue;
- NEXT();
- s = newstate(v->nfa);
- s2 = newstate(v->nfa);
- NOERR();
- t = parse(v, ')', LACON, s, s2);
- freesubre(v, t); /* internal structure irrelevant */
- assert(SEE(')') || ISERR());
- NEXT();
- n = newlacon(v, s, s2, pos);
- NOERR();
- ARCV(LACON, n);
- return;
- break;
- /* then errors, to get them out of the way */
- case '*':
- case '+':
- case '?':
- case '{':
- ERR(REG_BADRPT);
- return;
- break;
- default:
- ERR(REG_ASSERT);
- return;
- break;
- /* then plain characters, and minor variants on that theme */
- case ')': /* unbalanced paren */
- if ((v->cflags&REG_ADVANCED) != REG_EXTENDED) {
- ERR(REG_EPAREN);
- return;
- }
- /* legal in EREs due to specification botch */
- NOTE(REG_UPBOTCH);
- /* fallthrough into case PLAIN */
- case PLAIN:
- onechr(v, v->nextvalue, lp, rp);
- okcolors(v->nfa, v->cm);
- NOERR();
- NEXT();
- break;
- case '[':
- if (v->nextvalue == 1)
- bracket(v, lp, rp);
- else
- cbracket(v, lp, rp);
- assert(SEE(']') || ISERR());
- NEXT();
- break;
- case '.':
- rainbow(v->nfa, v->cm, PLAIN,
- (v->cflags&REG_NLSTOP) ? v->nlcolor : COLORLESS,
- lp, rp);
- NEXT();
- break;
- /* and finally the ugly stuff */
- case '(': /* value flags as capturing or non */
- cap = (type == LACON) ? 0 : v->nextvalue;
- if (cap) {
- v->nsubexp++;
- subno = v->nsubexp;
- if ((size_t)subno >= v->nsubs)
- moresubs(v, subno);
- assert((size_t)subno < v->nsubs);
- } else
- atomtype = PLAIN; /* something that's not '(' */
- NEXT();
- /* need new endpoints because tree will contain pointers */
- s = newstate(v->nfa);
- s2 = newstate(v->nfa);
- NOERR();
- EMPTYARC(lp, s);
- EMPTYARC(s2, rp);
- NOERR();
- atom = parse(v, ')', PLAIN, s, s2);
- assert(SEE(')') || ISERR());
- NEXT();
- NOERR();
- if (cap) {
- v->subs[subno] = atom;
- t = subre(v, '(', atom->flags|CAP, lp, rp);
- NOERR();
- t->subno = subno;
- t->left = atom;
- atom = t;
- }
- /* postpone everything else pending possible {0} */
- break;
- case BACKREF: /* the Feature From The Black Lagoon */
- INSIST(type != LACON, REG_ESUBREG);
- INSIST(v->nextvalue < v->nsubs, REG_ESUBREG);
- INSIST(v->subs[v->nextvalue] != NULL, REG_ESUBREG);
- NOERR();
- assert(v->nextvalue > 0);
- atom = subre(v, 'b', BACKR, lp, rp);
- subno = v->nextvalue;
- atom->subno = subno;
- EMPTYARC(lp, rp); /* temporarily, so there's something */
- NEXT();
- break;
+ case '^':
+ ARCV('^', 1);
+ if (v->cflags&REG_NLANCH) {
+ ARCV(BEHIND, v->nlcolor);
}
-
- /* ...and an atom may be followed by a quantifier */
- switch (v->nexttype) {
- case '*':
- m = 0;
- n = INFINITY;
- qprefer = (v->nextvalue) ? LONGER : SHORTER;
- NEXT();
- break;
- case '+':
- m = 1;
- n = INFINITY;
- qprefer = (v->nextvalue) ? LONGER : SHORTER;
- NEXT();
- break;
- case '?':
- m = 0;
- n = 1;
- qprefer = (v->nextvalue) ? LONGER : SHORTER;
- NEXT();
- break;
- case '{':
- NEXT();
- m = scannum(v);
- if (EAT(',')) {
- if (SEE(DIGIT))
- n = scannum(v);
- else
- n = INFINITY;
- if (m > n) {
- ERR(REG_BADBR);
- return;
- }
- /* {m,n} exercises preference, even if it's {m,m} */
- qprefer = (v->nextvalue) ? LONGER : SHORTER;
- } else {
- n = m;
- /* {m} passes operand's preference through */
- qprefer = 0;
- }
- if (!SEE('}')) { /* catches errors too */
- ERR(REG_BADBR);
- return;
- }
- NEXT();
- break;
- default: /* no quantifier */
- m = n = 1;
- qprefer = 0;
- break;
+ NEXT();
+ return;
+ case '$':
+ ARCV('$', 1);
+ if (v->cflags&REG_NLANCH) {
+ ARCV(AHEAD, v->nlcolor);
}
+ NEXT();
+ return;
+ case SBEGIN:
+ ARCV('^', 1); /* BOL */
+ ARCV('^', 0); /* or BOS */
+ NEXT();
+ return;
+ case SEND:
+ ARCV('$', 1); /* EOL */
+ ARCV('$', 0); /* or EOS */
+ NEXT();
+ return;
+ case '<':
+ wordchrs(v); /* does NEXT() */
+ s = newstate(v->nfa);
+ NOERR();
+ nonword(v, BEHIND, lp, s);
+ word(v, AHEAD, s, rp);
+ return;
+ case '>':
+ wordchrs(v); /* does NEXT() */
+ s = newstate(v->nfa);
+ NOERR();
+ word(v, BEHIND, lp, s);
+ nonword(v, AHEAD, s, rp);
+ return;
+ case WBDRY:
+ wordchrs(v); /* does NEXT() */
+ s = newstate(v->nfa);
+ NOERR();
+ nonword(v, BEHIND, lp, s);
+ word(v, AHEAD, s, rp);
+ s = newstate(v->nfa);
+ NOERR();
+ word(v, BEHIND, lp, s);
+ nonword(v, AHEAD, s, rp);
+ return;
+ case NWBDRY:
+ wordchrs(v); /* does NEXT() */
+ s = newstate(v->nfa);
+ NOERR();
+ word(v, BEHIND, lp, s);
+ word(v, AHEAD, s, rp);
+ s = newstate(v->nfa);
+ NOERR();
+ nonword(v, BEHIND, lp, s);
+ nonword(v, AHEAD, s, rp);
+ return;
+ case LACON: /* lookahead constraint */
+ pos = v->nextvalue;
+ NEXT();
+ s = newstate(v->nfa);
+ s2 = newstate(v->nfa);
+ NOERR();
+ t = parse(v, ')', LACON, s, s2);
+ freesubre(v, t); /* internal structure irrelevant */
+ assert(SEE(')') || ISERR());
+ NEXT();
+ n = newlacon(v, s, s2, pos);
+ NOERR();
+ ARCV(LACON, n);
+ return;
- /* annoying special case: {0} or {0,0} cancels everything */
- if (m == 0 && n == 0) {
- if (atom != NULL)
- freesubre(v, atom);
- if (atomtype == '(')
- v->subs[subno] = NULL;
- delsub(v->nfa, lp, rp);
- EMPTYARC(lp, rp);
- return;
+ /*
+ * Then errors, to get them out of the way.
+ */
+
+ case '*':
+ case '+':
+ case '?':
+ case '{':
+ ERR(REG_BADRPT);
+ return;
+ default:
+ ERR(REG_ASSERT);
+ return;
+
+ /*
+ * Then plain characters, and minor variants on that theme.
+ */
+
+ case ')': /* unbalanced paren */
+ if ((v->cflags&REG_ADVANCED) != REG_EXTENDED) {
+ ERR(REG_EPAREN);
+ return;
}
- /* if not a messy case, avoid hard part */
- assert(!MESSY(top->flags));
- f = top->flags | qprefer | ((atom != NULL) ? atom->flags : 0);
- if (atomtype != '(' && atomtype != BACKREF && !MESSY(UP(f))) {
- if (!(m == 1 && n == 1))
- repeat(v, lp, rp, m, n);
- if (atom != NULL)
- freesubre(v, atom);
- top->flags = f;
- return;
+ /*
+ * Legal in EREs due to specification botch.
+ */
+
+ NOTE(REG_UPBOTCH);
+ /* fallthrough into case PLAIN */
+ case PLAIN:
+ onechr(v, v->nextvalue, lp, rp);
+ okcolors(v->nfa, v->cm);
+ NOERR();
+ NEXT();
+ break;
+ case '[':
+ if (v->nextvalue == 1) {
+ bracket(v, lp, rp);
+ } else {
+ cbracket(v, lp, rp);
}
+ assert(SEE(']') || ISERR());
+ NEXT();
+ break;
+ case '.':
+ rainbow(v->nfa, v->cm, PLAIN,
+ (v->cflags&REG_NLSTOP) ? v->nlcolor : COLORLESS, lp, rp);
+ NEXT();
+ break;
/*
- * hard part: something messy
- * That is, capturing parens, back reference, short/long clash, or
- * an atom with substructure containing one of those.
+ * And finally the ugly stuff.
*/
- /* now we'll need a subre for the contents even if they're boring */
- if (atom == NULL) {
- atom = subre(v, '=', 0, lp, rp);
- NOERR();
+ case '(': /* value flags as capturing or non */
+ cap = (type == LACON) ? 0 : v->nextvalue;
+ if (cap) {
+ v->nsubexp++;
+ subno = v->nsubexp;
+ if ((size_t)subno >= v->nsubs) {
+ moresubs(v, subno);
+ }
+ assert((size_t)subno < v->nsubs);
+ } else {
+ atomtype = PLAIN; /* something that's not '(' */
}
+ NEXT();
/*
- * prepare a general-purpose state skeleton
- *
- * ---> [s] ---prefix---> [begin] ---atom---> [end] ----rest---> [rp]
- * / /
- * [lp] ----> [s2] ----bypass---------------------
- *
- * where bypass is an empty, and prefix is some repetitions of atom
+ * Need new endpoints because tree will contain pointers.
*/
- s = newstate(v->nfa); /* first, new endpoints for the atom */
+
+ s = newstate(v->nfa);
s2 = newstate(v->nfa);
NOERR();
- moveouts(v->nfa, lp, s);
- moveins(v->nfa, rp, s2);
+ EMPTYARC(lp, s);
+ EMPTYARC(s2, rp);
NOERR();
- atom->begin = s;
- atom->end = s2;
- s = newstate(v->nfa); /* and spots for prefix and bypass */
- s2 = newstate(v->nfa);
+ atom = parse(v, ')', PLAIN, s, s2);
+ assert(SEE(')') || ISERR());
+ NEXT();
NOERR();
- EMPTYARC(lp, s);
- EMPTYARC(lp, s2);
+ if (cap) {
+ v->subs[subno] = atom;
+ t = subre(v, '(', atom->flags|CAP, lp, rp);
+ NOERR();
+ t->subno = subno;
+ t->left = atom;
+ atom = t;
+ }
+
+ /*
+ * Postpone everything else pending possible {0}.
+ */
+
+ break;
+ case BACKREF: /* the Feature From The Black Lagoon */
+ INSIST(type != LACON, REG_ESUBREG);
+ INSIST(v->nextvalue < v->nsubs, REG_ESUBREG);
+ INSIST(v->subs[v->nextvalue] != NULL, REG_ESUBREG);
NOERR();
+ assert(v->nextvalue > 0);
+ atom = subre(v, 'b', BACKR, lp, rp);
+ subno = v->nextvalue;
+ atom->subno = subno;
+ EMPTYARC(lp, rp); /* temporarily, so there's something */
+ NEXT();
+ break;
+ }
- /* break remaining subRE into x{...} and what follows */
- t = subre(v, '.', COMBINE(qprefer, atom->flags), lp, rp);
- t->left = atom;
- atomp = &t->left;
- /* here we should recurse... but we must postpone that to the end */
-
- /* split top into prefix and remaining */
- assert(top->op == '=' && top->left == NULL && top->right == NULL);
- top->left = subre(v, '=', top->flags, top->begin, lp);
- top->op = '.';
- top->right = t;
-
- /* if it's a backref, now is the time to replicate the subNFA */
- if (atomtype == BACKREF) {
- assert(atom->begin->nouts == 1); /* just the EMPTY */
- delsub(v->nfa, atom->begin, atom->end);
- assert(v->subs[subno] != NULL);
- /* and here's why the recursion got postponed: it must */
- /* wait until the skeleton is filled in, because it may */
- /* hit a backref that wants to copy the filled-in skeleton */
- dupnfa(v->nfa, v->subs[subno]->begin, v->subs[subno]->end,
- atom->begin, atom->end);
- NOERR();
- }
+ /*
+ * ...and an atom may be followed by a quantifier.
+ */
- /* it's quantifier time; first, turn x{0,...} into x{1,...}|empty */
- if (m == 0) {
- EMPTYARC(s2, atom->end); /* the bypass */
- assert(PREF(qprefer) != 0);
- f = COMBINE(qprefer, atom->flags);
- t = subre(v, '|', f, lp, atom->end);
- NOERR();
- t->left = atom;
- t->right = subre(v, '|', PREF(f), s2, atom->end);
- NOERR();
- t->right->left = subre(v, '=', 0, s2, atom->end);
- NOERR();
- *atomp = t;
- atomp = &t->left;
- m = 1;
- }
+ switch (v->nexttype) {
+ case '*':
+ m = 0;
+ n = INFINITY;
+ qprefer = (v->nextvalue) ? LONGER : SHORTER;
+ NEXT();
+ break;
+ case '+':
+ m = 1;
+ n = INFINITY;
+ qprefer = (v->nextvalue) ? LONGER : SHORTER;
+ NEXT();
+ break;
+ case '?':
+ m = 0;
+ n = 1;
+ qprefer = (v->nextvalue) ? LONGER : SHORTER;
+ NEXT();
+ break;
+ case '{':
+ NEXT();
+ m = scannum(v);
+ if (EAT(',')) {
+ if (SEE(DIGIT)) {
+ n = scannum(v);
+ } else {
+ n = INFINITY;
+ }
+ if (m > n) {
+ ERR(REG_BADBR);
+ return;
+ }
- /* deal with the rest of the quantifier */
- if (atomtype == BACKREF) {
- /* special case: backrefs have internal quantifiers */
- EMPTYARC(s, atom->begin); /* empty prefix */
- /* just stuff everything into atom */
- repeat(v, atom->begin, atom->end, m, n);
- atom->min = (short)m;
- atom->max = (short)n;
- atom->flags |= COMBINE(qprefer, atom->flags);
- } else if (m == 1 && n == 1) {
- /* no/vacuous quantifier: done */
- EMPTYARC(s, atom->begin); /* empty prefix */
+ /*
+ * {m,n} exercises preference, even if it's {m,m}
+ */
+
+ qprefer = (v->nextvalue) ? LONGER : SHORTER;
} else {
- /* turn x{m,n} into x{m-1,n-1}x, with capturing */
- /* parens in only second x */
- dupnfa(v->nfa, atom->begin, atom->end, s, atom->begin);
- assert(m >= 1 && m != INFINITY && n >= 1);
- repeat(v, s, atom->begin, m-1, (n == INFINITY) ? n : n-1);
- f = COMBINE(qprefer, atom->flags);
- t = subre(v, '.', f, s, atom->end); /* prefix and atom */
- NOERR();
- t->left = subre(v, '=', PREF(f), s, atom->begin);
- NOERR();
- t->right = atom;
- *atomp = t;
+ n = m;
+ /*
+ * {m} passes operand's preference through.
+ */
+
+ qprefer = 0;
+ }
+ if (!SEE('}')) { /* catches errors too */
+ ERR(REG_BADBR);
+ return;
+ }
+ NEXT();
+ break;
+ default: /* no quantifier */
+ m = n = 1;
+ qprefer = 0;
+ break;
+ }
+
+ /*
+ * Annoying special case: {0} or {0,0} cancels everything.
+ */
+
+ if (m == 0 && n == 0) {
+ if (atom != NULL) {
+ freesubre(v, atom);
}
+ if (atomtype == '(') {
+ v->subs[subno] = NULL;
+ }
+ delsub(v->nfa, lp, rp);
+ EMPTYARC(lp, rp);
+ return;
+ }
- /* and finally, look after that postponed recursion */
- t = top->right;
- if (!(SEE('|') || SEE(stopper) || SEE(EOS)))
- t->right = parsebranch(v, stopper, type, atom->end, rp, 1);
- else {
- EMPTYARC(atom->end, rp);
- t->right = subre(v, '=', 0, atom->end, rp);
+ /*
+ * If not a messy case, avoid hard part.
+ */
+
+ assert(!MESSY(top->flags));
+ f = top->flags | qprefer | ((atom != NULL) ? atom->flags : 0);
+ if (atomtype != '(' && atomtype != BACKREF && !MESSY(UP(f))) {
+ if (!(m == 1 && n == 1)) {
+ repeat(v, lp, rp, m, n);
}
- assert(SEE('|') || SEE(stopper) || SEE(EOS));
- t->flags |= COMBINE(t->flags, t->right->flags);
- top->flags |= COMBINE(top->flags, t->flags);
-}
+ if (atom != NULL) {
+ freesubre(v, atom);
+ }
+ top->flags = f;
+ return;
+ }
+
+ /*
+ * hard part: something messy
+ * That is, capturing parens, back reference, short/long clash, or an atom
+ * with substructure containing one of those.
+ */
+
+ /*
+ * Now we'll need a subre for the contents even if they're boring.
+ */
+
+ if (atom == NULL) {
+ atom = subre(v, '=', 0, lp, rp);
+ NOERR();
+ }
+
+ /*
+ * Prepare a general-purpose state skeleton.
+ *
+ * ---> [s] ---prefix---> [begin] ---atom---> [end] ----rest---> [rp]
+ * / /
+ * [lp] ----> [s2] ----bypass---------------------
+ *
+ * where bypass is an empty, and prefix is some repetitions of atom
+ */
+
+ s = newstate(v->nfa); /* first, new endpoints for the atom */
+ s2 = newstate(v->nfa);
+ NOERR();
+ moveouts(v->nfa, lp, s);
+ moveins(v->nfa, rp, s2);
+ NOERR();
+ atom->begin = s;
+ atom->end = s2;
+ s = newstate(v->nfa); /* and spots for prefix and bypass */
+ s2 = newstate(v->nfa);
+ NOERR();
+ EMPTYARC(lp, s);
+ EMPTYARC(lp, s2);
+ NOERR();
+
+ /*
+ * Break remaining subRE into x{...} and what follows.
+ */
+
+ t = subre(v, '.', COMBINE(qprefer, atom->flags), lp, rp);
+ t->left = atom;
+ atomp = &t->left;
+
+ /*
+ * Here we should recurse... but we must postpone that to the end.
+ */
+
+ /*
+ * Split top into prefix and remaining.
+ */
+
+ assert(top->op == '=' && top->left == NULL && top->right == NULL);
+ top->left = subre(v, '=', top->flags, top->begin, lp);
+ top->op = '.';
+ top->right = t;
+
+ /*
+ * If it's a backref, now is the time to replicate the subNFA.
+ */
+
+ if (atomtype == BACKREF) {
+ assert(atom->begin->nouts == 1); /* just the EMPTY */
+ delsub(v->nfa, atom->begin, atom->end);
+ assert(v->subs[subno] != NULL);
+
+ /*
+ * And here's why the recursion got postponed: it must wait until the
+ * skeleton is filled in, because it may hit a backref that wants to
+ * copy the filled-in skeleton.
+ */
+
+ dupnfa(v->nfa, v->subs[subno]->begin, v->subs[subno]->end,
+ atom->begin, atom->end);
+ NOERR();
+ }
+
+ /*
+ * It's quantifier time; first, turn x{0,...} into x{1,...}|empty
+ */
+
+ if (m == 0) {
+ EMPTYARC(s2, atom->end);/* the bypass */
+ assert(PREF(qprefer) != 0);
+ f = COMBINE(qprefer, atom->flags);
+ t = subre(v, '|', f, lp, atom->end);
+ NOERR();
+ t->left = atom;
+ t->right = subre(v, '|', PREF(f), s2, atom->end);
+ NOERR();
+ t->right->left = subre(v, '=', 0, s2, atom->end);
+ NOERR();
+ *atomp = t;
+ atomp = &t->left;
+ m = 1;
+ }
+
+ /*
+ * Deal with the rest of the quantifier.
+ */
+
+ if (atomtype == BACKREF) {
+ /*
+ * Special case: backrefs have internal quantifiers.
+ */
+
+ EMPTYARC(s, atom->begin); /* empty prefix */
+
+ /*
+ * Just stuff everything into atom.
+ */
+
+ repeat(v, atom->begin, atom->end, m, n);
+ atom->min = (short) m;
+ atom->max = (short) n;
+ atom->flags |= COMBINE(qprefer, atom->flags);
+ } else if (m == 1 && n == 1) {
+ /*
+ * No/vacuous quantifier: done.
+ */
+
+ EMPTYARC(s, atom->begin); /* empty prefix */
+ } else {
+ /*
+ * Turn x{m,n} into x{m-1,n-1}x, with capturing parens in only second
+ * x
+ */
+ dupnfa(v->nfa, atom->begin, atom->end, s, atom->begin);
+ assert(m >= 1 && m != INFINITY && n >= 1);
+ repeat(v, s, atom->begin, m-1, (n == INFINITY) ? n : n-1);
+ f = COMBINE(qprefer, atom->flags);
+ t = subre(v, '.', f, s, atom->end); /* prefix and atom */
+ NOERR();
+ t->left = subre(v, '=', PREF(f), s, atom->begin);
+ NOERR();
+ t->right = atom;
+ *atomp = t;
+ }
+
+ /*
+ * And finally, look after that postponed recursion.
+ */
+
+ t = top->right;
+ if (!(SEE('|') || SEE(stopper) || SEE(EOS))) {
+ t->right = parsebranch(v, stopper, type, atom->end, rp, 1);
+ } else {
+ EMPTYARC(atom->end, rp);
+ t->right = subre(v, '=', 0, atom->end, rp);
+ }
+ assert(SEE('|') || SEE(stopper) || SEE(EOS));
+ t->flags |= COMBINE(t->flags, t->right->flags);
+ top->flags |= COMBINE(top->flags, t->flags);
+}
+
/*
- nonword - generate arcs for non-word-character ahead or behind
- ^ static VOID nonword(struct vars *, int, struct state *, struct state *);
+ ^ static void nonword(struct vars *, int, struct state *, struct state *);
*/
-static VOID
-nonword(v, dir, lp, rp)
-struct vars *v;
-int dir; /* AHEAD or BEHIND */
-struct state *lp;
-struct state *rp;
+static void
+nonword(
+ struct vars *v,
+ int dir, /* AHEAD or BEHIND */
+ struct state *lp,
+ struct state *rp)
{
- int anchor = (dir == AHEAD) ? '$' : '^';
+ int anchor = (dir == AHEAD) ? '$' : '^';
- assert(dir == AHEAD || dir == BEHIND);
- newarc(v->nfa, anchor, 1, lp, rp);
- newarc(v->nfa, anchor, 0, lp, rp);
- colorcomplement(v->nfa, v->cm, dir, v->wordchrs, lp, rp);
- /* (no need for special attention to \n) */
+ assert(dir == AHEAD || dir == BEHIND);
+ newarc(v->nfa, anchor, 1, lp, rp);
+ newarc(v->nfa, anchor, 0, lp, rp);
+ colorcomplement(v->nfa, v->cm, dir, v->wordchrs, lp, rp);
+ /* (no need for special attention to \n) */
}
-
+
/*
- word - generate arcs for word character ahead or behind
- ^ static VOID word(struct vars *, int, struct state *, struct state *);
+ ^ static void word(struct vars *, int, struct state *, struct state *);
*/
-static VOID
-word(v, dir, lp, rp)
-struct vars *v;
-int dir; /* AHEAD or BEHIND */
-struct state *lp;
-struct state *rp;
+static void
+word(
+ struct vars *v,
+ int dir, /* AHEAD or BEHIND */
+ struct state *lp,
+ struct state *rp)
{
- assert(dir == AHEAD || dir == BEHIND);
- cloneouts(v->nfa, v->wordchrs, lp, rp, dir);
- /* (no need for special attention to \n) */
+ assert(dir == AHEAD || dir == BEHIND);
+ cloneouts(v->nfa, v->wordchrs, lp, rp, dir);
+ /* (no need for special attention to \n) */
}
-
+
/*
- scannum - scan a number
^ static int scannum(struct vars *);
*/
static int /* value, <= DUPMAX */
-scannum(v)
-struct vars *v;
+scannum(
+ struct vars *v)
{
- int n = 0;
+ int n = 0;
- while (SEE(DIGIT) && n < DUPMAX) {
- n = n*10 + v->nextvalue;
- NEXT();
- }
- if (SEE(DIGIT) || n > DUPMAX) {
- ERR(REG_BADBR);
- return 0;
- }
- return n;
+ while (SEE(DIGIT) && n < DUPMAX) {
+ n = n*10 + v->nextvalue;
+ NEXT();
+ }
+ if (SEE(DIGIT) || n > DUPMAX) {
+ ERR(REG_BADBR);
+ return 0;
+ }
+ return n;
}
-
+
/*
- repeat - replicate subNFA for quantifiers
* The duplication sequences used here are chosen carefully so that any
* pointers starting out pointing into the subexpression end up pointing into
- * the last occurrence. (Note that it may not be strung between the same
- * left and right end states, however!) This used to be important for the
- * subRE tree, although the important bits are now handled by the in-line
- * code in parse(), and when this is called, it doesn't matter any more.
- ^ static VOID repeat(struct vars *, struct state *, struct state *, int, int);
+ * the last occurrence. (Note that it may not be strung between the same left
+ * and right end states, however!) This used to be important for the subRE
+ * tree, although the important bits are now handled by the in-line code in
+ * parse(), and when this is called, it doesn't matter any more.
+ ^ static void repeat(struct vars *, struct state *, struct state *, int, int);
*/
-static VOID
-repeat(v, lp, rp, m, n)
-struct vars *v;
-struct state *lp;
-struct state *rp;
-int m;
-int n;
+static void
+repeat(
+ struct vars *v,
+ struct state *lp,
+ struct state *rp,
+ int m,
+ int n)
{
-# define SOME 2
-# define INF 3
-# define PAIR(x, y) ((x)*4 + (y))
-# define REDUCE(x) ( ((x) == INFINITY) ? INF : (((x) > 1) ? SOME : (x)) )
- CONST int rm = REDUCE(m);
- CONST int rn = REDUCE(n);
- struct state *s;
- struct state *s2;
-
- switch (PAIR(rm, rn)) {
- case PAIR(0, 0): /* empty string */
- delsub(v->nfa, lp, rp);
- EMPTYARC(lp, rp);
- break;
- case PAIR(0, 1): /* do as x| */
- EMPTYARC(lp, rp);
- break;
- case PAIR(0, SOME): /* do as x{1,n}| */
- repeat(v, lp, rp, 1, n);
- NOERR();
- EMPTYARC(lp, rp);
- break;
- case PAIR(0, INF): /* loop x around */
- s = newstate(v->nfa);
- NOERR();
- moveouts(v->nfa, lp, s);
- moveins(v->nfa, rp, s);
- EMPTYARC(lp, s);
- EMPTYARC(s, rp);
- break;
- case PAIR(1, 1): /* no action required */
- break;
- case PAIR(1, SOME): /* do as x{0,n-1}x = (x{1,n-1}|)x */
- s = newstate(v->nfa);
- NOERR();
- moveouts(v->nfa, lp, s);
- dupnfa(v->nfa, s, rp, lp, s);
- NOERR();
- repeat(v, lp, s, 1, n-1);
- NOERR();
- EMPTYARC(lp, s);
- break;
- case PAIR(1, INF): /* add loopback arc */
- s = newstate(v->nfa);
- s2 = newstate(v->nfa);
- NOERR();
- moveouts(v->nfa, lp, s);
- moveins(v->nfa, rp, s2);
- EMPTYARC(lp, s);
- EMPTYARC(s2, rp);
- EMPTYARC(s2, s);
- break;
- case PAIR(SOME, SOME): /* do as x{m-1,n-1}x */
- s = newstate(v->nfa);
- NOERR();
- moveouts(v->nfa, lp, s);
- dupnfa(v->nfa, s, rp, lp, s);
- NOERR();
- repeat(v, lp, s, m-1, n-1);
- break;
- case PAIR(SOME, INF): /* do as x{m-1,}x */
- s = newstate(v->nfa);
- NOERR();
- moveouts(v->nfa, lp, s);
- dupnfa(v->nfa, s, rp, lp, s);
- NOERR();
- repeat(v, lp, s, m-1, n);
- break;
- default:
- ERR(REG_ASSERT);
- break;
- }
+#define SOME 2
+#define INF 3
+#define PAIR(x, y) ((x)*4 + (y))
+#define REDUCE(x) ( ((x) == INFINITY) ? INF : (((x) > 1) ? SOME : (x)) )
+ const int rm = REDUCE(m);
+ const int rn = REDUCE(n);
+ struct state *s, *s2;
+
+ switch (PAIR(rm, rn)) {
+ case PAIR(0, 0): /* empty string */
+ delsub(v->nfa, lp, rp);
+ EMPTYARC(lp, rp);
+ break;
+ case PAIR(0, 1): /* do as x| */
+ EMPTYARC(lp, rp);
+ break;
+ case PAIR(0, SOME): /* do as x{1,n}| */
+ repeat(v, lp, rp, 1, n);
+ NOERR();
+ EMPTYARC(lp, rp);
+ break;
+ case PAIR(0, INF): /* loop x around */
+ s = newstate(v->nfa);
+ NOERR();
+ moveouts(v->nfa, lp, s);
+ moveins(v->nfa, rp, s);
+ EMPTYARC(lp, s);
+ EMPTYARC(s, rp);
+ break;
+ case PAIR(1, 1): /* no action required */
+ break;
+ case PAIR(1, SOME): /* do as x{0,n-1}x = (x{1,n-1}|)x */
+ s = newstate(v->nfa);
+ NOERR();
+ moveouts(v->nfa, lp, s);
+ dupnfa(v->nfa, s, rp, lp, s);
+ NOERR();
+ repeat(v, lp, s, 1, n-1);
+ NOERR();
+ EMPTYARC(lp, s);
+ break;
+ case PAIR(1, INF): /* add loopback arc */
+ s = newstate(v->nfa);
+ s2 = newstate(v->nfa);
+ NOERR();
+ moveouts(v->nfa, lp, s);
+ moveins(v->nfa, rp, s2);
+ EMPTYARC(lp, s);
+ EMPTYARC(s2, rp);
+ EMPTYARC(s2, s);
+ break;
+ case PAIR(SOME, SOME): /* do as x{m-1,n-1}x */
+ s = newstate(v->nfa);
+ NOERR();
+ moveouts(v->nfa, lp, s);
+ dupnfa(v->nfa, s, rp, lp, s);
+ NOERR();
+ repeat(v, lp, s, m-1, n-1);
+ break;
+ case PAIR(SOME, INF): /* do as x{m-1,}x */
+ s = newstate(v->nfa);
+ NOERR();
+ moveouts(v->nfa, lp, s);
+ dupnfa(v->nfa, s, rp, lp, s);
+ NOERR();
+ repeat(v, lp, s, m-1, n);
+ break;
+ default:
+ ERR(REG_ASSERT);
+ break;
+ }
}
-
+
/*
- bracket - handle non-complemented bracket expression
* Also called from cbracket for complemented bracket expressions.
- ^ static VOID bracket(struct vars *, struct state *, struct state *);
+ ^ static void bracket(struct vars *, struct state *, struct state *);
*/
-static VOID
-bracket(v, lp, rp)
-struct vars *v;
-struct state *lp;
-struct state *rp;
+static void
+bracket(
+ struct vars *v,
+ struct state *lp,
+ struct state *rp)
{
- assert(SEE('['));
- NEXT();
- while (!SEE(']') && !SEE(EOS))
- brackpart(v, lp, rp);
- assert(SEE(']') || ISERR());
- okcolors(v->nfa, v->cm);
+ assert(SEE('['));
+ NEXT();
+ while (!SEE(']') && !SEE(EOS)) {
+ brackpart(v, lp, rp);
+ }
+ assert(SEE(']') || ISERR());
+ okcolors(v->nfa, v->cm);
}
-
+
/*
- cbracket - handle complemented bracket expression
* We do it by calling bracket() with dummy endpoints, and then complementing
- * the result. The alternative would be to invoke rainbow(), and then delete
+ * the result. The alternative would be to invoke rainbow(), and then delete
* arcs as the b.e. is seen... but that gets messy.
- ^ static VOID cbracket(struct vars *, struct state *, struct state *);
+ ^ static void cbracket(struct vars *, struct state *, struct state *);
*/
-static VOID
-cbracket(v, lp, rp)
-struct vars *v;
-struct state *lp;
-struct state *rp;
+static void
+cbracket(
+ struct vars *v,
+ struct state *lp,
+ struct state *rp)
{
- struct state *left = newstate(v->nfa);
- struct state *right = newstate(v->nfa);
- struct state *s;
- struct arc *a; /* arc from lp */
- struct arc *ba; /* arc from left, from bracket() */
- struct arc *pa; /* MCCE-prototype arc */
- color co;
- chr *p;
- int i;
+ struct state *left = newstate(v->nfa);
+ struct state *right = newstate(v->nfa);
- NOERR();
- bracket(v, left, right);
- if (v->cflags&REG_NLSTOP)
- newarc(v->nfa, PLAIN, v->nlcolor, left, right);
- NOERR();
+ NOERR();
+ bracket(v, left, right);
+ if (v->cflags&REG_NLSTOP) {
+ newarc(v->nfa, PLAIN, v->nlcolor, left, right);
+ }
+ NOERR();
- assert(lp->nouts == 0); /* all outarcs will be ours */
+ assert(lp->nouts == 0); /* all outarcs will be ours */
- /* easy part of complementing */
- colorcomplement(v->nfa, v->cm, PLAIN, left, lp, rp);
- NOERR();
- if (v->mcces == NULL) { /* no MCCEs -- we're done */
- dropstate(v->nfa, left);
- assert(right->nins == 0);
- freestate(v->nfa, right);
- return;
- }
-
- /* but complementing gets messy in the presence of MCCEs... */
- NOTE(REG_ULOCALE);
- for (p = v->mcces->chrs, i = v->mcces->nchrs; i > 0; p++, i--) {
- co = GETCOLOR(v->cm, *p);
- a = findarc(lp, PLAIN, co);
- ba = findarc(left, PLAIN, co);
- if (ba == NULL) {
- assert(a != NULL);
- freearc(v->nfa, a);
- } else {
- assert(a == NULL);
- }
- s = newstate(v->nfa);
- NOERR();
- newarc(v->nfa, PLAIN, co, lp, s);
- NOERR();
- pa = findarc(v->mccepbegin, PLAIN, co);
- assert(pa != NULL);
- if (ba == NULL) { /* easy case, need all of them */
- cloneouts(v->nfa, pa->to, s, rp, PLAIN);
- newarc(v->nfa, '$', 1, s, rp);
- newarc(v->nfa, '$', 0, s, rp);
- colorcomplement(v->nfa, v->cm, AHEAD, pa->to, s, rp);
- } else { /* must be selective */
- if (findarc(ba->to, '$', 1) == NULL) {
- newarc(v->nfa, '$', 1, s, rp);
- newarc(v->nfa, '$', 0, s, rp);
- colorcomplement(v->nfa, v->cm, AHEAD, pa->to,
- s, rp);
- }
- for (pa = pa->to->outs; pa != NULL; pa = pa->outchain)
- if (findarc(ba->to, PLAIN, pa->co) == NULL)
- newarc(v->nfa, PLAIN, pa->co, s, rp);
- if (s->nouts == 0) /* limit of selectivity: none */
- dropstate(v->nfa, s); /* frees arc too */
- }
- NOERR();
- }
+ /*
+ * Easy part of complementing, and all there is to do since the MCCE code
+ * was removed.
+ */
- delsub(v->nfa, left, right);
- assert(left->nouts == 0);
- freestate(v->nfa, left);
- assert(right->nins == 0);
- freestate(v->nfa, right);
+ colorcomplement(v->nfa, v->cm, PLAIN, left, lp, rp);
+ NOERR();
+ dropstate(v->nfa, left);
+ assert(right->nins == 0);
+ freestate(v->nfa, right);
+ return;
}
-
+
/*
- brackpart - handle one item (or range) within a bracket expression
- ^ static VOID brackpart(struct vars *, struct state *, struct state *);
+ ^ static void brackpart(struct vars *, struct state *, struct state *);
*/
-static VOID
-brackpart(v, lp, rp)
-struct vars *v;
-struct state *lp;
-struct state *rp;
+static void
+brackpart(
+ struct vars *v,
+ struct state *lp,
+ struct state *rp)
{
- celt startc;
- celt endc;
- struct cvec *cv;
- CONST chr *startp;
- CONST chr *endp;
- chr c[1];
-
- /* parse something, get rid of special cases, take shortcuts */
+ celt startc, endc;
+ struct cvec *cv;
+ const chr *startp, *endp;
+ chr c[1];
+
+ /*
+ * Parse something, get rid of special cases, take shortcuts.
+ */
+
+ switch (v->nexttype) {
+ case RANGE: /* a-b-c or other botch */
+ ERR(REG_ERANGE);
+ return;
+ break;
+ case PLAIN:
+ c[0] = v->nextvalue;
+ NEXT();
+
+ /*
+ * Shortcut for ordinary chr (not range).
+ */
+
+ if (!SEE(RANGE)) {
+ onechr(v, c[0], lp, rp);
+ return;
+ }
+ startc = element(v, c, c+1);
+ NOERR();
+ break;
+ case COLLEL:
+ startp = v->now;
+ endp = scanplain(v);
+ INSIST(startp < endp, REG_ECOLLATE);
+ NOERR();
+ startc = element(v, startp, endp);
+ NOERR();
+ break;
+ case ECLASS:
+ startp = v->now;
+ endp = scanplain(v);
+ INSIST(startp < endp, REG_ECOLLATE);
+ NOERR();
+ startc = element(v, startp, endp);
+ NOERR();
+ cv = eclass(v, startc, (v->cflags&REG_ICASE));
+ NOERR();
+ dovec(v, cv, lp, rp);
+ return;
+ break;
+ case CCLASS:
+ startp = v->now;
+ endp = scanplain(v);
+ INSIST(startp < endp, REG_ECTYPE);
+ NOERR();
+ cv = cclass(v, startp, endp, (v->cflags&REG_ICASE));
+ NOERR();
+ dovec(v, cv, lp, rp);
+ return;
+ break;
+ default:
+ ERR(REG_ASSERT);
+ return;
+ break;
+ }
+
+ if (SEE(RANGE)) {
+ NEXT();
switch (v->nexttype) {
- case RANGE: /* a-b-c or other botch */
- ERR(REG_ERANGE);
- return;
- break;
case PLAIN:
- c[0] = v->nextvalue;
- NEXT();
- /* shortcut for ordinary chr (not range, not MCCE leader) */
- if (!SEE(RANGE) && !ISCELEADER(v, c[0])) {
- onechr(v, c[0], lp, rp);
- return;
- }
- startc = element(v, c, c+1);
- NOERR();
- break;
+ case RANGE:
+ c[0] = v->nextvalue;
+ NEXT();
+ endc = element(v, c, c+1);
+ NOERR();
+ break;
case COLLEL:
- startp = v->now;
- endp = scanplain(v);
- INSIST(startp < endp, REG_ECOLLATE);
- NOERR();
- startc = element(v, startp, endp);
- NOERR();
- break;
- case ECLASS:
- startp = v->now;
- endp = scanplain(v);
- INSIST(startp < endp, REG_ECOLLATE);
- NOERR();
- startc = element(v, startp, endp);
- NOERR();
- cv = eclass(v, startc, (v->cflags&REG_ICASE));
- NOERR();
- dovec(v, cv, lp, rp);
- return;
- break;
- case CCLASS:
- startp = v->now;
- endp = scanplain(v);
- INSIST(startp < endp, REG_ECTYPE);
- NOERR();
- cv = cclass(v, startp, endp, (v->cflags&REG_ICASE));
- NOERR();
- dovec(v, cv, lp, rp);
- return;
- break;
+ startp = v->now;
+ endp = scanplain(v);
+ INSIST(startp < endp, REG_ECOLLATE);
+ NOERR();
+ endc = element(v, startp, endp);
+ NOERR();
+ break;
default:
- ERR(REG_ASSERT);
- return;
- break;
+ ERR(REG_ERANGE);
+ return;
+ break;
}
+ } else {
+ endc = startc;
+ }
- if (SEE(RANGE)) {
- NEXT();
- switch (v->nexttype) {
- case PLAIN:
- case RANGE:
- c[0] = v->nextvalue;
- NEXT();
- endc = element(v, c, c+1);
- NOERR();
- break;
- case COLLEL:
- startp = v->now;
- endp = scanplain(v);
- INSIST(startp < endp, REG_ECOLLATE);
- NOERR();
- endc = element(v, startp, endp);
- NOERR();
- break;
- default:
- ERR(REG_ERANGE);
- return;
- break;
- }
- } else
- endc = startc;
+ /*
+ * Ranges are unportable. Actually, standard C does guarantee that digits
+ * are contiguous, but making that an exception is just too complicated.
+ */
- /*
- * Ranges are unportable. Actually, standard C does
- * guarantee that digits are contiguous, but making
- * that an exception is just too complicated.
- */
- if (startc != endc)
- NOTE(REG_UUNPORT);
- cv = range(v, startc, endc, (v->cflags&REG_ICASE));
- NOERR();
- dovec(v, cv, lp, rp);
+ if (startc != endc) {
+ NOTE(REG_UUNPORT);
+ }
+ cv = range(v, startc, endc, (v->cflags&REG_ICASE));
+ NOERR();
+ dovec(v, cv, lp, rp);
}
-
+
/*
- scanplain - scan PLAIN contents of [. etc.
- * Certain bits of trickery in lex.c know that this code does not try
- * to look past the final bracket of the [. etc.
- ^ static chr *scanplain(struct vars *);
+ * Certain bits of trickery in lex.c know that this code does not try to look
+ * past the final bracket of the [. etc.
+ ^ static const chr *scanplain(struct vars *);
*/
-static CONST chr * /* just after end of sequence */
-scanplain(v)
-struct vars *v;
+static const chr * /* just after end of sequence */
+scanplain(
+ struct vars *v)
{
- CONST chr *endp;
+ const chr *endp;
- assert(SEE(COLLEL) || SEE(ECLASS) || SEE(CCLASS));
- NEXT();
+ assert(SEE(COLLEL) || SEE(ECLASS) || SEE(CCLASS));
+ NEXT();
+ endp = v->now;
+ while (SEE(PLAIN)) {
endp = v->now;
- while (SEE(PLAIN)) {
- endp = v->now;
- NEXT();
- }
-
- assert(SEE(END) || ISERR());
NEXT();
+ }
- return endp;
-}
+ assert(SEE(END) || ISERR());
+ NEXT();
+ return endp;
+}
+
/*
- onechr - fill in arcs for a plain character, and possible case complements
* This is mostly a shortcut for efficient handling of the common case.
- ^ static VOID onechr(struct vars *, pchr, struct state *, struct state *);
+ ^ static void onechr(struct vars *, pchr, struct state *, struct state *);
*/
-static VOID
-onechr(v, c, lp, rp)
-struct vars *v;
-pchr c;
-struct state *lp;
-struct state *rp;
+static void
+onechr(
+ struct vars *v,
+ pchr c,
+ struct state *lp,
+ struct state *rp)
{
- if (!(v->cflags&REG_ICASE)) {
- newarc(v->nfa, PLAIN, subcolor(v->cm, c), lp, rp);
- return;
- }
+ if (!(v->cflags&REG_ICASE)) {
+ newarc(v->nfa, PLAIN, subcolor(v->cm, c), lp, rp);
+ return;
+ }
- /* rats, need general case anyway... */
- dovec(v, allcases(v, c), lp, rp);
-}
+ /*
+ * Rats, need general case anyway...
+ */
+ dovec(v, allcases(v, c), lp, rp);
+}
+
/*
- dovec - fill in arcs for each element of a cvec
- * This one has to handle the messy cases, like MCCEs and MCCE leaders.
- ^ static VOID dovec(struct vars *, struct cvec *, struct state *,
+ ^ static void dovec(struct vars *, struct cvec *, struct state *,
^ struct state *);
*/
-static VOID
-dovec(v, cv, lp, rp)
-struct vars *v;
-struct cvec *cv;
-struct state *lp;
-struct state *rp;
+static void
+dovec(
+ struct vars *v,
+ struct cvec *cv,
+ struct state *lp,
+ struct state *rp)
{
- chr ch, from, to;
- celt ce;
- chr *p;
- int i;
- color co;
- struct cvec *leads;
- struct arc *a;
- struct arc *pa; /* arc in prototype */
- struct state *s;
- struct state *ps; /* state in prototype */
-
- leads = NULL;
-
- /* first, get the ordinary characters out of the way */
- for (p = cv->chrs, i = cv->nchrs; i > 0; p++, i--) {
- ch = *p;
- if (!ISCELEADER(v, ch))
- newarc(v->nfa, PLAIN, subcolor(v->cm, ch), lp, rp);
- else {
- assert(singleton(v->cm, ch));
- assert(leads != NULL);
- if (!haschr(leads, ch))
- addchr(leads, ch);
- }
- }
-
- /* and the ranges */
- for (p = cv->ranges, i = cv->nranges; i > 0; p += 2, i--) {
- from = *p;
- to = *(p+1);
- while (from <= to && (ce = nextleader(v, from, to)) != NOCELT) {
- if (from < ce)
- subrange(v, from, ce - 1, lp, rp);
- assert(singleton(v->cm, ce));
- assert(leads != NULL);
- if (!haschr(leads, ce))
- addchr(leads, ce);
- from = ce + 1;
- }
- if (from <= to)
- subrange(v, from, to, lp, rp);
+ chr ch, from, to;
+ const chr *p;
+ int i;
+
+ for (p = cv->chrs, i = cv->nchrs; i > 0; p++, i--) {
+ ch = *p;
+ newarc(v->nfa, PLAIN, subcolor(v->cm, ch), lp, rp);
+ }
+
+ for (p = cv->ranges, i = cv->nranges; i > 0; p += 2, i--) {
+ from = *p;
+ to = *(p+1);
+ if (from <= to) {
+ subrange(v, from, to, lp, rp);
}
+ }
- if ((leads == NULL || leads->nchrs == 0) && cv->nmcces == 0)
- return;
-
- /* deal with the MCCE leaders */
- NOTE(REG_ULOCALE);
- for (p = leads->chrs, i = leads->nchrs; i > 0; p++, i--) {
- co = GETCOLOR(v->cm, *p);
- a = findarc(lp, PLAIN, co);
- if (a != NULL)
- s = a->to;
- else {
- s = newstate(v->nfa);
- NOERR();
- newarc(v->nfa, PLAIN, co, lp, s);
- NOERR();
- }
- pa = findarc(v->mccepbegin, PLAIN, co);
- assert(pa != NULL);
- ps = pa->to;
- newarc(v->nfa, '$', 1, s, rp);
- newarc(v->nfa, '$', 0, s, rp);
- colorcomplement(v->nfa, v->cm, AHEAD, ps, s, rp);
- NOERR();
- }
-
- /* and the MCCEs */
- for (i = 0; i < cv->nmcces; i++) {
- p = cv->mcces[i];
- assert(singleton(v->cm, *p));
- if (!singleton(v->cm, *p)) {
- ERR(REG_ASSERT);
- return;
- }
- ch = *p++;
- co = GETCOLOR(v->cm, ch);
- a = findarc(lp, PLAIN, co);
- if (a != NULL)
- s = a->to;
- else {
- s = newstate(v->nfa);
- NOERR();
- newarc(v->nfa, PLAIN, co, lp, s);
- NOERR();
- }
- assert(*p != 0); /* at least two chars */
- assert(singleton(v->cm, *p));
- ch = *p++;
- co = GETCOLOR(v->cm, ch);
- assert(*p == 0); /* and only two, for now */
- newarc(v->nfa, PLAIN, co, s, rp);
- NOERR();
- }
-}
-
-/*
- - nextleader - find next MCCE leader within range
- ^ static celt nextleader(struct vars *, pchr, pchr);
- */
-static celt /* NOCELT means none */
-nextleader(v, from, to)
-struct vars *v;
-pchr from;
-pchr to;
-{
- int i;
- chr *p;
- chr ch;
- celt it = NOCELT;
-
- if (v->mcces == NULL)
- return it;
-
- for (i = v->mcces->nchrs, p = v->mcces->chrs; i > 0; i--, p++) {
- ch = *p;
- if (from <= ch && ch <= to)
- if (it == NOCELT || ch < it)
- it = ch;
- }
- return it;
}
-
+
/*
- wordchrs - set up word-chr list for word-boundary stuff, if needed
- * The list is kept as a bunch of arcs between two dummy states; it's
- * disposed of by the unreachable-states sweep in NFA optimization.
- * Does NEXT(). Must not be called from any unusual lexical context.
- * This should be reconciled with the \w etc. handling in lex.c, and
- * should be cleaned up to reduce dependencies on input scanning.
- ^ static VOID wordchrs(struct vars *);
+ * The list is kept as a bunch of arcs between two dummy states; it's disposed
+ * of by the unreachable-states sweep in NFA optimization. Does NEXT(). Must
+ * not be called from any unusual lexical context. This should be reconciled
+ * with the \w etc. handling in lex.c, and should be cleaned up to reduce
+ * dependencies on input scanning.
+ ^ static void wordchrs(struct vars *);
*/
-static VOID
-wordchrs(v)
-struct vars *v;
+static void
+wordchrs(
+ struct vars *v)
{
- struct state *left;
- struct state *right;
+ struct state *left, *right;
- if (v->wordchrs != NULL) {
- NEXT(); /* for consistency */
- return;
- }
+ if (v->wordchrs != NULL) {
+ NEXT(); /* for consistency */
+ return;
+ }
- left = newstate(v->nfa);
- right = newstate(v->nfa);
- NOERR();
- /* fine point: implemented with [::], and lexer will set REG_ULOCALE */
- lexword(v);
- NEXT();
- assert(v->savenow != NULL && SEE('['));
- bracket(v, left, right);
- assert((v->savenow != NULL && SEE(']')) || ISERR());
- NEXT();
- NOERR();
- v->wordchrs = left;
-}
+ left = newstate(v->nfa);
+ right = newstate(v->nfa);
+ NOERR();
+ /*
+ * Fine point: implemented with [::], and lexer will set REG_ULOCALE.
+ */
+
+ lexword(v);
+ NEXT();
+ assert(v->savenow != NULL && SEE('['));
+ bracket(v, left, right);
+ assert((v->savenow != NULL && SEE(']')) || ISERR());
+ NEXT();
+ NOERR();
+ v->wordchrs = left;
+}
+
/*
- subre - allocate a subre
^ static struct subre *subre(struct vars *, int, int, struct state *,
^ struct state *);
*/
static struct subre *
-subre(v, op, flags, begin, end)
-struct vars *v;
-int op;
-int flags;
-struct state *begin;
-struct state *end;
+subre(
+ struct vars *v,
+ int op,
+ int flags,
+ struct state *begin,
+ struct state *end)
{
- struct subre *ret;
-
- ret = v->treefree;
- if (ret != NULL)
- v->treefree = ret->left;
- else {
- ret = (struct subre *)MALLOC(sizeof(struct subre));
- if (ret == NULL) {
- ERR(REG_ESPACE);
- return NULL;
- }
- ret->chain = v->treechain;
- v->treechain = ret;
+ struct subre *ret = v->treefree;
+
+ if (ret != NULL) {
+ v->treefree = ret->left;
+ } else {
+ ret = (struct subre *) MALLOC(sizeof(struct subre));
+ if (ret == NULL) {
+ ERR(REG_ESPACE);
+ return NULL;
}
-
- assert(strchr("|.b(=", op) != NULL);
-
- ret->op = op;
- ret->flags = flags;
- ret->retry = 0;
- ret->subno = 0;
- ret->min = ret->max = 1;
- ret->left = NULL;
- ret->right = NULL;
- ret->begin = begin;
- ret->end = end;
- ZAPCNFA(ret->cnfa);
-
- return ret;
+ ret->chain = v->treechain;
+ v->treechain = ret;
+ }
+
+ assert(strchr("|.b(=", op) != NULL);
+
+ ret->op = op;
+ ret->flags = flags;
+ ret->retry = 0;
+ ret->subno = 0;
+ ret->min = ret->max = 1;
+ ret->left = NULL;
+ ret->right = NULL;
+ ret->begin = begin;
+ ret->end = end;
+ ZAPCNFA(ret->cnfa);
+
+ return ret;
}
-
+
/*
- freesubre - free a subRE subtree
- ^ static VOID freesubre(struct vars *, struct subre *);
+ ^ static void freesubre(struct vars *, struct subre *);
*/
-static VOID
-freesubre(v, sr)
-struct vars *v; /* might be NULL */
-struct subre *sr;
+static void
+freesubre(
+ struct vars *v, /* might be NULL */
+ struct subre *sr)
{
- if (sr == NULL)
- return;
-
- if (sr->left != NULL)
- freesubre(v, sr->left);
- if (sr->right != NULL)
- freesubre(v, sr->right);
-
- freesrnode(v, sr);
+ if (sr == NULL) {
+ return;
+ }
+
+ if (sr->left != NULL) {
+ freesubre(v, sr->left);
+ }
+ if (sr->right != NULL) {
+ freesubre(v, sr->right);
+ }
+
+ freesrnode(v, sr);
}
-
+
/*
- freesrnode - free one node in a subRE subtree
- ^ static VOID freesrnode(struct vars *, struct subre *);
+ ^ static void freesrnode(struct vars *, struct subre *);
*/
-static VOID
-freesrnode(v, sr)
-struct vars *v; /* might be NULL */
-struct subre *sr;
+static void
+freesrnode(
+ struct vars *v, /* might be NULL */
+ struct subre *sr)
{
- if (sr == NULL)
- return;
-
- if (!NULLCNFA(sr->cnfa))
- freecnfa(&sr->cnfa);
- sr->flags = 0;
-
- if (v != NULL) {
- sr->left = v->treefree;
- v->treefree = sr;
- } else
- FREE(sr);
+ if (sr == NULL) {
+ return;
+ }
+
+ if (!NULLCNFA(sr->cnfa)) {
+ freecnfa(&sr->cnfa);
+ }
+ sr->flags = 0;
+
+ if (v != NULL) {
+ sr->left = v->treefree;
+ v->treefree = sr;
+ } else {
+ FREE(sr);
+ }
}
-
+
/*
- optst - optimize a subRE subtree
- ^ static VOID optst(struct vars *, struct subre *);
+ ^ static void optst(struct vars *, struct subre *);
*/
-static VOID
-optst(v, t)
-struct vars *v;
-struct subre *t;
+static void
+optst(
+ struct vars *v,
+ struct subre *t)
{
/*
* DGP (2007-11-13): I assume it was the programmer's intent to eventually
* come back and add code to optimize subRE trees, but the routine coded
- * just spent effort traversing the tree and doing nothing. We can do
+ * just spends effort traversing the tree and doing nothing. We can do
* nothing with less effort.
*/
return;
}
-
+
/*
- numst - number tree nodes (assigning retry indexes)
^ static int numst(struct subre *, int);
*/
static int /* next number */
-numst(t, start)
-struct subre *t;
-int start; /* starting point for subtree numbers */
+numst(
+ struct subre *t,
+ int start) /* starting point for subtree numbers */
{
- int i;
-
- assert(t != NULL);
-
- i = start;
- t->retry = (short)i++;
- if (t->left != NULL)
- i = numst(t->left, i);
- if (t->right != NULL)
- i = numst(t->right, i);
- return i;
+ int i;
+
+ assert(t != NULL);
+
+ i = start;
+ t->retry = (short) i++;
+ if (t->left != NULL) {
+ i = numst(t->left, i);
+ }
+ if (t->right != NULL) {
+ i = numst(t->right, i);
+ }
+ return i;
}
-
+
/*
- markst - mark tree nodes as INUSE
- ^ static VOID markst(struct subre *);
+ ^ static void markst(struct subre *);
*/
-static VOID
-markst(t)
-struct subre *t;
+static void
+markst(
+ struct subre *t)
{
- assert(t != NULL);
-
- t->flags |= INUSE;
- if (t->left != NULL)
- markst(t->left);
- if (t->right != NULL)
- markst(t->right);
+ assert(t != NULL);
+
+ t->flags |= INUSE;
+ if (t->left != NULL) {
+ markst(t->left);
+ }
+ if (t->right != NULL) {
+ markst(t->right);
+ }
}
-
+
/*
- cleanst - free any tree nodes not marked INUSE
- ^ static VOID cleanst(struct vars *);
+ ^ static void cleanst(struct vars *);
*/
-static VOID
-cleanst(v)
-struct vars *v;
+static void
+cleanst(
+ struct vars *v)
{
- struct subre *t;
- struct subre *next;
+ struct subre *t;
+ struct subre *next;
- for (t = v->treechain; t != NULL; t = next) {
- next = t->chain;
- if (!(t->flags&INUSE))
- FREE(t);
+ for (t = v->treechain; t != NULL; t = next) {
+ next = t->chain;
+ if (!(t->flags&INUSE)) {
+ FREE(t);
}
- v->treechain = NULL;
- v->treefree = NULL; /* just on general principles */
+ }
+ v->treechain = NULL;
+ v->treefree = NULL; /* just on general principles */
}
-
+
/*
- nfatree - turn a subRE subtree into a tree of compacted NFAs
^ static long nfatree(struct vars *, struct subre *, FILE *);
*/
static long /* optimize results from top node */
-nfatree(v, t, f)
-struct vars *v;
-struct subre *t;
-FILE *f; /* for debug output */
+nfatree(
+ struct vars *v,
+ struct subre *t,
+ FILE *f) /* for debug output */
{
- assert(t != NULL && t->begin != NULL);
+ assert(t != NULL && t->begin != NULL);
- if (t->left != NULL)
- (DISCARD)nfatree(v, t->left, f);
- if (t->right != NULL)
- (DISCARD)nfatree(v, t->right, f);
+ if (t->left != NULL) {
+ (DISCARD) nfatree(v, t->left, f);
+ }
+ if (t->right != NULL) {
+ (DISCARD) nfatree(v, t->right, f);
+ }
- return nfanode(v, t, f);
+ return nfanode(v, t, f);
}
-
+
/*
- nfanode - do one NFA for nfatree
^ static long nfanode(struct vars *, struct subre *, FILE *);
*/
static long /* optimize results */
-nfanode(v, t, f)
-struct vars *v;
-struct subre *t;
-FILE *f; /* for debug output */
+nfanode(
+ struct vars *v,
+ struct subre *t,
+ FILE *f) /* for debug output */
{
- struct nfa *nfa;
- long ret = 0;
- char idbuf[50];
-
- assert(t->begin != NULL);
-
- if (f != NULL)
- fprintf(f, "\n\n\n========= TREE NODE %s ==========\n",
- stid(t, idbuf, sizeof(idbuf)));
- nfa = newnfa(v, v->cm, v->nfa);
- NOERRZ();
- dupnfa(nfa, t->begin, t->end, nfa->init, nfa->final);
- if (!ISERR()) {
- specialcolors(nfa);
- ret = optimize(nfa, f);
- }
- if (!ISERR())
- compact(nfa, &t->cnfa);
-
- freenfa(nfa);
- return ret;
+ struct nfa *nfa;
+ long ret = 0;
+ char idbuf[50];
+
+ assert(t->begin != NULL);
+
+ if (f != NULL) {
+ fprintf(f, "\n\n\n========= TREE NODE %s ==========\n",
+ stid(t, idbuf, sizeof(idbuf)));
+ }
+ nfa = newnfa(v, v->cm, v->nfa);
+ NOERRZ();
+ dupnfa(nfa, t->begin, t->end, nfa->init, nfa->final);
+ if (!ISERR()) {
+ specialcolors(nfa);
+ ret = optimize(nfa, f);
+ }
+ if (!ISERR()) {
+ compact(nfa, &t->cnfa);
+ }
+
+ freenfa(nfa);
+ return ret;
}
-
+
/*
- newlacon - allocate a lookahead-constraint subRE
^ static int newlacon(struct vars *, struct state *, struct state *, int);
*/
static int /* lacon number */
-newlacon(v, begin, end, pos)
-struct vars *v;
-struct state *begin;
-struct state *end;
-int pos;
+newlacon(
+ struct vars *v,
+ struct state *begin,
+ struct state *end,
+ int pos)
{
- int n;
- struct subre *sub;
-
- if (v->nlacons == 0) {
- v->lacons = (struct subre *)MALLOC(2 * sizeof(struct subre));
- n = 1; /* skip 0th */
- v->nlacons = 2;
- } else {
- v->lacons = (struct subre *)REALLOC(v->lacons,
- (v->nlacons+1)*sizeof(struct subre));
- n = v->nlacons++;
- }
- if (v->lacons == NULL) {
- ERR(REG_ESPACE);
- return 0;
- }
- sub = &v->lacons[n];
- sub->begin = begin;
- sub->end = end;
- sub->subno = pos;
- ZAPCNFA(sub->cnfa);
- return n;
+ struct subre *sub;
+ int n;
+
+ if (v->nlacons == 0) {
+ v->lacons = (struct subre *) MALLOC(2 * sizeof(struct subre));
+ n = 1; /* skip 0th */
+ v->nlacons = 2;
+ } else {
+ v->lacons = (struct subre *) REALLOC(v->lacons,
+ (v->nlacons+1)*sizeof(struct subre));
+ n = v->nlacons++;
+ }
+
+ if (v->lacons == NULL) {
+ ERR(REG_ESPACE);
+ return 0;
+ }
+
+ sub = &v->lacons[n];
+ sub->begin = begin;
+ sub->end = end;
+ sub->subno = pos;
+ ZAPCNFA(sub->cnfa);
+ return n;
}
-
+
/*
- freelacons - free lookahead-constraint subRE vector
- ^ static VOID freelacons(struct subre *, int);
+ ^ static void freelacons(struct subre *, int);
*/
-static VOID
-freelacons(subs, n)
-struct subre *subs;
-int n;
+static void
+freelacons(
+ struct subre *subs,
+ int n)
{
- struct subre *sub;
- int i;
-
- assert(n > 0);
- for (sub = subs + 1, i = n - 1; i > 0; sub++, i--) /* no 0th */
- if (!NULLCNFA(sub->cnfa))
- freecnfa(&sub->cnfa);
- FREE(subs);
-}
+ struct subre *sub;
+ int i;
+ assert(n > 0);
+ for (sub=subs+1, i=n-1; i>0; sub++, i--) { /* no 0th */
+ if (!NULLCNFA(sub->cnfa)) {
+ freecnfa(&sub->cnfa);
+ }
+ }
+ FREE(subs);
+}
+
/*
- rfree - free a whole RE (insides of regfree)
- ^ static VOID rfree(regex_t *);
+ ^ static void rfree(regex_t *);
*/
-static VOID
-rfree(re)
-regex_t *re;
+static void
+rfree(
+ regex_t *re)
{
- struct guts *g;
-
- if (re == NULL || re->re_magic != REMAGIC)
- return;
-
- re->re_magic = 0; /* invalidate RE */
- g = (struct guts *)re->re_guts;
- re->re_guts = NULL;
- re->re_fns = NULL;
- g->magic = 0;
- freecm(&g->cmap);
- if (g->tree != NULL)
- freesubre((struct vars *)NULL, g->tree);
- if (g->lacons != NULL)
- freelacons(g->lacons, g->nlacons);
- if (!NULLCNFA(g->search))
- freecnfa(&g->search);
- FREE(g);
+ struct guts *g;
+
+ if (re == NULL || re->re_magic != REMAGIC) {
+ return;
+ }
+
+ re->re_magic = 0; /* invalidate RE */
+ g = (struct guts *) re->re_guts;
+ re->re_guts = NULL;
+ re->re_fns = NULL;
+ g->magic = 0;
+ freecm(&g->cmap);
+ if (g->tree != NULL) {
+ freesubre(NULL, g->tree);
+ }
+ if (g->lacons != NULL) {
+ freelacons(g->lacons, g->nlacons);
+ }
+ if (!NULLCNFA(g->search)) {
+ freecnfa(&g->search);
+ }
+ FREE(g);
}
-
+
/*
- dump - dump an RE in human-readable form
- ^ static VOID dump(regex_t *, FILE *);
+ ^ static void dump(regex_t *, FILE *);
*/
-static VOID
-dump(re, f)
-regex_t *re;
-FILE *f;
+static void
+dump(
+ regex_t *re,
+ FILE *f)
{
#ifdef REG_DEBUG
- struct guts *g;
- int i;
-
- if (re->re_magic != REMAGIC)
- fprintf(f, "bad magic number (0x%x not 0x%x)\n", re->re_magic,
- REMAGIC);
- if (re->re_guts == NULL) {
- fprintf(f, "NULL guts!!!\n");
- return;
- }
- g = (struct guts *)re->re_guts;
- if (g->magic != GUTSMAGIC)
- fprintf(f, "bad guts magic number (0x%x not 0x%x)\n", g->magic,
- GUTSMAGIC);
-
- fprintf(f, "\n\n\n========= DUMP ==========\n");
- fprintf(f, "nsub %d, info 0%lo, csize %d, ntree %d\n",
- re->re_nsub, re->re_info, re->re_csize, g->ntree);
-
- dumpcolors(&g->cmap, f);
- if (!NULLCNFA(g->search)) {
- printf("\nsearch:\n");
- dumpcnfa(&g->search, f);
- }
- for (i = 1; i < g->nlacons; i++) {
- fprintf(f, "\nla%d (%s):\n", i,
- (g->lacons[i].subno) ? "positive" : "negative");
- dumpcnfa(&g->lacons[i].cnfa, f);
- }
- fprintf(f, "\n");
- dumpst(g->tree, f, 0);
+ struct guts *g;
+ int i;
+
+ if (re->re_magic != REMAGIC) {
+ fprintf(f, "bad magic number (0x%x not 0x%x)\n",
+ re->re_magic, REMAGIC);
+ }
+ if (re->re_guts == NULL) {
+ fprintf(f, "NULL guts!!!\n");
+ return;
+ }
+ g = (struct guts *) re->re_guts;
+ if (g->magic != GUTSMAGIC) {
+ fprintf(f, "bad guts magic number (0x%x not 0x%x)\n",
+ g->magic, GUTSMAGIC);
+ }
+
+ fprintf(f, "\n\n\n========= DUMP ==========\n");
+ fprintf(f, "nsub %d, info 0%lo, csize %d, ntree %d\n",
+ re->re_nsub, re->re_info, re->re_csize, g->ntree);
+
+ dumpcolors(&g->cmap, f);
+ if (!NULLCNFA(g->search)) {
+ printf("\nsearch:\n");
+ dumpcnfa(&g->search, f);
+ }
+ for (i = 1; i < g->nlacons; i++) {
+ fprintf(f, "\nla%d (%s):\n", i,
+ (g->lacons[i].subno) ? "positive" : "negative");
+ dumpcnfa(&g->lacons[i].cnfa, f);
+ }
+ fprintf(f, "\n");
+ dumpst(g->tree, f, 0);
#endif
}
-
+
/*
- dumpst - dump a subRE tree
- ^ static VOID dumpst(struct subre *, FILE *, int);
+ ^ static void dumpst(struct subre *, FILE *, int);
*/
-static VOID
-dumpst(t, f, nfapresent)
-struct subre *t;
-FILE *f;
-int nfapresent; /* is the original NFA still around? */
+static void
+dumpst(
+ struct subre *t,
+ FILE *f,
+ int nfapresent) /* is the original NFA still around? */
{
- if (t == NULL)
- fprintf(f, "null tree\n");
- else
- stdump(t, f, nfapresent);
- fflush(f);
+ if (t == NULL) {
+ fprintf(f, "null tree\n");
+ } else {
+ stdump(t, f, nfapresent);
+ }
+ fflush(f);
}
-
+
/*
- stdump - recursive guts of dumpst
- ^ static VOID stdump(struct subre *, FILE *, int);
+ ^ static void stdump(struct subre *, FILE *, int);
*/
-static VOID
-stdump(t, f, nfapresent)
-struct subre *t;
-FILE *f;
-int nfapresent; /* is the original NFA still around? */
+static void
+stdump(
+ struct subre *t,
+ FILE *f,
+ int nfapresent) /* is the original NFA still around? */
{
- char idbuf[50];
-
- fprintf(f, "%s. `%c'", stid(t, idbuf, sizeof(idbuf)), t->op);
- if (t->flags&LONGER)
- fprintf(f, " longest");
- if (t->flags&SHORTER)
- fprintf(f, " shortest");
- if (t->flags&MIXED)
- fprintf(f, " hasmixed");
- if (t->flags&CAP)
- fprintf(f, " hascapture");
- if (t->flags&BACKR)
- fprintf(f, " hasbackref");
- if (!(t->flags&INUSE))
- fprintf(f, " UNUSED");
- if (t->subno != 0)
- fprintf(f, " (#%d)", t->subno);
- if (t->min != 1 || t->max != 1) {
- fprintf(f, " {%d,", t->min);
- if (t->max != INFINITY)
- fprintf(f, "%d", t->max);
- fprintf(f, "}");
- }
- if (nfapresent)
- fprintf(f, " %ld-%ld", (long)t->begin->no, (long)t->end->no);
- if (t->left != NULL)
- fprintf(f, " L:%s", stid(t->left, idbuf, sizeof(idbuf)));
- if (t->right != NULL)
- fprintf(f, " R:%s", stid(t->right, idbuf, sizeof(idbuf)));
- if (!NULLCNFA(t->cnfa)) {
- fprintf(f, "\n");
- dumpcnfa(&t->cnfa, f);
+ char idbuf[50];
+
+ fprintf(f, "%s. `%c'", stid(t, idbuf, sizeof(idbuf)), t->op);
+ if (t->flags&LONGER) {
+ fprintf(f, " longest");
+ }
+ if (t->flags&SHORTER) {
+ fprintf(f, " shortest");
+ }
+ if (t->flags&MIXED) {
+ fprintf(f, " hasmixed");
+ }
+ if (t->flags&CAP) {
+ fprintf(f, " hascapture");
+ }
+ if (t->flags&BACKR) {
+ fprintf(f, " hasbackref");
+ }
+ if (!(t->flags&INUSE)) {
+ fprintf(f, " UNUSED");
+ }
+ if (t->subno != 0) {
+ fprintf(f, " (#%d)", t->subno);
+ }
+ if (t->min != 1 || t->max != 1) {
+ fprintf(f, " {%d,", t->min);
+ if (t->max != INFINITY) {
+ fprintf(f, "%d", t->max);
}
+ fprintf(f, "}");
+ }
+ if (nfapresent) {
+ fprintf(f, " %ld-%ld", (long)t->begin->no, (long)t->end->no);
+ }
+ if (t->left != NULL) {
+ fprintf(f, " L:%s", stid(t->left, idbuf, sizeof(idbuf)));
+ }
+ if (t->right != NULL) {
+ fprintf(f, " R:%s", stid(t->right, idbuf, sizeof(idbuf)));
+ }
+ if (!NULLCNFA(t->cnfa)) {
fprintf(f, "\n");
- if (t->left != NULL)
- stdump(t->left, f, nfapresent);
- if (t->right != NULL)
- stdump(t->right, f, nfapresent);
+ dumpcnfa(&t->cnfa, f);
+ }
+ fprintf(f, "\n");
+ if (t->left != NULL) {
+ stdump(t->left, f, nfapresent);
+ }
+ if (t->right != NULL) {
+ stdump(t->right, f, nfapresent);
+ }
}
-
+
/*
- stid - identify a subtree node for dumping
- ^ static char *stid(struct subre *, char *, size_t);
+ ^ static const char *stid(struct subre *, char *, size_t);
*/
-static char * /* points to buf or constant string */
-stid(t, buf, bufsize)
-struct subre *t;
-char *buf;
-size_t bufsize;
+static const char * /* points to buf or constant string */
+stid(
+ struct subre *t,
+ char *buf,
+ size_t bufsize)
{
- /* big enough for hex int or decimal t->retry? */
- if (bufsize < sizeof(void*)*2 + 3 || bufsize < sizeof(t->retry)*3 + 1)
- return "unable";
- if (t->retry != 0)
- sprintf(buf, "%d", t->retry);
- else
- sprintf(buf, "%p", t);
- return buf;
+ /*
+ * Big enough for hex int or decimal t->retry?
+ */
+
+ if (bufsize < sizeof(void*)*2 + 3 || bufsize < sizeof(t->retry)*3 + 1) {
+ return "unable";
+ }
+ if (t->retry != 0) {
+ sprintf(buf, "%d", t->retry);
+ } else {
+ sprintf(buf, "%p", t);
+ }
+ return buf;
}
#include "regc_lex.c"
@@ -2108,3 +2159,11 @@ size_t bufsize;
#include "regc_nfa.c"
#include "regc_cvec.c"
#include "regc_locale.c"
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/regcustom.h b/generic/regcustom.h
index 5b6815c..57a2d47 100644
--- a/generic/regcustom.h
+++ b/generic/regcustom.h
@@ -1,22 +1,22 @@
/*
* Copyright (c) 1998, 1999 Henry Spencer. All rights reserved.
- *
+ *
* Development of this software was funded, in part, by Cray Research Inc.,
* UUNET Communications Services Inc., Sun Microsystems Inc., and Scriptics
- * Corporation, none of whom are responsible for the results. The author
- * thanks all of them.
- *
- * Redistribution and use in source and binary forms -- with or without
- * modification -- are permitted for any purpose, provided that
- * redistributions in source form retain this entire copyright notice and
- * indicate the origin and nature of any modifications.
- *
- * I'd appreciate being given credit for this package in the documentation
- * of software which uses it, but that is not a requirement.
- *
+ * Corporation, none of whom are responsible for the results. The author
+ * thanks all of them.
+ *
+ * Redistribution and use in source and binary forms - with or without
+ * modification - are permitted for any purpose, provided that redistributions
+ * in source form retain this entire copyright notice and indicate the origin
+ * and nature of any modifications.
+ *
+ * I'd appreciate being given credit for this package in the documentation of
+ * software which uses it, but that is not a requirement.
+ *
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* HENRY SPENCER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
@@ -26,23 +26,28 @@
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-/* headers if any */
+/*
+ * Headers if any.
+ */
+
#include "tclInt.h"
-/* overrides for regguts.h definitions, if any */
-#define FUNCPTR(name, args) (*name) _ANSI_ARGS_(args)
+/*
+ * Overrides for regguts.h definitions, if any.
+ */
+
+#define FUNCPTR(name, args) (*name)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.
+ * 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 */
+/* Ensure certain things don't sneak in from system headers. */
#ifdef __REG_WIDE_T
#undef __REG_WIDE_T
#endif
@@ -67,54 +72,90 @@
#ifdef __REG_NOCHAR
#undef __REG_NOCHAR
#endif
-/* interface types */
+/* 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_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 __REG_NOFRONT /* Don't want regcomp() and regexec() */
+#define __REG_NOCHAR /* Or the char versions */
#define regfree TclReFree
#define regerror TclReError
/* --- end --- */
+/*
+ * Internal character type and related.
+ */
-
-/* internal character type and related */
-typedef 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 */
+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, or NOCELT */
+#define NOCELT (-1) /* Celt value which is not valid chr */
+#define CHR(c) (UCHAR(c)) /* Turn char literal into chr literal */
+#define DIGITVAL(c) ((c)-'0') /* Turn chr digit into its value */
#if TCL_UTF_MAX > 4
-#define CHRBITS 32 /* bits in a chr; must not use sizeof */
-#define CHR_MIN 0x00000000 /* smallest and largest chr; the value */
-#define CHR_MAX 0xffffffff /* CHR_MAX-CHR_MIN+1 should fit in uchr */
+#define CHRBITS 32 /* Bits in a chr; must not use sizeof */
+#define CHR_MIN 0x00000000 /* Smallest and largest chr; the value */
+#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 */
+#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 */
+/*
+ * Functions operating on chr.
+ */
+
#define iscalnum(x) Tcl_UniCharIsAlnum(x)
#define iscalpha(x) Tcl_UniCharIsAlpha(x)
#define iscdigit(x) Tcl_UniCharIsDigit(x)
#define iscspace(x) Tcl_UniCharIsSpace(x)
-/* name the external functions */
+/*
+ * 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 */
+/*
+& 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 */
+/*
+ * Method of allocating a local workspace. We used a thread-specific data
+ * space to store this because the regular expression engine is never
+ * reentered from the same thread; it doesn't make any callbacks.
+ */
+
+#if 1
+#define AllocVars(vPtr) \
+ static Tcl_ThreadDataKey varsKey; \
+ register struct vars *vPtr = (struct vars *) \
+ Tcl_GetThreadData(&varsKey, sizeof(struct vars))
+#else
+/*
+ * This strategy for allocating workspace is "more proper" in some sense, but
+ * quite a bit slower. Using TSD (as above) leads to code that is quite a bit
+ * faster in practice (measured!)
+ */
+#define AllocVars(vPtr) \
+ register struct vars *vPtr = (struct vars *) MALLOC(sizeof(struct vars))
+#define FreeVars(vPtr) \
+ FREE(vPtr)
+#endif
+
+/*
+ * And pick up the standard header.
+ */
+
#include "regex.h"
diff --git a/generic/rege_dfa.c b/generic/rege_dfa.c
index bc391fd..e233680 100644
--- a/generic/rege_dfa.c
+++ b/generic/rege_dfa.c
@@ -3,20 +3,20 @@
* This file is #included by regexec.c.
*
* Copyright (c) 1998, 1999 Henry Spencer. All rights reserved.
- *
+ *
* Development of this software was funded, in part, by Cray Research Inc.,
* UUNET Communications Services Inc., Sun Microsystems Inc., and Scriptics
* Corporation, none of whom are responsible for the results. The author
- * thanks all of them.
- *
+ * thanks all of them.
+ *
* Redistribution and use in source and binary forms -- with or without
* modification -- are permitted for any purpose, provided that
* redistributions in source form retain this entire copyright notice and
* indicate the origin and nature of any modifications.
- *
+ *
* I'd appreciate being given credit for this package in the documentation
* of software which uses it, but that is not a requirement.
- *
+ *
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
@@ -29,521 +29,620 @@
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
-
+
/*
- longest - longest-preferred matching engine
^ static chr *longest(struct vars *, struct dfa *, chr *, chr *, int *);
*/
static chr * /* endpoint, or 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 */
+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 */
{
- chr *cp;
- chr *realstop = (stop == v->stop) ? stop : stop + 1;
- color co;
- struct sset *css;
- struct sset *ss;
- chr *post;
- int i;
- struct colormap *cm = d->cm;
-
- /* initialize */
- css = initialize(v, d, start);
- cp = start;
- if (hitstopp != NULL)
- *hitstopp = 0;
-
- /* startup */
- FDEBUG(("+++ startup +++\n"));
- if (cp == v->start) {
- co = d->cnfa->bos[(v->eflags&REG_NOTBOL) ? 0 : 1];
- FDEBUG(("color %ld\n", (long)co));
- } else {
- co = GETCOLOR(cm, *(cp - 1));
- FDEBUG(("char %c, color %ld\n", (char)*(cp-1), (long)co));
- }
- css = miss(v, d, css, co, cp, start);
- if (css == NULL)
- return NULL;
- css->lastseen = cp;
-
- /* main loop */
- if (v->eflags&REG_FTRACE)
- 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) {
- ss = miss(v, d, css, co, cp+1, start);
- if (ss == NULL)
- break; /* NOTE BREAK OUT */
- }
- cp++;
- ss->lastseen = cp;
- css = ss;
+ chr *cp;
+ chr *realstop = (stop == v->stop) ? stop : stop + 1;
+ color co;
+ struct sset *css;
+ struct sset *ss;
+ chr *post;
+ int i;
+ struct colormap *cm = d->cm;
+
+ /*
+ * Initialize.
+ */
+
+ css = initialize(v, d, start);
+ cp = start;
+ if (hitstopp != NULL) {
+ *hitstopp = 0;
+ }
+
+ /*
+ * Startup.
+ */
+
+ FDEBUG(("+++ startup +++\n"));
+ if (cp == v->start) {
+ co = d->cnfa->bos[(v->eflags&REG_NOTBOL) ? 0 : 1];
+ FDEBUG(("color %ld\n", (long)co));
+ } else {
+ co = GETCOLOR(cm, *(cp - 1));
+ FDEBUG(("char %c, color %ld\n", (char)*(cp-1), (long)co));
+ }
+ css = miss(v, d, css, co, cp, start);
+ if (css == NULL) {
+ return NULL;
+ }
+ css->lastseen = cp;
+
+ /*
+ * Main loop.
+ */
+
+ if (v->eflags&REG_FTRACE) {
+ 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) {
+ ss = miss(v, d, css, co, cp+1, start);
+ if (ss == NULL) {
+ break; /* NOTE BREAK OUT */
}
- else
- while (cp < realstop) {
- co = GETCOLOR(cm, *cp);
- ss = css->outs[co];
- if (ss == NULL) {
- ss = miss(v, d, css, co, cp+1, start);
- if (ss == NULL)
- break; /* NOTE BREAK OUT */
- }
- cp++;
- ss->lastseen = cp;
- css = ss;
+ }
+ cp++;
+ ss->lastseen = cp;
+ css = ss;
+ }
+ } else {
+ while (cp < realstop) {
+ co = GETCOLOR(cm, *cp);
+ ss = css->outs[co];
+ if (ss == NULL) {
+ ss = miss(v, d, css, co, cp+1, start);
+ if (ss == NULL) {
+ break; /* NOTE BREAK OUT */
}
+ }
+ cp++;
+ ss->lastseen = cp;
+ css = ss;
+ }
+ }
- /* shutdown */
- FDEBUG(("+++ shutdown at c%d +++\n", css - d->ssets));
- if (cp == v->stop && stop == v->stop) {
- if (hitstopp != NULL)
- *hitstopp = 1;
- co = d->cnfa->eos[(v->eflags&REG_NOTEOL) ? 0 : 1];
- FDEBUG(("color %ld\n", (long)co));
- ss = miss(v, d, css, co, cp, start);
- /* special case: match ended at eol? */
- if (ss != NULL && (ss->flags&POSTSTATE))
- return cp;
- else if (ss != NULL)
- ss->lastseen = cp; /* to be tidy */
+ /*
+ * Shutdown.
+ */
+
+ FDEBUG(("+++ shutdown at c%d +++\n", css - d->ssets));
+ if (cp == v->stop && stop == v->stop) {
+ if (hitstopp != NULL) {
+ *hitstopp = 1;
+ }
+ co = d->cnfa->eos[(v->eflags&REG_NOTEOL) ? 0 : 1];
+ FDEBUG(("color %ld\n", (long)co));
+ ss = miss(v, d, css, co, cp, start);
+
+ /*
+ * Special case: match ended at eol?
+ */
+
+ if (ss != NULL && (ss->flags&POSTSTATE)) {
+ return cp;
+ } else if (ss != NULL) {
+ ss->lastseen = cp; /* to be tidy */
}
+ }
- /* find last match, if any */
- post = d->lastpost;
- for (ss = d->ssets, i = d->nssused; i > 0; ss++, i--)
- if ((ss->flags&POSTSTATE) && post != ss->lastseen &&
- (post == NULL || post < ss->lastseen))
- post = ss->lastseen;
- if (post != NULL) /* found one */
- return post - 1;
+ /*
+ * Find last match, if any.
+ */
- return NULL;
-}
+ post = d->lastpost;
+ for (ss = d->ssets, i = d->nssused; i > 0; ss++, i--) {
+ if ((ss->flags&POSTSTATE) && (post != ss->lastseen) &&
+ (post == NULL || post < ss->lastseen)) {
+ post = ss->lastseen;
+ }
+ }
+ if (post != NULL) { /* found one */
+ return post - 1;
+ }
+ return NULL;
+}
+
/*
- shortest - shortest-preferred matching engine
^ static chr *shortest(struct vars *, struct dfa *, chr *, chr *, chr *,
^ chr **, int *);
*/
static chr * /* endpoint, or 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 */
+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 */
{
- chr *cp;
- chr *realmin = (min == v->stop) ? min : min + 1;
- chr *realmax = (max == v->stop) ? max : max + 1;
- color co;
- struct sset *css;
- struct sset *ss;
- struct colormap *cm = d->cm;
-
- /* initialize */
- css = initialize(v, d, start);
- cp = start;
- if (hitstopp != NULL)
- *hitstopp = 0;
-
- /* startup */
- FDEBUG(("--- startup ---\n"));
- if (cp == v->start) {
- co = d->cnfa->bos[(v->eflags&REG_NOTBOL) ? 0 : 1];
- FDEBUG(("color %ld\n", (long)co));
- } else {
- co = GETCOLOR(cm, *(cp - 1));
- FDEBUG(("char %c, color %ld\n", (char)*(cp-1), (long)co));
- }
- css = miss(v, d, css, co, cp, start);
- if (css == NULL)
- return NULL;
- css->lastseen = cp;
- ss = css;
-
- /* main loop */
- if (v->eflags&REG_FTRACE)
- 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) {
- ss = miss(v, d, css, co, cp+1, start);
- if (ss == NULL)
- break; /* NOTE BREAK OUT */
- }
- cp++;
- ss->lastseen = cp;
- css = ss;
- if ((ss->flags&POSTSTATE) && cp >= realmin)
- break; /* NOTE BREAK OUT */
+ chr *cp;
+ chr *realmin = (min == v->stop) ? min : min + 1;
+ chr *realmax = (max == v->stop) ? max : max + 1;
+ color co;
+ struct sset *css;
+ struct sset *ss;
+ struct colormap *cm = d->cm;
+
+ /*
+ * Initialize.
+ */
+
+ css = initialize(v, d, start);
+ cp = start;
+ if (hitstopp != NULL) {
+ *hitstopp = 0;
+ }
+
+ /*
+ * Startup.
+ */
+
+ FDEBUG(("--- startup ---\n"));
+ if (cp == v->start) {
+ co = d->cnfa->bos[(v->eflags&REG_NOTBOL) ? 0 : 1];
+ FDEBUG(("color %ld\n", (long)co));
+ } else {
+ co = GETCOLOR(cm, *(cp - 1));
+ FDEBUG(("char %c, color %ld\n", (char)*(cp-1), (long)co));
+ }
+ css = miss(v, d, css, co, cp, start);
+ if (css == NULL) {
+ return NULL;
+ }
+ css->lastseen = cp;
+ ss = css;
+
+ /*
+ * Main loop.
+ */
+
+ if (v->eflags&REG_FTRACE) {
+ 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) {
+ ss = miss(v, d, css, co, cp+1, start);
+ if (ss == NULL) {
+ break; /* NOTE BREAK OUT */
}
- else
- while (cp < realmax) {
- co = GETCOLOR(cm, *cp);
- ss = css->outs[co];
- if (ss == NULL) {
- ss = miss(v, d, css, co, cp+1, start);
- if (ss == NULL)
- break; /* NOTE BREAK OUT */
- }
- cp++;
- ss->lastseen = cp;
- css = ss;
- if ((ss->flags&POSTSTATE) && cp >= realmin)
- break; /* NOTE BREAK OUT */
+ }
+ cp++;
+ ss->lastseen = cp;
+ css = ss;
+ if ((ss->flags&POSTSTATE) && cp >= realmin) {
+ break; /* NOTE BREAK OUT */
+ }
+ }
+ } else {
+ while (cp < realmax) {
+ co = GETCOLOR(cm, *cp);
+ ss = css->outs[co];
+ if (ss == NULL) {
+ ss = miss(v, d, css, co, cp+1, start);
+ if (ss == NULL) {
+ break; /* NOTE BREAK OUT */
}
+ }
+ cp++;
+ ss->lastseen = cp;
+ css = ss;
+ if ((ss->flags&POSTSTATE) && cp >= realmin) {
+ break; /* NOTE BREAK OUT */
+ }
+ }
+ }
- if (ss == NULL)
- return NULL;
-
- if (coldp != NULL) /* report last no-progress state set, if any */
- *coldp = lastcold(v, d);
-
- if ((ss->flags&POSTSTATE) && cp > min) {
- assert(cp >= realmin);
- cp--;
- } else if (cp == v->stop && max == v->stop) {
- co = d->cnfa->eos[(v->eflags&REG_NOTEOL) ? 0 : 1];
- FDEBUG(("color %ld\n", (long)co));
- ss = miss(v, d, css, co, cp, start);
- /* match might have ended at eol */
- if ((ss == NULL || !(ss->flags&POSTSTATE)) && hitstopp != NULL)
- *hitstopp = 1;
+ if (ss == NULL) {
+ return NULL;
+ }
+
+ if (coldp != NULL) { /* report last no-progress state set, if any */
+ *coldp = lastcold(v, d);
+ }
+
+ if ((ss->flags&POSTSTATE) && cp > min) {
+ assert(cp >= realmin);
+ cp--;
+ } else if (cp == v->stop && max == v->stop) {
+ co = d->cnfa->eos[(v->eflags&REG_NOTEOL) ? 0 : 1];
+ FDEBUG(("color %ld\n", (long)co));
+ ss = miss(v, d, css, co, cp, start);
+
+ /*
+ * Match might have ended at eol.
+ */
+
+ if ((ss == NULL || !(ss->flags&POSTSTATE)) && hitstopp != NULL) {
+ *hitstopp = 1;
}
+ }
- if (ss == NULL || !(ss->flags&POSTSTATE))
- return NULL;
+ if (ss == NULL || !(ss->flags&POSTSTATE)) {
+ return NULL;
+ }
- return cp;
+ return cp;
}
-
+
/*
- lastcold - determine last point at which no progress had been made
^ static chr *lastcold(struct vars *, struct dfa *);
*/
static chr * /* endpoint, or NULL */
-lastcold(v, d)
-struct vars *v;
-struct dfa *d;
+lastcold(
+ struct vars *v,
+ struct dfa *d)
{
- struct sset *ss;
- chr *nopr;
- int i;
-
- nopr = d->lastnopr;
- if (nopr == NULL)
- nopr = v->start;
- for (ss = d->ssets, i = d->nssused; i > 0; ss++, i--)
- if ((ss->flags&NOPROGRESS) && nopr < ss->lastseen)
- nopr = ss->lastseen;
- return nopr;
+ struct sset *ss;
+ chr *nopr;
+ int i;
+
+ nopr = d->lastnopr;
+ if (nopr == NULL) {
+ nopr = v->start;
+ }
+ for (ss = d->ssets, i = d->nssused; i > 0; ss++, i--) {
+ if ((ss->flags&NOPROGRESS) && nopr < ss->lastseen) {
+ nopr = ss->lastseen;
+ }
+ }
+ return nopr;
}
-
+
/*
- newdfa - set up a fresh DFA
^ static struct dfa *newdfa(struct vars *, struct cnfa *,
^ struct colormap *, struct smalldfa *);
*/
static struct dfa *
-newdfa(v, cnfa, cm, small)
-struct vars *v;
-struct cnfa *cnfa;
-struct colormap *cm;
-struct smalldfa *small; /* preallocated space, may be NULL */
+newdfa(
+ struct vars *v,
+ struct cnfa *cnfa,
+ struct colormap *cm,
+ struct smalldfa *sml) /* preallocated space, may be NULL */
{
- struct dfa *d;
- size_t nss = cnfa->nstates * 2;
- int wordsper = (cnfa->nstates + UBITS - 1) / UBITS;
- struct smalldfa *smallwas = small;
-
- assert(cnfa != NULL && cnfa->nstates != 0);
-
- if (nss <= FEWSTATES && cnfa->ncolors <= FEWCOLORS) {
- assert(wordsper == 1);
- if (small == NULL) {
- small = (struct smalldfa *)MALLOC(
- sizeof(struct smalldfa));
- if (small == NULL) {
- ERR(REG_ESPACE);
- return NULL;
- }
- }
- d = &small->dfa;
- d->ssets = small->ssets;
- d->statesarea = small->statesarea;
- d->work = &d->statesarea[nss];
- d->outsarea = small->outsarea;
- d->incarea = small->incarea;
- d->cptsmalloced = 0;
- d->mallocarea = (smallwas == NULL) ? (char *)small : NULL;
- } else {
- d = (struct dfa *)MALLOC(sizeof(struct dfa));
- if (d == NULL) {
- ERR(REG_ESPACE);
- return NULL;
- }
- d->ssets = (struct sset *)MALLOC(nss * sizeof(struct sset));
- d->statesarea = (unsigned *)MALLOC((nss+WORK) * wordsper *
- sizeof(unsigned));
- d->work = &d->statesarea[nss * wordsper];
- d->outsarea = (struct sset **)MALLOC(nss * cnfa->ncolors *
- sizeof(struct sset *));
- d->incarea = (struct arcp *)MALLOC(nss * cnfa->ncolors *
- sizeof(struct arcp));
- d->cptsmalloced = 1;
- d->mallocarea = (char *)d;
- if (d->ssets == NULL || d->statesarea == NULL ||
- d->outsarea == NULL || d->incarea == NULL) {
- freedfa(d);
- ERR(REG_ESPACE);
- return NULL;
- }
+ struct dfa *d;
+ size_t nss = cnfa->nstates * 2;
+ int wordsper = (cnfa->nstates + UBITS - 1) / UBITS;
+ struct smalldfa *smallwas = sml;
+
+ assert(cnfa != NULL && cnfa->nstates != 0);
+
+ if (nss <= FEWSTATES && cnfa->ncolors <= FEWCOLORS) {
+ assert(wordsper == 1);
+ if (sml == NULL) {
+ sml = (struct smalldfa *) MALLOC(sizeof(struct smalldfa));
+ if (sml == NULL) {
+ ERR(REG_ESPACE);
+ return NULL;
+ }
}
-
- d->nssets = (v->eflags&REG_SMALL) ? 7 : nss;
- d->nssused = 0;
- d->nstates = cnfa->nstates;
- d->ncolors = cnfa->ncolors;
- d->wordsper = wordsper;
- d->cnfa = cnfa;
- d->cm = cm;
- d->lastpost = NULL;
- d->lastnopr = NULL;
- d->search = d->ssets;
-
- /* initialization of sset fields is done as needed */
-
- return d;
+ d = &sml->dfa;
+ d->ssets = sml->ssets;
+ d->statesarea = sml->statesarea;
+ d->work = &d->statesarea[nss];
+ d->outsarea = sml->outsarea;
+ d->incarea = sml->incarea;
+ d->cptsmalloced = 0;
+ d->mallocarea = (smallwas == NULL) ? (char *)sml : NULL;
+ } else {
+ d = (struct dfa *)MALLOC(sizeof(struct dfa));
+ if (d == NULL) {
+ ERR(REG_ESPACE);
+ return NULL;
+ }
+ d->ssets = (struct sset *)MALLOC(nss * sizeof(struct sset));
+ d->statesarea = (unsigned *)
+ MALLOC((nss+WORK) * wordsper * sizeof(unsigned));
+ d->work = &d->statesarea[nss * wordsper];
+ d->outsarea = (struct sset **)
+ MALLOC(nss * cnfa->ncolors * sizeof(struct sset *));
+ d->incarea = (struct arcp *)
+ MALLOC(nss * cnfa->ncolors * sizeof(struct arcp));
+ d->cptsmalloced = 1;
+ d->mallocarea = (char *)d;
+ if (d->ssets == NULL || d->statesarea == NULL ||
+ d->outsarea == NULL || d->incarea == NULL) {
+ freedfa(d);
+ ERR(REG_ESPACE);
+ return NULL;
+ }
+ }
+
+ d->nssets = (v->eflags&REG_SMALL) ? 7 : nss;
+ d->nssused = 0;
+ d->nstates = cnfa->nstates;
+ d->ncolors = cnfa->ncolors;
+ d->wordsper = wordsper;
+ d->cnfa = cnfa;
+ d->cm = cm;
+ d->lastpost = NULL;
+ d->lastnopr = NULL;
+ d->search = d->ssets;
+
+ /*
+ * Initialization of sset fields is done as needed.
+ */
+
+ return d;
}
-
+
/*
- freedfa - free a DFA
- ^ static VOID freedfa(struct dfa *);
+ ^ static void freedfa(struct dfa *);
*/
-static VOID
-freedfa(d)
-struct dfa *d;
+static void
+freedfa(
+ struct dfa *d)
{
- if (d->cptsmalloced) {
- if (d->ssets != NULL)
- FREE(d->ssets);
- if (d->statesarea != NULL)
- FREE(d->statesarea);
- if (d->outsarea != NULL)
- FREE(d->outsarea);
- if (d->incarea != NULL)
- FREE(d->incarea);
+ if (d->cptsmalloced) {
+ if (d->ssets != NULL) {
+ FREE(d->ssets);
+ }
+ if (d->statesarea != NULL) {
+ FREE(d->statesarea);
+ }
+ if (d->outsarea != NULL) {
+ FREE(d->outsarea);
}
+ if (d->incarea != NULL) {
+ FREE(d->incarea);
+ }
+ }
- if (d->mallocarea != NULL)
- FREE(d->mallocarea);
+ if (d->mallocarea != NULL) {
+ FREE(d->mallocarea);
+ }
}
-
+
/*
- 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(uv, n)
-unsigned *uv;
-int n;
+hash(
+ unsigned *uv,
+ int n)
{
- int i;
- unsigned h;
-
- h = 0;
- for (i = 0; i < n; i++)
- h ^= uv[i];
- return h;
+ int i;
+ unsigned h;
+
+ h = 0;
+ for (i = 0; i < n; i++) {
+ h ^= uv[i];
+ }
+ return h;
}
-
+
/*
- initialize - hand-craft a cache entry for startup, otherwise get ready
^ static struct sset *initialize(struct vars *, struct dfa *, chr *);
*/
static struct sset *
-initialize(v, d, start)
-struct vars *v; /* used only for debug flags */
-struct dfa *d;
-chr *start;
+initialize(
+ struct vars *v, /* used only for debug flags */
+ struct dfa *d,
+ chr *start)
{
- struct sset *ss;
- int i;
-
- /* is previous one still there? */
- if (d->nssused > 0 && (d->ssets[0].flags&STARTER))
- ss = &d->ssets[0];
- else { /* no, must (re)build it */
- ss = getvacant(v, d, start, start);
- for (i = 0; i < d->wordsper; i++)
- ss->states[i] = 0;
- BSET(ss->states, d->cnfa->pre);
- ss->hash = HASH(ss->states, d->wordsper);
- assert(d->cnfa->pre != d->cnfa->post);
- ss->flags = STARTER|LOCKED|NOPROGRESS;
- /* lastseen dealt with below */
+ struct sset *ss;
+ int i;
+
+ /*
+ * Is previous one still there?
+ */
+
+ if (d->nssused > 0 && (d->ssets[0].flags&STARTER)) {
+ ss = &d->ssets[0];
+ } else { /* no, must (re)build it */
+ ss = getvacant(v, d, start, start);
+ for (i = 0; i < d->wordsper; i++) {
+ ss->states[i] = 0;
}
-
- for (i = 0; i < d->nssused; i++)
- d->ssets[i].lastseen = NULL;
- ss->lastseen = start; /* maybe untrue, but harmless */
- d->lastpost = NULL;
- d->lastnopr = NULL;
- return ss;
+ BSET(ss->states, d->cnfa->pre);
+ ss->hash = HASH(ss->states, d->wordsper);
+ assert(d->cnfa->pre != d->cnfa->post);
+ ss->flags = STARTER|LOCKED|NOPROGRESS;
+
+ /*
+ * lastseen dealt with below
+ */
+ }
+
+ for (i = 0; i < d->nssused; i++) {
+ d->ssets[i].lastseen = NULL;
+ }
+ ss->lastseen = start; /* maybe untrue, but harmless */
+ d->lastpost = NULL;
+ d->lastnopr = NULL;
+ return ss;
}
-
+
/*
- 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(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 */
+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 */
{
- struct cnfa *cnfa = d->cnfa;
- int i;
- unsigned h;
- struct carc *ca;
- struct sset *p;
- int ispost;
- int noprogress;
- int gotstate;
- int dolacons;
- int sawlacons;
-
- /* for convenience, we can be called even if it might not be a miss */
- if (css->outs[co] != NULL) {
- FDEBUG(("hit\n"));
- return css->outs[co];
- }
- FDEBUG(("miss\n"));
-
- /* first, what set of states would we end up in? */
- for (i = 0; i < d->wordsper; i++)
- d->work[i] = 0;
- ispost = 0;
- noprogress = 1;
- gotstate = 0;
- 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) {
- BSET(d->work, ca->to);
- gotstate = 1;
- if (ca->to == cnfa->post)
- ispost = 1;
- if (!cnfa->states[ca->to]->co)
- noprogress = 0;
- FDEBUG(("%d -> %d\n", i, ca->to));
- }
- dolacons = (gotstate) ? (cnfa->flags&HASLACONS) : 0;
- sawlacons = 0;
- 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++) {
- if (ca->co <= cnfa->ncolors)
- continue; /* NOTE CONTINUE */
- sawlacons = 1;
- if (ISBSET(d->work, ca->to))
- continue; /* NOTE CONTINUE */
- if (!lacon(v, cnfa, cp, ca->co))
- continue; /* NOTE CONTINUE */
- BSET(d->work, ca->to);
- dolacons = 1;
- if (ca->to == cnfa->post)
- ispost = 1;
- if (!cnfa->states[ca->to]->co)
- noprogress = 0;
- FDEBUG(("%d :> %d\n", i, ca->to));
- }
+ struct cnfa *cnfa = d->cnfa;
+ int i;
+ unsigned h;
+ struct carc *ca;
+ struct sset *p;
+ int ispost;
+ int noprogress;
+ int gotstate;
+ int dolacons;
+ int sawlacons;
+
+ /*
+ * For convenience, we can be called even if it might not be a miss.
+ */
+
+ if (css->outs[co] != NULL) {
+ FDEBUG(("hit\n"));
+ return css->outs[co];
+ }
+ FDEBUG(("miss\n"));
+
+ /*
+ * First, what set of states would we end up in?
+ */
+
+ for (i = 0; i < d->wordsper; i++) {
+ d->work[i] = 0;
+ }
+ ispost = 0;
+ noprogress = 1;
+ gotstate = 0;
+ 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) {
+ BSET(d->work, ca->to);
+ gotstate = 1;
+ if (ca->to == cnfa->post) {
+ ispost = 1;
+ }
+ if (!cnfa->states[ca->to]->co) {
+ noprogress = 0;
+ }
+ FDEBUG(("%d -> %d\n", i, ca->to));
+ }
+ }
}
- if (!gotstate)
- return NULL;
- h = HASH(d->work, d->wordsper);
-
- /* 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)) {
- FDEBUG(("cached c%d\n", p - d->ssets));
- break; /* NOTE BREAK OUT */
+ }
+ dolacons = (gotstate) ? (cnfa->flags&HASLACONS) : 0;
+ sawlacons = 0;
+ 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++) {
+ if (ca->co <= cnfa->ncolors) {
+ continue; /* NOTE CONTINUE */
+ }
+ sawlacons = 1;
+ if (ISBSET(d->work, ca->to)) {
+ continue; /* NOTE CONTINUE */
+ }
+ if (!lacon(v, cnfa, cp, ca->co)) {
+ continue; /* NOTE CONTINUE */
+ }
+ BSET(d->work, ca->to);
+ dolacons = 1;
+ if (ca->to == cnfa->post) {
+ ispost = 1;
+ }
+ if (!cnfa->states[ca->to]->co) {
+ noprogress = 0;
+ }
+ FDEBUG(("%d :> %d\n", i, ca->to));
}
- 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++)
- p->states[i] = d->work[i];
- p->hash = h;
- p->flags = (ispost) ? POSTSTATE : 0;
- if (noprogress)
- p->flags |= NOPROGRESS;
- /* lastseen to be dealt with by caller */
+ }
}
-
- 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;
- p->ins.ss = css;
- p->ins.co = (color)co;
+ }
+ if (!gotstate) {
+ return NULL;
+ }
+ h = HASH(d->work, d->wordsper);
+
+ /*
+ * 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)) {
+ FDEBUG(("cached c%d\n", p - d->ssets));
+ break; /* NOTE BREAK OUT */
+ }
+ }
+ 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++) {
+ p->states[i] = d->work[i];
+ }
+ p->hash = h;
+ p->flags = (ispost) ? POSTSTATE : 0;
+ if (noprogress) {
+ p->flags |= NOPROGRESS;
}
- return p;
-}
+ /*
+ * lastseen to be dealt with by caller
+ */
+ }
+
+ 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;
+ p->ins.ss = css;
+ p->ins.co = (color)co;
+ }
+ return p;
+}
+
/*
- lacon - lookahead-constraint checker for miss()
^ static int lacon(struct vars *, struct cnfa *, chr *, pcolor);
*/
static int /* predicate: constraint satisfied? */
-lacon(v, pcnfa, cp, co)
-struct vars *v;
-struct cnfa *pcnfa; /* parent cnfa */
-chr *cp;
-pcolor co; /* "color" of the lookahead constraint */
+lacon(
+ struct vars *v,
+ struct cnfa *pcnfa, /* parent cnfa */
+ chr *cp,
+ pcolor co) /* "color" of the lookahead constraint */
{
- int n;
- struct subre *sub;
- struct dfa *d;
- struct smalldfa sd;
- chr *end;
-
- n = co - pcnfa->ncolors;
- assert(n < v->g->nlacons && v->g->lacons != NULL);
- FDEBUG(("=== testing lacon %d\n", n));
- sub = &v->g->lacons[n];
- d = newdfa(v, &sub->cnfa, &v->g->cmap, &sd);
- if (d == NULL) {
- ERR(REG_ESPACE);
- return 0;
- }
- end = longest(v, d, cp, v->stop, (int *)NULL);
- freedfa(d);
- FDEBUG(("=== lacon %d match %d\n", n, (end != NULL)));
- return (sub->subno) ? (end != NULL) : (end == NULL);
+ int n;
+ struct subre *sub;
+ struct dfa *d;
+ struct smalldfa sd;
+ chr *end;
+
+ n = co - pcnfa->ncolors;
+ assert(n < v->g->nlacons && v->g->lacons != NULL);
+ FDEBUG(("=== testing lacon %d\n", n));
+ sub = &v->g->lacons[n];
+ d = newdfa(v, &sub->cnfa, &v->g->cmap, &sd);
+ if (d == NULL) {
+ ERR(REG_ESPACE);
+ return 0;
+ }
+ end = longest(v, d, cp, v->stop, (int *)NULL);
+ freedfa(d);
+ FDEBUG(("=== lacon %d match %d\n", n, (end != NULL)));
+ return (sub->subno) ? (end != NULL) : (end == NULL);
}
-
+
/*
- getvacant - get a vacant state set
* This routine clears out the inarcs and outarcs, but does not otherwise
@@ -551,127 +650,167 @@ pcolor co; /* "color" of the lookahead constraint */
^ static struct sset *getvacant(struct vars *, struct dfa *, chr *, chr *);
*/
static struct sset *
-getvacant(v, d, cp, start)
-struct vars *v; /* used only for debug flags */
-struct dfa *d;
-chr *cp;
-chr *start;
+getvacant(
+ struct vars *v, /* used only for debug flags */
+ struct dfa *d,
+ chr *cp,
+ chr *start)
{
- int i;
- struct sset *ss;
- struct sset *p;
- struct arcp ap;
- struct arcp lastap = {NULL, 0}; /* silence gcc 4 warning */
- color co;
-
- ss = pickss(v, d, cp, start);
- assert(!(ss->flags&LOCKED));
-
- /* clear out its inarcs, including self-referential ones */
- ap = ss->ins;
- 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;
- ap = p->inchain[co];
- p->inchain[co].ss = NULL; /* paranoia */
+ int i;
+ struct sset *ss;
+ struct sset *p;
+ struct arcp ap;
+ struct arcp lastap = {NULL, 0}; /* silence gcc 4 warning */
+ color co;
+
+ ss = pickss(v, d, cp, start);
+ assert(!(ss->flags&LOCKED));
+
+ /*
+ * Clear out its inarcs, including self-referential ones.
+ */
+
+ ap = ss->ins;
+ 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;
+ ap = p->inchain[co];
+ p->inchain[co].ss = NULL; /* paranoia */
+ }
+ ss->ins.ss = NULL;
+
+ /*
+ * Take it off the inarc chains of the ssets reached by its outarcs.
+ */
+
+ for (i = 0; i < d->ncolors; i++) {
+ p = ss->outs[i];
+ assert(p != ss); /* not self-referential */
+ if (p == NULL) {
+ continue; /* NOTE CONTINUE */
}
- ss->ins.ss = NULL;
-
- /* take it off the inarc chains of the ssets reached by its outarcs */
- for (i = 0; i < d->ncolors; i++) {
- p = ss->outs[i];
- assert(p != ss); /* not self-referential */
- if (p == NULL)
- continue; /* NOTE CONTINUE */
- 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 {
- assert(p->ins.ss != NULL);
- for (ap = p->ins; ap.ss != NULL &&
- !(ap.ss == ss && ap.co == i);
- ap = ap.ss->inchain[ap.co])
- lastap = ap;
- assert(ap.ss != NULL);
- lastap.ss->inchain[lastap.co] = ss->inchain[i];
- }
- ss->outs[i] = NULL;
- ss->inchain[i].ss = NULL;
+ 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 {
+ assert(p->ins.ss != NULL);
+ for (ap = p->ins; ap.ss != NULL &&
+ !(ap.ss == ss && ap.co == i);
+ ap = ap.ss->inchain[ap.co]) {
+ lastap = ap;
+ }
+ assert(ap.ss != NULL);
+ lastap.ss->inchain[lastap.co] = ss->inchain[i];
}
+ ss->outs[i] = NULL;
+ ss->inchain[i].ss = NULL;
+ }
- /* if ss was a success state, may need to remember location */
- if ((ss->flags&POSTSTATE) && ss->lastseen != d->lastpost &&
- (d->lastpost == NULL || d->lastpost < ss->lastseen))
- d->lastpost = ss->lastseen;
+ /*
+ * If ss was a success state, may need to remember location.
+ */
- /* likewise for a no-progress state */
- if ((ss->flags&NOPROGRESS) && ss->lastseen != d->lastnopr &&
- (d->lastnopr == NULL || d->lastnopr < ss->lastseen))
- d->lastnopr = ss->lastseen;
+ if ((ss->flags&POSTSTATE) && ss->lastseen != d->lastpost &&
+ (d->lastpost == NULL || d->lastpost < ss->lastseen)) {
+ d->lastpost = ss->lastseen;
+ }
- return ss;
-}
+ /*
+ * Likewise for a no-progress state.
+ */
+ if ((ss->flags&NOPROGRESS) && ss->lastseen != d->lastnopr &&
+ (d->lastnopr == NULL || d->lastnopr < ss->lastseen)) {
+ d->lastnopr = ss->lastseen;
+ }
+
+ return ss;
+}
+
/*
- pickss - pick the next stateset to be used
^ static struct sset *pickss(struct vars *, struct dfa *, chr *, chr *);
*/
static struct sset *
-pickss(v, d, cp, start)
-struct vars *v; /* used only for debug flags */
-struct dfa *d;
-chr *cp;
-chr *start;
+pickss(
+ struct vars *v, /* used only for debug flags */
+ struct dfa *d,
+ chr *cp,
+ chr *start)
{
- int i;
- struct sset *ss;
- struct sset *end;
- chr *ancient;
-
- /* shortcut for cases where cache isn't full */
- if (d->nssused < d->nssets) {
- i = d->nssused;
- d->nssused++;
- ss = &d->ssets[i];
- FDEBUG(("new c%d\n", i));
- /* set up innards */
- ss->states = &d->statesarea[i * d->wordsper];
- ss->flags = 0;
- ss->ins.ss = NULL;
- 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++) {
- ss->outs[i] = NULL;
- ss->inchain[i].ss = NULL;
- }
- return ss;
+ int i;
+ struct sset *ss;
+ struct sset *end;
+ chr *ancient;
+
+ /*
+ * Shortcut for cases where cache isn't full.
+ */
+
+ if (d->nssused < d->nssets) {
+ i = d->nssused;
+ d->nssused++;
+ ss = &d->ssets[i];
+ FDEBUG(("new c%d\n", i));
+
+ /*
+ * Set up innards.
+ */
+
+ ss->states = &d->statesarea[i * d->wordsper];
+ ss->flags = 0;
+ ss->ins.ss = NULL;
+ 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++) {
+ ss->outs[i] = NULL;
+ ss->inchain[i].ss = NULL;
+ }
+ return ss;
+ }
+
+ /*
+ * Look for oldest, or old enough anyway.
+ */
+
+ if (cp - start > d->nssets*2/3) { /* oldest 33% are expendable */
+ ancient = cp - d->nssets*2/3;
+ } else {
+ ancient = start;
+ }
+ for (ss = d->search, end = &d->ssets[d->nssets]; ss < end; ss++) {
+ if ((ss->lastseen == NULL || ss->lastseen < ancient)
+ && !(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)) {
+ d->search = ss + 1;
+ FDEBUG(("replacing c%d\n", ss - d->ssets));
+ return ss;
+ }
+ }
- /* look for oldest, or old enough anyway */
- if (cp - start > d->nssets*2/3) /* oldest 33% are expendable */
- ancient = cp - d->nssets*2/3;
- else
- ancient = start;
- for (ss = d->search, end = &d->ssets[d->nssets]; ss < end; ss++)
- if ((ss->lastseen == NULL || ss->lastseen < ancient) &&
- !(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)) {
- d->search = ss + 1;
- FDEBUG(("replacing c%d\n", ss - d->ssets));
- return ss;
- }
+ /*
+ * Nobody's old enough?!? -- something's really wrong.
+ */
- /* nobody's old enough?!? -- something's really wrong */
- FDEBUG(("can't find victim to replace!\n"));
- assert(NOTREACHED);
- ERR(REG_ASSERT);
- return d->ssets;
+ FDEBUG(("can't find victim to replace!\n"));
+ assert(NOTREACHED);
+ ERR(REG_ASSERT);
+ return d->ssets;
}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/regerror.c b/generic/regerror.c
index 6376e80..a1a0163 100644
--- a/generic/regerror.c
+++ b/generic/regerror.c
@@ -2,20 +2,20 @@
* regerror - error-code expansion
*
* Copyright (c) 1998, 1999 Henry Spencer. All rights reserved.
- *
+ *
* Development of this software was funded, in part, by Cray Research Inc.,
* UUNET Communications Services Inc., Sun Microsystems Inc., and Scriptics
* Corporation, none of whom are responsible for the results. The author
- * thanks all of them.
- *
+ * thanks all of them.
+ *
* Redistribution and use in source and binary forms -- with or without
* modification -- are permitted for any purpose, provided that
* redistributions in source form retain this entire copyright notice and
* indicate the origin and nature of any modifications.
- *
- * I'd appreciate being given credit for this package in the documentation
- * of software which uses it, but that is not a requirement.
- *
+ *
+ * I'd appreciate being given credit for this package in the documentation of
+ * software which uses it, but that is not a requirement.
+ *
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
@@ -31,79 +31,99 @@
#include "regguts.h"
-/* unknown-error explanation */
-static CONST char unk[] = "*** unknown regex error code 0x%x ***";
+/*
+ * Unknown-error explanation.
+ */
+
+static const char unk[] = "*** unknown regex error code 0x%x ***";
+
+/*
+ * Struct to map among codes, code names, and explanations.
+ */
-/* struct to map among codes, code names, and explanations */
static struct rerr {
- int code;
- char *name;
- char *explain;
+ int code;
+ const char *name;
+ const char *explain;
} rerrs[] = {
- /* the actual table is built from regex.h */
-# include "regerrs.h"
- { -1, "", "oops" }, /* explanation special-cased in code */
+ /* The actual table is built from regex.h */
+#include "regerrs.h"
+ { -1, "", "oops" }, /* explanation special-cased in code */
};
-
+
/*
- regerror - the interface to error numbers
*/
/* ARGSUSED */
-size_t /* actual space needed (including NUL) */
-regerror(code, preg, errbuf, errbuf_size)
-int code; /* 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 */
+size_t /* Actual space needed (including NUL) */
+regerror(
+ int code, /* 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;
- char convbuf[sizeof(unk)+50]; /* 50 = plenty for int */
- size_t len;
- int icode;
+ struct rerr *r;
+ const char *msg;
+ char convbuf[sizeof(unk)+50]; /* 50 = plenty for int */
+ size_t len;
+ int icode;
- switch (code) {
- case REG_ATOI: /* convert name to number */
- for (r = rerrs; r->code >= 0; r++)
- if (strcmp(r->name, errbuf) == 0)
- break;
- sprintf(convbuf, "%d", r->code); /* -1 for unknown */
- msg = convbuf;
+ switch (code) {
+ case REG_ATOI: /* Convert name to number */
+ for (r = rerrs; r->code >= 0; r++) {
+ if (strcmp(r->name, errbuf) == 0) {
break;
- case REG_ITOA: /* convert number to name */
- icode = atoi(errbuf); /* not our problem if this fails */
- for (r = rerrs; r->code >= 0; r++)
- if (r->code == icode)
- break;
- if (r->code >= 0)
- msg = r->name;
- else { /* unknown; tell him the number */
- sprintf(convbuf, "REG_%u", (unsigned)icode);
- msg = convbuf;
- }
+ }
+ }
+ sprintf(convbuf, "%d", r->code); /* -1 for unknown */
+ msg = convbuf;
+ break;
+ case REG_ITOA: /* Convert number to name */
+ icode = atoi(errbuf); /* Not our problem if this fails */
+ for (r = rerrs; r->code >= 0; r++) {
+ if (r->code == icode) {
break;
- default: /* a real, normal error code */
- for (r = rerrs; r->code >= 0; r++)
- if (r->code == code)
- break;
- if (r->code >= 0)
- msg = r->explain;
- else { /* unknown; say so */
- sprintf(convbuf, unk, code);
- msg = convbuf;
- }
+ }
+ }
+ if (r->code >= 0) {
+ msg = r->name;
+ } else { /* Unknown; tell him the number */
+ sprintf(convbuf, "REG_%u", (unsigned)icode);
+ msg = convbuf;
+ }
+ break;
+ default: /* A real, normal error code */
+ for (r = rerrs; r->code >= 0; r++) {
+ if (r->code == code) {
break;
+ }
+ }
+ if (r->code >= 0) {
+ msg = r->explain;
+ } else { /* Unknown; say so */
+ sprintf(convbuf, unk, code);
+ msg = convbuf;
}
+ break;
+ }
- len = strlen(msg) + 1; /* space needed, including NUL */
- if (errbuf_size > 0) {
- if (errbuf_size > len)
- strcpy(errbuf, msg);
- else { /* truncate to fit */
- strncpy(errbuf, msg, errbuf_size-1);
- errbuf[errbuf_size-1] = '\0';
- }
+ len = strlen(msg) + 1; /* Space needed, including NUL */
+ if (errbuf_size > 0) {
+ if (errbuf_size > len) {
+ strcpy(errbuf, msg);
+ } else { /* Truncate to fit */
+ strncpy(errbuf, msg, errbuf_size-1);
+ errbuf[errbuf_size-1] = '\0';
}
+ }
- return len;
+ return len;
}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/regex.h b/generic/regex.h
index a35925a..fa86092 100644
--- a/generic/regex.h
+++ b/generic/regex.h
@@ -4,20 +4,20 @@
* regular expressions
*
* Copyright (c) 1998, 1999 Henry Spencer. All rights reserved.
- *
+ *
* Development of this software was funded, in part, by Cray Research Inc.,
* UUNET Communications Services Inc., Sun Microsystems Inc., and Scriptics
- * Corporation, none of whom are responsible for the results. The author
- * thanks all of them.
- *
+ * Corporation, none of whom are responsible for the results. The author
+ * thanks all of them.
+ *
* Redistribution and use in source and binary forms -- with or without
* modification -- are permitted for any purpose, provided that
* redistributions in source form retain this entire copyright notice and
* indicate the origin and nature of any modifications.
*
- * I'd appreciate being given credit for this package in the documentation
- * of software which uses it, but that is not a requirement.
- *
+ * I'd appreciate being given credit for this package in the documentation of
+ * software which uses it, but that is not a requirement.
+ *
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
@@ -30,38 +30,35 @@
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
- *
* Prototypes etc. marked with "^" within comments get gathered up (and
- * possibly edited) by the regfwd program and inserted near the bottom of
- * this file.
+ * 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:
+ * 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.
+ * 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.
+ * 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.
*/
-
-
/*
* voodoo for C++
*/
@@ -69,18 +66,15 @@
extern "C" {
#endif
-
-
/*
* 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).
+ * 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
@@ -121,15 +115,14 @@ extern "C" {
#define regerror TclReError
/* --- end --- */
-
/*
* interface types etc.
*/
/*
- * 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, so we
- * offer <sys/types.h> an override.
+ * 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, so we offer
+ * <sys/types.h> an override.
*/
#ifdef __REG_REGOFF_T
typedef __REG_REGOFF_T regoff_t;
@@ -148,8 +141,8 @@ 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'.
+ * 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
@@ -163,43 +156,41 @@ typedef void re_void;
/* the biggie, a compiled RE (or rather, a front end to same) */
typedef struct {
- int re_magic; /* magic number */
- size_t re_nsub; /* number of subexpressions */
- long re_info; /* information about RE */
-# define REG_UBACKREF 000001
-# define REG_ULOOKAHEAD 000002
-# define REG_UBOUNDS 000004
-# define REG_UBRACES 000010
-# define REG_UBSALNUM 000020
-# define REG_UPBOTCH 000040
-# define REG_UBBS 000100
-# define REG_UNONPOSIX 000200
-# define REG_UUNSPEC 000400
-# define REG_UUNPORT 001000
-# define REG_ULOCALE 002000
-# define REG_UEMPTYMATCH 004000
-# define REG_UIMPOSSIBLE 010000
-# define REG_USHORTEST 020000
- int re_csize; /* sizeof(character) */
- char *re_endp; /* backward compatibility kludge */
- /* the rest is opaque pointers to hidden innards */
- char *re_guts; /* `char *' is more portable than `void *' */
- char *re_fns;
+ int re_magic; /* magic number */
+ size_t re_nsub; /* number of subexpressions */
+ long re_info; /* information about RE */
+#define REG_UBACKREF 000001
+#define REG_ULOOKAHEAD 000002
+#define REG_UBOUNDS 000004
+#define REG_UBRACES 000010
+#define REG_UBSALNUM 000020
+#define REG_UPBOTCH 000040
+#define REG_UBBS 000100
+#define REG_UNONPOSIX 000200
+#define REG_UUNSPEC 000400
+#define REG_UUNPORT 001000
+#define REG_ULOCALE 002000
+#define REG_UEMPTYMATCH 004000
+#define REG_UIMPOSSIBLE 010000
+#define REG_USHORTEST 020000
+ int re_csize; /* sizeof(character) */
+ char *re_endp; /* backward compatibility kludge */
+ /* the rest is opaque pointers to hidden innards */
+ char *re_guts; /* `char *' is more portable than `void *' */
+ char *re_fns;
} regex_t;
/* result reporting (may acquire more fields later) */
typedef struct {
- regoff_t rm_so; /* start of substring */
- regoff_t rm_eo; /* end of substring */
+ regoff_t rm_so; /* start of substring */
+ regoff_t rm_eo; /* end of substring */
} regmatch_t;
/* supplementary control and reporting */
typedef struct {
- regmatch_t rm_extend; /* see REG_EXPECT */
+ regmatch_t rm_extend; /* see REG_EXPECT */
} rm_detail_t;
-
-
/*
* compilation
^ #ifndef __REG_NOCHAR
@@ -231,8 +222,6 @@ typedef struct {
#define REG_FAKE 010000 /* none of your business :-) */
#define REG_PROGRESS 020000 /* none of your business :-) */
-
-
/*
* execution
^ #ifndef __REG_NOCHAR
@@ -254,23 +243,19 @@ typedef struct {
#define REG_MTRACE 0020 /* none of your business */
#define REG_SMALL 0040 /* none of your business */
-
-
/*
* misc generics (may be more functions here eventually)
^ re_void regfree(regex_t *);
*/
-
-
/*
* error reporting
* 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.
+ * 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);
*/
@@ -297,8 +282,6 @@ typedef struct {
#define REG_ATOI 101 /* convert error-code name to number */
#define REG_ITOA 102 /* convert error-code number to name */
-
-
/*
* the prototypes, as possibly munched by regfwd
*/
@@ -306,30 +289,28 @@ typedef struct {
/* 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));
+int re_comp(regex_t *, __REG_CONST char *, size_t, int);
#endif
#ifndef __REG_NOFRONT
-int regcomp _ANSI_ARGS_((regex_t *, __REG_CONST char *, int));
+int regcomp(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));
+MODULE_SCOPE int __REG_WIDE_COMPILE(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));
+int re_exec(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));
+int regexec(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));
+MODULE_SCOPE int __REG_WIDE_EXEC(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));
+MODULE_SCOPE re_void regfree(regex_t *);
+MODULE_SCOPE size_t regerror(int, __REG_CONST regex_t *, char *, size_t);
/* automatically gathered by fwd; do not hand-edit */
/* =====^!^===== end forwards =====^!^===== */
-
-
/*
* more C++ voodoo
*/
@@ -337,6 +318,4 @@ extern size_t regerror _ANSI_ARGS_((int, __REG_CONST regex_t *, char *, size_t))
}
#endif
-
-
#endif
diff --git a/generic/regexec.c b/generic/regexec.c
index be459d3..c902209 100644
--- a/generic/regexec.c
+++ b/generic/regexec.c