]> git.michaelhowe.org Git - packages/o/openafs.git/commitdiff
Use Posix regex(3) within src/bucoord/commands.c
authorHans-Werner Paulsen <hans@MPA-Garching.MPG.DE>
Mon, 20 Jul 2009 10:06:23 +0000 (12:06 +0200)
committerRuss Allbery <rra@stanford.edu>
Wed, 22 Jul 2009 17:18:00 +0000 (10:18 -0700)
Normally pattern matching against volume names is done on the server, but
if this fails, the client (src/bucoord/commands.c) is doing this.
This program had no code to use regex(3) when HAVE_POSIX_REGEX is defined.
This patch adds calls to regex(3) if HAVE_POSIX_REGEX is defined.
For systems without POSIX regex there were two (slightly different)
implementations in src/bucoord/regex.c and src/util/regex.c. The newer
version src/bucoord/regex.c has been modified and moved to src/util/regex.c.
Some header files and Makefiles have been removed/updated to work with this
setup.

Reviewed-on: http://gerrit.openafs.org/http://gerrit.openafs.org/99
Tested-by: Russ Allbery <rra@stanford.edu>
Reviewed-by: Russ Allbery <rra@stanford.edu>
Tested-by: Jeffrey Altman <jaltman@openafs.org>
Reviewed-by: Jeffrey Altman <jaltman@openafs.org>
Tested-by: Derrick Brashear <shadow@dementia.org>
Reviewed-by: Derrick Brashear <shadow@dementia.org>
src/bucoord/Makefile.in
src/bucoord/NTMakefile
src/bucoord/commands.c
src/bucoord/regex.c [deleted file]
src/bucoord/regex.h [deleted file]
src/util/afsutil.h
src/util/regex.c

index 1700606c1841471312e72f0c8f27f5fec932e09c..58561eead738b93a5ccb6a62a57d4a879005b382 100644 (file)
@@ -48,12 +48,12 @@ btest: btest.o ${TOP_LIBDIR}/libbubasics.a ${TOP_LIBDIR}/librx.a ${TOP_LIBDIR}/l
 
 btest.o: AFS_component_version_number.c
 
-BACKSRCS = main.c config.c dsstub.c volstub.c commands.c regex.c server.c \
+BACKSRCS = main.c config.c dsstub.c volstub.c commands.c server.c \
        dsvs.c dump.c restore.c ubik_db_if.c                              \
        dump_sched.c vol_sets.c tape_hosts.c                              \
        bc_status.c status.c dlq.c
 
-BACKOBJS = main.o config.o dsstub.o volstub.o commands.o regex.o server.o \
+BACKOBJS = main.o config.o dsstub.o volstub.o commands.o server.o \
        dsvs.o dump.o restore.o ubik_db_if.o dump_sched.o vol_sets.o    \
        tape_hosts.o bucoord_errs.o bc_status.o status.o dlq.o
 
index 82b86213a5c9b5beab5511cc3d9ac58b89a92419..bf5d49fe42b1b30c222c368e3a61d80bc3bf18c7 100644 (file)
@@ -47,7 +47,6 @@ EXEOBJS =\
        $(OUT)\dsstub.obj \
        $(OUT)\volstub.obj \
        $(OUT)\commands.obj \
-       $(OUT)\regex.obj \
        $(OUT)\server.obj \
        $(OUT)\dsvs.obj \
        $(OUT)\dump.obj \
index fc8ecb8819ae944b0b0146ec5556fe2e51d2cbb1..c97a350b4561f2dd9fdf96d1c57a7d4974e42009 100644 (file)
@@ -16,9 +16,6 @@
 #define _REGEX_RE_COMP
 #endif
 #include <sys/types.h>
-#if defined(AFS_LINUX24_ENV)
-#include <regex.h>
-#endif
 #include <afs/cmd.h>
 #ifdef AFS_NT40_ENV
 #include <winsock2.h>
@@ -29,6 +26,7 @@
 #endif
 #include <errno.h>
 #include <afs/com_err.h>
+#include <afs/afsutil.h>
 #include <afs/budb.h>
 #include <afs/butc.h>
 #include <afs/bubasics.h>      /* PA */
 #include <afs/tcdata.h>
 #include <afs/butx.h>
 #include <afs/vsutils_prototypes.h>
+#ifdef HAVE_POSIX_REGEX                /* use POSIX regexp library */
+#include <regex.h>
+#endif
 #include "bc.h"
 #include "error_macros.h"
 #include "bucoord_internal.h"
 #include "bucoord_prototypes.h"
-#include "regex.h"
 
 extern struct bc_config *bc_globalConfig;
 extern struct bc_dumpTask bc_dumpTasks[BC_MAXSIMDUMPS];
@@ -440,6 +440,10 @@ EvalVolumeSet1(struct bc_config *aconfig,
     int foundentry = 0;
     struct serversort *servers = 0, *ss = 0;
     struct partitionsort *ps = 0;
+#ifdef HAVE_POSIX_REGEX
+    regex_t re;
+    int need_regfree = 0;
+#endif
 
     *avols = (struct bc_volumeDump *)0;
     ctve = (struct bc_volumeEntry *)0; /* no compiled entry */
@@ -486,6 +490,13 @@ EvalVolumeSet1(struct bc_config *aconfig,
                /* If the volume entry is not compiled, then compile it */
                if (ctve != tve) {
                    sprintf(patt, "^%s$", tve->name);
+#ifdef HAVE_POSIX_REGEX
+                   if (regcomp(&re, patt, REG_NOSUB) != 0) {
+                     afs_com_err(whoami, 0, "Can't compile regular expression '%s'", patt);
+                     return (-1);
+                   }
+                   need_regfree = 1;
+#else
                    errm = (char *)re_comp(patt);
                    if (errm) {
                        afs_com_err(whoami, 0,
@@ -493,6 +504,7 @@ EvalVolumeSet1(struct bc_config *aconfig,
                                patt, errm);
                        return (-1);
                    }
+#endif
                    ctve = tve;
                }
 
@@ -502,8 +514,13 @@ EvalVolumeSet1(struct bc_config *aconfig,
                if (entry.serverFlags[srvpartpair] & ITSRWVOL) {
                    if (entry.flags & RW_EXISTS) {
                        sprintf(patt, "%s", entry.name);
+#ifdef HAVE_POSIX_REGEX
+                       code = regexec(&re, patt, 0, NULL, 0);
+                       if (code == 0) {
+#else
                        code = re_exec(patt);
                        if (code == 1) {
+#endif
                            found = 1;
                            foundentry = srvpartpair;
                            volType = RWVOL;
@@ -516,8 +533,13 @@ EvalVolumeSet1(struct bc_config *aconfig,
                     */
                    if (entry.flags & BACK_EXISTS) {
                        sprintf(patt, "%s.backup", entry.name);
+#ifdef HAVE_POSIX_REGEX
+                       code = regexec(&re, patt, 0, NULL, 0);
+                       if (code == 0) {
+#else
                        code = re_exec(patt);
                        if (code == 1) {
+#endif
                            found = 1;
                            foundentry = srvpartpair;
                            volType = BACKVOL;
@@ -533,8 +555,13 @@ EvalVolumeSet1(struct bc_config *aconfig,
                else if (!found && (entry.serverFlags[srvpartpair] & ITSROVOL)
                         && (entry.flags & RO_EXISTS)) {
                    sprintf(patt, "%s.readonly", entry.name);
+#ifdef HAVE_POSIX_REGEX
+                   code = regexec(&re, patt, 0, NULL, 0);
+                   if (code == 0) {
+#else
                    code = re_exec(patt);
                    if (code == 1) {
+#endif
                        found = 1;
                        foundentry = srvpartpair;
                        volType = ROVOL;
@@ -596,6 +623,10 @@ EvalVolumeSet1(struct bc_config *aconfig,
            }                   /*f */
        }                       /*ve */
     }                          /*w */
+#ifdef HAVE_POSIX_REGEX
+    if (need_regfree)
+       regfree(&re);
+#endif
 
     /* Randomly link the volumedump entries together */
     randSPEntries(servers, avols);
diff --git a/src/bucoord/regex.c b/src/bucoord/regex.c
deleted file mode 100644 (file)
index 25dd094..0000000
+++ /dev/null
@@ -1,395 +0,0 @@
-/*
- * Copyright 2000, International Business Machines Corporation and others.
- * All Rights Reserved.
- * 
- * This software has been released under the terms of the IBM Public
- * License.  For details, see the LICENSE file in the top-level source
- * directory or online at http://www.openafs.org/dl/license10.html
- */
-
-/*
- * routines to do regular expression matching
- *
- * Entry points:
- *
- *     re_comp(s)
- *             char *s;
- *      ... returns 0 if the string s was compiled successfully,
- *                  a pointer to an error message otherwise.
- *          If passed 0 or a null string returns without changing
- *           the currently compiled re (see note 11 below).
- *
- *     re_exec(s)
- *             char *s;
- *      ... returns 1 if the string s matches the last compiled regular
- *                    expression, 
- *                  0 if the string s failed to match the last compiled
- *                    regular expression, and
- *                 -1 if the compiled regular expression was invalid 
- *                    (indicating an internal error).
- *
- * The strings passed to both re_comp and re_exec may have trailing or
- * embedded newline characters; they are terminated by nulls.
- *
- * The identity of the author of these routines is lost in antiquity;
- * this is essentially the same as the re code in the original V6 ed.
- *
- * The regular expressions recognized are described below. This description
- * is essentially the same as that for ed.
- *
- *     A regular expression specifies a set of strings of characters.
- *     A member of this set of strings is said to be matched by
- *     the regular expression.  In the following specification for
- *     regular expressions the word `character' means any character but NUL.
- *
- *     1.  Any character except a special character matches itself.
- *         Special characters are the regular expression delimiter plus
- *         \ [ . and sometimes ^ * $.
- *     2.  A . matches any character.
- *     3.  A \ followed by any character except a digit or ( )
- *         matches that character.
- *     4.  A nonempty string s bracketed [s] (or [^s]) matches any
- *         character in (or not in) s. In s, \ has no special meaning,
- *         and ] may only appear as the first letter. A substring 
- *         a-b, with a and b in ascending ASCII order, stands for
- *         the inclusive range of ASCII characters.
- *     5.  A regular expression of form 1-4 followed by * matches a
- *         sequence of 0 or more matches of the regular expression.
- *     6.  A regular expression, x, of form 1-8, bracketed \(x\)
- *         matches what x matches.
- *     7.  A \ followed by a digit n matches a copy of the string that the
- *         bracketed regular expression beginning with the nth \( matched.
- *     8.  A regular expression of form 1-8, x, followed by a regular
- *         expression of form 1-7, y matches a match for x followed by
- *         a match for y, with the x match being as long as possible
- *         while still permitting a y match.
- *     9.  A regular expression of form 1-8 preceded by ^ (or followed
- *         by $), is constrained to matches that begin at the left
- *         (or end at the right) end of a line.
- *     10. A regular expression of form 1-9 picks out the longest among
- *         the leftmost matches in a line.
- *     11. An empty regular expression stands for a copy of the last
- *         regular expression encountered.
- */
-
-#include "regex.h"
-
-/*
- * constants for re's
- */
-#define        CBRA    1
-#define        CCHR    2
-#define        CDOT    4
-#define        CCL     6
-#define        NCCL    8
-#define        CDOL    10
-#define        CEOF    11
-#define        CKET    12
-#define        CBACK   18
-
-#define        CSTAR   01
-
-#define        ESIZE   512
-#define        NBRA    9
-
-static char expbuf[ESIZE], *braslist[NBRA], *braelist[NBRA];
-static char circf;
-
-static int advance(char *, char *);
-static int backref(int i, char *);
-static int cclass(char *, char, int);
-
-/*
- * compile the regular expression argument into a dfa
- */
-char *
-re_comp(const char *sp)
-{
-    register int c;
-    register char *ep = expbuf;
-    int cclcnt, numbra = 0;
-    char *lastep = 0;
-    char bracket[NBRA];
-    char *bracketp = &bracket[0];
-    static char *retoolong = "Regular expression too long";
-
-#define        comerr(msg) {expbuf[0] = 0; numbra = 0; return(msg); }
-
-    if (sp == 0 || *sp == '\0') {
-       if (*ep == 0)
-           return ("No previous regular expression");
-       return (0);
-    }
-    if (*sp == '^') {
-       circf = 1;
-       sp++;
-    } else
-       circf = 0;
-    for (;;) {
-       if (ep >= &expbuf[ESIZE])
-           comerr(retoolong);
-       if ((c = *sp++) == '\0') {
-           if (bracketp != bracket)
-               comerr("unmatched \\(");
-           *ep++ = CEOF;
-           *ep++ = 0;
-           return (0);
-       }
-       if (c != '*')
-           lastep = ep;
-       switch (c) {
-
-       case '.':
-           *ep++ = CDOT;
-           continue;
-
-       case '*':
-           if (lastep == 0 || *lastep == CBRA || *lastep == CKET)
-               goto defchar;
-           *lastep |= CSTAR;
-           continue;
-
-       case '$':
-           if (*sp != '\0')
-               goto defchar;
-           *ep++ = CDOL;
-           continue;
-
-       case '[':
-           *ep++ = CCL;
-           *ep++ = 0;
-           cclcnt = 1;
-           if ((c = *sp++) == '^') {
-               c = *sp++;
-               ep[-2] = NCCL;
-           }
-           do {
-               if (c == '\0')
-                   comerr("missing ]");
-               if (c == '-' && ep[-1] != 0) {
-                   if ((c = *sp++) == ']') {
-                       *ep++ = '-';
-                       cclcnt++;
-                       break;
-                   }
-                   while (ep[-1] < c) {
-                       *ep = ep[-1] + 1;
-                       ep++;
-                       cclcnt++;
-                       if (ep >= &expbuf[ESIZE])
-                           comerr(retoolong);
-                   }
-               }
-               *ep++ = c;
-               cclcnt++;
-               if (ep >= &expbuf[ESIZE])
-                   comerr(retoolong);
-           } while ((c = *sp++) != ']');
-           lastep[1] = cclcnt;
-           continue;
-
-       case '\\':
-           if ((c = *sp++) == '(') {
-               if (numbra >= NBRA)
-                   comerr("too many \\(\\) pairs");
-               *bracketp++ = numbra;
-               *ep++ = CBRA;
-               *ep++ = numbra++;
-               continue;
-           }
-           if (c == ')') {
-               if (bracketp <= bracket)
-                   comerr("unmatched \\)");
-               *ep++ = CKET;
-               *ep++ = *--bracketp;
-               continue;
-           }
-           if (c >= '1' && c < ('1' + NBRA)) {
-               *ep++ = CBACK;
-               *ep++ = c - '1';
-               continue;
-           }
-           *ep++ = CCHR;
-           *ep++ = c;
-           continue;
-
-         defchar:
-       default:
-           *ep++ = CCHR;
-           *ep++ = c;
-       }
-    }
-}
-
-static int
-cclass(char *set, char c, int af)
-{
-    register int n;
-
-    if (c == 0)
-       return (0);
-    n = *set++;
-    while (--n)
-       if (*set++ == c)
-           return (af);
-    return (!af);
-}
-
-static int
-backref(int i, char *lp)
-{
-    register char *bp;
-
-    bp = braslist[i];
-    while (*bp++ == *lp++)
-       if (bp >= braelist[i])
-           return (1);
-    return (0);
-}
-
-/* 
- * try to match the next thing in the dfa
- */
-static int
-advance(char *lp, char *ep)
-{
-    register char *curlp;
-    int ct, i;
-    int rv;
-
-    for (;;)
-       switch (*ep++) {
-
-       case CCHR:
-           if (*ep++ == *lp++)
-               continue;
-           return (0);
-
-       case CDOT:
-           if (*lp++)
-               continue;
-           return (0);
-
-       case CDOL:
-           if (*lp == '\0')
-               continue;
-           return (0);
-
-       case CEOF:
-           return (1);
-
-       case CCL:
-           if (cclass(ep, *lp++, 1)) {
-               ep += *ep;
-               continue;
-           }
-           return (0);
-
-       case NCCL:
-           if (cclass(ep, *lp++, 0)) {
-               ep += *ep;
-               continue;
-           }
-           return (0);
-
-       case CBRA:
-           braslist[(int) *ep++] = lp;
-           continue;
-
-       case CKET:
-           braelist[(int) *ep++] = lp;
-           continue;
-
-       case CBACK:
-           if (braelist[i = *ep++] == 0)
-               return (-1);
-           if (backref(i, lp)) {
-               lp += braelist[i] - braslist[i];
-               continue;
-           }
-           return (0);
-
-       case CBACK | CSTAR:
-           if (braelist[i = *ep++] == 0)
-               return (-1);
-           curlp = lp;
-           ct = braelist[i] - braslist[i];
-           while (backref(i, lp))
-               lp += ct;
-           while (lp >= curlp) {
-               if ((rv = advance(lp, ep)))
-                   return (rv);
-               lp -= ct;
-           }
-           continue;
-
-       case CDOT | CSTAR:
-           curlp = lp;
-           while (*lp++);
-           goto star;
-
-       case CCHR | CSTAR:
-           curlp = lp;
-           while (*lp++ == *ep);
-           ep++;
-           goto star;
-
-       case CCL | CSTAR:
-       case NCCL | CSTAR:
-           curlp = lp;
-           while (cclass(ep, *lp++, ep[-1] == (CCL | CSTAR)));
-           ep += *ep;
-           goto star;
-
-         star:
-           do {
-               lp--;
-               if ((rv = advance(lp, ep)))
-                   return (rv);
-           } while (lp > curlp);
-           return (0);
-
-       default:
-           return (-1);
-       }
-}
-
-/* 
- * match the argument string against the compiled re
- */
-int
-re_exec(const char *p1)
-{
-    register char *p2 = expbuf;
-    register int c;
-    int rv;
-
-    for (c = 0; c < NBRA; c++) {
-       braslist[c] = 0;
-       braelist[c] = 0;
-    }
-    if (circf)
-       return ((advance(p1, p2)));
-    /*
-     * fast check for first character
-     */
-    if (*p2 == CCHR) {
-       c = p2[1];
-       do {
-           if (*p1 != c)
-               continue;
-           if ((rv = advance(p1, p2)))
-               return (rv);
-       } while (*p1++);
-       return (0);
-    }
-    /*
-     * regular algorithm
-     */
-    do
-       if ((rv = advance(p1, p2)))
-           return (rv);
-    while (*p1++);
-    return (0);
-}
-
diff --git a/src/bucoord/regex.h b/src/bucoord/regex.h
deleted file mode 100644 (file)
index 8fb6b0f..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-/* Copyright 2000, International Business Machines Corporation and others.
- * All Rights Reserved.
- * 
- * This software has been released under the terms of the IBM Public
- * License.  For details, see the LICENSE file in the top-level source
- * directory or online at http://www.openafs.org/dl/license10.html
- */
-
-#ifndef _BUCOORD_REGEX_H
-#define _BUCOORD_REGEX_H
-/* regex.c */
-extern char *re_comp(const char *sp);
-extern int re_exec(const char *p1);
-#endif
index e4dfead7640bf6ed1394ec06c647e119c9331d56..bf4db4e14dc23026f2ee73429d93a79f88a8ad8a 100644 (file)
@@ -121,14 +121,15 @@ extern char *vctime(const time_t * atime);
 /* Unbuffer output when Un*x would do line buffering. */
 #define setlinebuf(S) setvbuf(S, NULL, _IONBF, 0)
 
-/* regular expression parser for NT */
-     extern char *re_comp(char *sp);
-     extern int rc_exec(char *p);
-
 /* Abort on error, possibly trapping to debugger or dumping a trace. */
      void afs_NTAbort(void);
 #endif /* AFS_NT40_ENV */
 
+#ifndef HAVE_POSIX_REGEX
+extern char *re_comp(const char *sp);
+extern int re_exec(const char *p1);
+#endif
+
      typedef char b32_string_t[8];
 /* b64_string_t is 8 bytes, in stds.h */
      typedef char lb64_string_t[12];
index 45999b21bd727d1450413689133458220b2087ff..1c20f960a274dc0aae2ec40047c025396ef26fd9 100644 (file)
@@ -7,15 +7,6 @@
  * directory or online at http://www.openafs.org/dl/license10.html
  */
 
-/*
- * regex.c -- regular expression patter matching functions
- * 
- */
-
-#include <afsconfig.h>
-#include <afs/param.h>
-
-
 /*
  * routines to do regular expression matching
  *
@@ -81,6 +72,9 @@
  *         regular expression encountered.
  */
 
+#include <afsconfig.h>
+#include <afs/param.h>
+
 /*
  * constants for re's
  */
 static char expbuf[ESIZE], *braslist[NBRA], *braelist[NBRA];
 static char circf;
 
-/* forward defs
-*/
-
-static int advance(register char *lp, register char *ep);
-static int backref(register int i, register char *lp);
-static int cclass(register char *set, register char c, int af);
-
+static int advance(char *, char *);
+static int backref(int i, char *);
+static int cclass(char *, char, int);
 
 /*
  * compile the regular expression argument into a dfa
  */
 char *
-re_comp(register char *sp)
+re_comp(const char *sp)
 {
     register int c;
     register char *ep = expbuf;
@@ -124,7 +114,7 @@ re_comp(register char *sp)
     char *bracketp = &bracket[0];
     static char *retoolong = "Regular expression too long";
 
-#define        comperr(msg) {expbuf[0] = 0; numbra = 0; return(msg); }
+#define        comerr(msg) {expbuf[0] = 0; numbra = 0; return(msg); }
 
     if (sp == 0 || *sp == '\0') {
        if (*ep == 0)
@@ -138,10 +128,10 @@ re_comp(register char *sp)
        circf = 0;
     for (;;) {
        if (ep >= &expbuf[ESIZE - 10 /* fudge factor */])
-           comperr(retoolong);
+           comerr(retoolong);
        if ((c = *sp++) == '\0') {
            if (bracketp != bracket)
-               comperr("unmatched \\(");
+               comerr("unmatched \\(");
            *ep++ = CEOF;
            *ep++ = 0;
            return (0);
@@ -176,7 +166,7 @@ re_comp(register char *sp)
            }
            do {
                if (c == '\0')
-                   comperr("missing ]");
+                   comerr("missing ]");
                if (c == '-' && ep[-1] != 0) {
                    if ((c = *sp++) == ']') {
                        *ep++ = '-';
@@ -188,13 +178,13 @@ re_comp(register char *sp)
                        ep++;
                        cclcnt++;
                        if (ep >= &expbuf[ESIZE - 10 /* fudge factor */])
-                           comperr(retoolong);
+                           comerr(retoolong);
                    }
                }
                *ep++ = c;
                cclcnt++;
                if (ep >= &expbuf[ESIZE - 10 /* fudge factor */])
-                   comperr(retoolong);
+                   comerr(retoolong);
            } while ((c = *sp++) != ']');
            lastep[1] = cclcnt;
            continue;
@@ -202,7 +192,7 @@ re_comp(register char *sp)
        case '\\':
            if ((c = *sp++) == '(') {
                if (numbra >= NBRA)
-                   comperr("too many \\(\\) pairs");
+                   comerr("too many \\(\\) pairs");
                *bracketp++ = numbra;
                *ep++ = CBRA;
                *ep++ = numbra++;
@@ -210,7 +200,7 @@ re_comp(register char *sp)
            }
            if (c == ')') {
                if (bracketp <= bracket)
-                   comperr("unmatched \\)");
+                   comerr("unmatched \\)");
                *ep++ = CKET;
                *ep++ = *--bracketp;
                continue;
@@ -232,42 +222,29 @@ re_comp(register char *sp)
     }
 }
 
-/* 
- * match the argument string against the compiled re
- */
-int
-re_exec(register char *p1)
+static int
+cclass(char *set, char c, int af)
 {
-    register char *p2 = expbuf;
-    register int c;
-    int rv;
+    register int n;
 
-    for (c = 0; c < NBRA; c++) {
-       braslist[c] = 0;
-       braelist[c] = 0;
-    }
-    if (circf)
-       return ((advance(p1, p2)));
-    /*
-     * fast check for first character
-     */
-    if (*p2 == CCHR) {
-       c = p2[1];
-       do {
-           if (*p1 != c)
-               continue;
-           if ((rv = advance(p1, p2)))
-               return (rv);
-       } while (*p1++);
+    if (c == 0)
        return (0);
-    }
-    /*
-     * regular algorithm
-     */
-    do
-       if ((rv = advance(p1, p2)))
-           return (rv);
-    while (*p1++);
+    n = *set++;
+    while (--n)
+       if (*set++ == c)
+           return (af);
+    return (!af);
+}
+
+static int
+backref(int i, char *lp)
+{
+    register char *bp;
+
+    bp = braslist[i];
+    while (*bp++ == *lp++)
+       if (bp >= braelist[i])
+           return (1);
     return (0);
 }
 
@@ -275,7 +252,7 @@ re_exec(register char *p1)
  * try to match the next thing in the dfa
  */
 static int
-advance(register char *lp, register char *ep)
+advance(char *lp, char *ep)
 {
     register char *curlp;
     int ct, i;
@@ -317,11 +294,11 @@ advance(register char *lp, register char *ep)
            return (0);
 
        case CBRA:
-           braslist[*ep++] = lp;
+           braslist[(int) *ep++] = lp;
            continue;
 
        case CKET:
-           braelist[*ep++] = lp;
+           braelist[(int) *ep++] = lp;
            continue;
 
        case CBACK:
@@ -337,7 +314,7 @@ advance(register char *lp, register char *ep)
            if (braelist[i = *ep++] == 0)
                return (-1);
            curlp = lp;
-           ct = (int)(braelist[i] - braslist[i]);
+           ct = braelist[i] - braslist[i];
            while (backref(i, lp))
                lp += ct;
            while (lp >= curlp) {
@@ -378,28 +355,42 @@ advance(register char *lp, register char *ep)
        }
 }
 
-static int
-backref(register int i, register char *lp)
+/*
+ * match the argument string against the compiled re
+ */
+int
+re_exec(const char *p1)
 {
-    register char *bp;
+    register char *p2 = expbuf;
+    register int c;
+    int rv;
 
-    bp = braslist[i];
-    while (*bp++ == *lp++)
-       if (bp >= braelist[i])
-           return (1);
+    for (c = 0; c < NBRA; c++) {
+       braslist[c] = 0;
+       braelist[c] = 0;
+    }
+    if (circf)
+       return ((advance(p1, p2)));
+    /*
+     * fast check for first character
+     */
+    if (*p2 == CCHR) {
+       c = p2[1];
+       do {
+           if (*p1 != c)
+               continue;
+           if ((rv = advance(p1, p2)))
+               return (rv);
+       } while (*p1++);
+       return (0);
+    }
+    /*
+     * regular algorithm
+     */
+    do
+       if ((rv = advance(p1, p2)))
+           return (rv);
+    while (*p1++);
     return (0);
 }
 
-static int
-cclass(register char *set, register char c, int af)
-{
-    register int n;
-
-    if (c == 0)
-       return (0);
-    n = *set++;
-    while (--n)
-       if (*set++ == c)
-           return (af);
-    return (!af);
-}