* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
* This code is derived from software contributed to Berkeley by
* Jim R. Oldroyd at The Instruction Set and Keith Gabryelski at
* Commodore Business Machines.
* %sccs.include.redist.c%
static char sccsid
[] = "@(#)rxp.c 8.1 (Berkeley) %G%";
* regular expression parser
* external functions and return values are:
* FALSE parse failure; error message will be in char rxperr[]
* {...} optional pattern, equialent to [...|]
* [...] pattern delimiters
* TRUE string s matches compiled pattern
* FALSE match failure or regexp error
* char * reverse-engineered regular expression string
#define LIT (-1) /* literal character, char */
#define SOT (-2) /* start text anchor, - */
#define EOT (-3) /* end text anchor, - */
#define GRP_S (-4) /* start alternate grp, ptr_to_end */
#define GRP_E (-5) /* end group, - */
#define ALT_S (-6) /* alternate starts, ptr_to_next */
#define ALT_E (-7) /* alternate ends, - */
#define END (-8) /* end of regexp, - */
typedef short Rxp_t
; /* type for regexp tokens */
static Rxp_t rxpbuf
[RXP_LINE_SZ
]; /* compiled regular expression buffer */
char rxperr
[128]; /* parser error message */
static int rxp__compile
__P((char *, int));
static char *rxp__expand
__P((int));
static int rxp__match
__P((char *, int, Rxp_t
*, Rxp_t
*, char *));
return (rxp__compile(s
, TRUE
));
*rp
++ = SOT
; /* auto-anchor: pat is really ^pat$ */
*rp
++ = GRP_S
; /* auto-group: ^pat$ is really ^[pat]$ */
if (rp
- rxpbuf
>= RXP_LINE_SZ
- 4) {
(void)snprintf(rxperr
, sizeof(rxperr
),
"regular expression too long %s", s
);
if ((err
= rxp__compile(s
, FALSE
)) != TRUE
)
(void)snprintf(rxperr
, sizeof(rxperr
),
"unmatched alternator in regexp %s",
(void)snprintf(rxperr
, sizeof(rxperr
),
"unmatched alternator in regexp %s", s
);
*(rxpbuf
+ 2) = rp
- rxpbuf
;
* match string against compiled regular expression
return (rxp__match(s
, TRUE
, NULL
, NULL
, NULL
));
rxp__match(s
, first
, j_succ
, j_fail
, sp_fail
)
Rxp_t
*j_succ
; /* jump here on successful alt match */
Rxp_t
*j_fail
; /* jump here on failed match */
char *sp_fail
; /* reset sp to here on failed match */
while (rp
< rxpbuf
+ RXP_LINE_SZ
&& *rp
!= END
)
ch
= isascii(*rp
) && isupper(*rp
) ? tolower(*rp
) : *rp
;
grp_end
= rxpbuf
+ *rp
++;
if ((err
= rxp__match(sp
,
FALSE
, grp_end
, rxpbuf
+ *rp
++, sp
)) != TRUE
)
return (*rp
!= END
? FALSE
: TRUE
);
* Reverse engineer the regular expression, by picking first of all alternates.
return (rxp__expand(TRUE
));
static char buf
[RXP_LINE_SZ
/2];
while (rp
< rxpbuf
+ RXP_LINE_SZ
&& *rp
!= END
)
if ((err
= rxp__expand(FALSE
)) == NULL
)