Blame | Last modification | View Log | RSS feed
/*
* Simple Regular Expression functions. Derived from Unix 7th Edition,
* /usr/src/cmd/expr.y
*
* Modified by Gunnar Ritter, Freiburg i. Br., Germany, February 2002.
*
* Copyright(C) Caldera International Inc. 2001-2002. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* Redistributions of source code and documentation must retain the
* above copyright notice, this list of conditions and the following
* disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed or owned by Caldera
* International, Inc.
* Neither the name of Caldera International, Inc. nor the names of
* other contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA
* INTERNATIONAL, INC. AND CONTRIBUTORS ``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 CALDERA INTERNATIONAL, INC. 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; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* 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.
*/
#if __GNUC__ >= 3 && __GNUC_MINOR__ >= 4
#define REGEXP_H_USED __attribute__ ((used))
#elif defined __GNUC__
#define REGEXP_H_USED __attribute__ ((unused))
#else
#define REGEXP_H_USED
#endif
static const char regexp_h_sccsid[] REGEXP_H_USED =
"@(#)regexp.sl 1.54 (gritter) 2/19/05";
#if !defined (REGEXP_H_USED_FROM_VI) && !defined (__dietlibc__)
#define REGEXP_H_WCHARS
#endif
#define CBRA 2
#define CCHR 4
#define CDOT 8
#define CCL 12
/* CLNUM 14 used in sed */
/* CEND 16 used in sed */
#define CDOL 20
#define CCEOF 22
#define CKET 24
#define CBACK 36
#define CNCL 40
#define CBRC 44
#define CLET 48
#define CCH1 52
#define CCH2 56
#define CCH3 60
#define STAR 01
#define RNGE 03
#define REGEXP_H_LEAST 0100
#ifdef REGEXP_H_WCHARS
#define CMB 0200
#else /* !REGEXP_H_WCHARS */
#define CMB 0
#endif /* !REGEXP_H_WCHARS */
#define NBRA 9
#define PLACE(c) ep[c >> 3] |= bittab[c & 07]
#define ISTHERE(c) (ep[c >> 3] & bittab[c & 07])
#ifdef REGEXP_H_WCHARS
#define REGEXP_H_IS_THERE(ep, c) ((ep)[c >> 3] & bittab[c & 07])
#endif
#include <ctype.h>
#include <string.h>
#include <limits.h>
#ifdef REGEXP_H_WCHARS
#include <stdlib.h>
#include <wchar.h>
#include <wctype.h>
#endif /* REGEXP_H_WCHARS */
#define regexp_h_uletter(c) (isalpha(c) || (c) == '_')
#ifdef REGEXP_H_WCHARS
#define regexp_h_wuletter(c) (iswalpha(c) || (c) == L'_')
/*
* Used to allocate memory for the multibyte star algorithm.
*/
#ifndef regexp_h_malloc
#define regexp_h_malloc(n) malloc(n)
#endif
#ifndef regexp_h_free
#define regexp_h_free(p) free(p)
#endif
/*
* Can be predefined to 'inline' to inline some multibyte functions;
* may improve performance for files that contain many multibyte
* sequences.
*/
#ifndef regexp_h_inline
#define regexp_h_inline
#endif
/*
* Mask to determine whether the first byte of a sequence possibly
* starts a multibyte character. Set to 0377 to force mbtowc() for
* any byte sequence (except 0).
*/
#ifndef REGEXP_H_MASK
#define REGEXP_H_MASK 0200
#endif
#endif /* REGEXP_H_WCHARS */
/*
* For regexpr.h.
*/
#ifndef regexp_h_static
#define regexp_h_static
#endif
#ifndef REGEXP_H_STEP_INIT
#define REGEXP_H_STEP_INIT
#endif
#ifndef REGEXP_H_ADVANCE_INIT
#define REGEXP_H_ADVANCE_INIT
#endif
char *braslist[NBRA];
char *braelist[NBRA];
int nbra;
char *loc1, *loc2, *locs;
int sed;
int nodelim;
regexp_h_static int circf;
regexp_h_static int low;
regexp_h_static int size;
regexp_h_static unsigned char bittab[] = {
1,
2,
4,
8,
16,
32,
64,
128
};
static int regexp_h_advance(register const char *lp,
register const char *ep);
static void regexp_h_getrnge(register const char *str, int least);
static const char *regexp_h_bol; /* beginning of input line (for \<) */
#ifdef REGEXP_H_WCHARS
static int regexp_h_wchars;
static int regexp_h_mbcurmax;
static const char *regexp_h_firstwc; /* location of first
multibyte character
on input line */
#define regexp_h_getwc(c) { \
if (regexp_h_wchars) { \
char mbbuf[MB_LEN_MAX + 1], *mbptr; \
wchar_t wcbuf; \
int mb, len; \
mbptr = mbbuf; \
do { \
mb = GETC(); \
*mbptr++ = mb; \
*mbptr = '\0'; \
} while ((len = mbtowc(&wcbuf, mbbuf, regexp_h_mbcurmax)) < 0 \
&& mb != eof && mbptr < mbbuf + MB_LEN_MAX); \
if (len == -1) \
ERROR(67); \
c = wcbuf; \
} else { \
c = GETC(); \
} \
}
#define regexp_h_store(wc, mb, me) { \
int len; \
if (wc == WEOF) \
ERROR(67); \
if ((len = me - mb) <= regexp_h_mbcurmax) { \
char mt[MB_LEN_MAX]; \
if (wctomb(mt, wc) >= len) \
ERROR(50); \
} \
switch (len = wctomb(mb, wc)) { \
case -1: \
ERROR(67); \
case 0: \
mb++; \
break; \
default: \
mb += len; \
} \
}
static regexp_h_inline wint_t
regexp_h_fetchwc(const char **mb, int islp)
{
wchar_t wc;
int len;
if ((len = mbtowc(&wc, *mb, regexp_h_mbcurmax)) < 0) {
(*mb)++;
return WEOF;
}
if (islp && regexp_h_firstwc == NULL)
regexp_h_firstwc = *mb;
/*if (len == 0) {
(*mb)++;
return L'\0';
} handled in singlebyte code */
*mb += len;
return wc;
}
#define regexp_h_fetch(mb, islp) ((*(mb) & REGEXP_H_MASK) == 0 ? \
(*(mb)++&0377): \
regexp_h_fetchwc(&(mb), islp))
static regexp_h_inline wint_t
regexp_h_showwc(const char *mb)
{
wchar_t wc;
if (mbtowc(&wc, mb, regexp_h_mbcurmax) < 0)
return WEOF;
return wc;
}
#define regexp_h_show(mb) ((*(mb) & REGEXP_H_MASK) == 0 ? (*(mb)&0377): \
regexp_h_showwc(mb))
/*
* Return the character immediately preceding mb. Since no byte is
* required to be the first byte of a character, the longest multibyte
* character ending at &[mb-1] is searched.
*/
static regexp_h_inline wint_t
regexp_h_previous(const char *mb)
{
const char *p = mb;
wchar_t wc, lastwc = WEOF;
int len, max = 0;
if (regexp_h_firstwc == NULL || mb <= regexp_h_firstwc)
return (mb > regexp_h_bol ? (mb[-1] & 0377) : WEOF);
while (p-- > regexp_h_bol) {
mbtowc(NULL, NULL, 0);
if ((len = mbtowc(&wc, p, mb - p)) >= 0) {
if (len < max || len < mb - p)
break;
max = len;
lastwc = wc;
} else if (len < 0 && max > 0)
break;
}
return lastwc;
}
#define regexp_h_cclass(set, c, af) \
((c) == 0 || (c) == WEOF ? 0 : ( \
((c) > 0177) ? \
regexp_h_cclass_wc(set, c, af) : ( \
REGEXP_H_IS_THERE((set)+1, (c)) ? (af) : !(af) \
) \
) \
)
static regexp_h_inline int
regexp_h_cclass_wc(const char *set, register wint_t c, int af)
{
register wint_t wc, wl = WEOF;
const char *end;
end = &set[18] + set[0] - 1;
set += 17;
while (set < end) {
wc = regexp_h_fetch(set, 0);
#ifdef REGEXP_H_VI_BACKSLASH
if (wc == '\\' && set < end &&
(*set == ']' || *set == '-' ||
*set == '^' || *set == '\\')) {
wc = regexp_h_fetch(set, 0);
} else
#endif /* REGEXP_H_VI_BACKSLASH */
if (wc == '-' && wl != WEOF && set < end) {
wc = regexp_h_fetch(set, 0);
#ifdef REGEXP_H_VI_BACKSLASH
if (wc == '\\' && set < end &&
(*set == ']' || *set == '-' ||
*set == '^' || *set == '\\')) {
wc = regexp_h_fetch(set, 0);
}
#endif /* REGEXP_H_VI_BACKSLASH */
if (c > wl && c < wc)
return af;
}
if (c == wc)
return af;
wl = wc;
}
return !af;
}
#else /* !REGEXP_H_WCHARS */
#define regexp_h_wchars 0
#define regexp_h_getwc(c) { c = GETC(); }
#endif /* !REGEXP_H_WCHARS */
regexp_h_static char *
compile(char *instring, char *ep, const char *endbuf, int seof)
{
INIT /* Dependent declarations and initializations */
register int c;
register int eof = seof;
char *lastep = instring;
int cclcnt;
char bracket[NBRA], *bracketp;
int closed;
char neg;
int lc;
int i, cflg;
#ifdef REGEXP_H_WCHARS
char *eq;
regexp_h_mbcurmax = MB_CUR_MAX;
regexp_h_wchars = regexp_h_mbcurmax > 1 ? CMB : 0;
#endif
lastep = 0;
bracketp = bracket;
if((c = GETC()) == eof || c == '\n') {
if (c == '\n') {
UNGETC(c);
nodelim = 1;
}
if(*ep == 0 && !sed)
ERROR(41);
if (bracketp > bracket)
ERROR(42);
RETURN(ep);
}
circf = closed = nbra = 0;
if (c == '^')
circf++;
else
UNGETC(c);
for (;;) {
if (ep >= endbuf)
ERROR(50);
regexp_h_getwc(c);
if(c != '*' && ((c != '\\') || (PEEKC() != '{')))
lastep = ep;
if (c == eof) {
*ep++ = CCEOF;
if (bracketp > bracket)
ERROR(42);
RETURN(ep);
}
switch (c) {
case '.':
*ep++ = CDOT|regexp_h_wchars;
continue;
case '\n':
if (sed == 0) {
UNGETC(c);
*ep++ = CCEOF;
nodelim = 1;
RETURN(ep);
}
ERROR(36);
case '*':
if (lastep==0 || *lastep==CBRA || *lastep==CKET ||
*lastep==(CBRC|regexp_h_wchars) ||
*lastep==(CLET|regexp_h_wchars))
goto defchar;
*lastep |= STAR;
continue;
case '$':
if(PEEKC() != eof)
goto defchar;
*ep++ = CDOL;
continue;
case '[':
#ifdef REGEXP_H_WCHARS
if (regexp_h_wchars == 0) {
#endif
if(&ep[33] >= endbuf)
ERROR(50);
*ep++ = CCL;
lc = 0;
for(i = 0; i < 32; i++)
ep[i] = 0;
neg = 0;
if((c = GETC()) == '^') {
neg = 1;
c = GETC();
}
do {
c &= 0377;
if(c == '\0' || c == '\n')
ERROR(49);
#ifdef REGEXP_H_VI_BACKSLASH
if(c == '\\' && ((c = PEEKC()) == ']' ||
c == '-' || c == '^' ||
c == '\\')) {
c = GETC();
c &= 0377;
} else
#endif /* REGEXP_H_VI_BACKSLASH */
if(c == '-' && lc != 0) {
if ((c = GETC()) == ']') {
PLACE('-');
break;
}
#ifdef REGEXP_H_VI_BACKSLASH
if(c == '\\' &&
((c = PEEKC()) == ']' ||
c == '-' ||
c == '^' ||
c == '\\'))
c = GETC();
#endif /* REGEXP_H_VI_BACKSLASH */
c &= 0377;
while(lc < c) {
PLACE(lc);
lc++;
}
}
lc = c;
PLACE(c);
} while((c = GETC()) != ']');
if(neg) {
for(cclcnt = 0; cclcnt < 32; cclcnt++)
ep[cclcnt] ^= 0377;
ep[0] &= 0376;
}
ep += 32;
#ifdef REGEXP_H_WCHARS
} else {
if (&ep[18] >= endbuf)
ERROR(50);
*ep++ = CCL|CMB;
*ep++ = 0;
lc = 0;
for (i = 0; i < 16; i++)
ep[i] = 0;
eq = &ep[16];
regexp_h_getwc(c);
if (c == L'^') {
regexp_h_getwc(c);
ep[-2] = CNCL|CMB;
}
do {
if (c == '\0' || c == '\n')
ERROR(49);
#ifdef REGEXP_H_VI_BACKSLASH
if(c == '\\' && ((c = PEEKC()) == ']' ||
c == '-' || c == '^' ||
c == '\\')) {
regexp_h_store(c, eq, endbuf);
regexp_h_getwc(c);
} else
#endif /* REGEXP_H_VI_BACKSLASH */
if (c == '-' && lc != 0 && lc <= 0177) {
regexp_h_store(c, eq, endbuf);
regexp_h_getwc(c);
if (c == ']') {
PLACE('-');
break;
}
#ifdef REGEXP_H_VI_BACKSLASH
if(c == '\\' &&
((c = PEEKC()) == ']' ||
c == '-' ||
c == '^' ||
c == '\\')) {
regexp_h_store(c, eq,
endbuf);
regexp_h_getwc(c);
}
#endif /* REGEXP_H_VI_BACKSLASH */
while (lc < (c & 0177)) {
PLACE(lc);
lc++;
}
}
lc = c;
if (c <= 0177)
PLACE(c);
regexp_h_store(c, eq, endbuf);
regexp_h_getwc(c);
} while (c != L']');
if ((i = eq - &ep[16]) > 255)
ERROR(50);
lastep[1] = i;
ep = eq;
}
#endif /* REGEXP_H_WCHARS */
continue;
case '\\':
regexp_h_getwc(c);
switch(c) {
case '(':
if(nbra >= NBRA)
ERROR(43);
*bracketp++ = nbra;
*ep++ = CBRA;
*ep++ = nbra++;
continue;
case ')':
if(bracketp <= bracket)
ERROR(42);
*ep++ = CKET;
*ep++ = *--bracketp;
closed++;
continue;
case '<':
*ep++ = CBRC|regexp_h_wchars;
continue;
case '>':
*ep++ = CLET|regexp_h_wchars;
continue;
case '{':
if(lastep == (char *) (0))
goto defchar;
*lastep |= RNGE;
cflg = 0;
nlim:
c = GETC();
i = 0;
do {
if ('0' <= c && c <= '9')
i = 10 * i + c - '0';
else
ERROR(16);
} while(((c = GETC()) != '\\') && (c != ','));
if (i > 255)
ERROR(11);
*ep++ = i;
if (c == ',') {
if(cflg++)
ERROR(44);
if((c = GETC()) == '\\') {
*ep++ = (char)255;
*lastep |= REGEXP_H_LEAST;
} else {
UNGETC(c);
goto nlim; /* get 2'nd number */
}
}
if(GETC() != '}')
ERROR(45);
if(!cflg) /* one number */
*ep++ = i;
else if((ep[-1] & 0377) < (ep[-2] & 0377))
ERROR(46);
continue;
case '\n':
ERROR(36);
case 'n':
c = '\n';
goto defchar;
default:
if(c >= '1' && c <= '9') {
if((c -= '1') >= closed)
ERROR(25);
*ep++ = CBACK;
*ep++ = c;
continue;
}
}
/* Drop through to default to use \ to turn off special chars */
defchar:
default:
lastep = ep;
#ifdef REGEXP_H_WCHARS
if (regexp_h_wchars == 0) {
#endif
*ep++ = CCHR;
*ep++ = c;
#ifdef REGEXP_H_WCHARS
} else {
char mbbuf[MB_LEN_MAX];
switch (wctomb(mbbuf, c)) {
case 1: *ep++ = CCH1;
break;
case 2: *ep++ = CCH2;
break;
case 3: *ep++ = CCH3;
break;
default:
*ep++ = CCHR|CMB;
}
regexp_h_store(c, ep, endbuf);
}
#endif /* REGEXP_H_WCHARS */
}
}
}
int
step(const char *p1, const char *p2)
{
register int c;
#ifdef REGEXP_H_WCHARS
register int d;
#endif /* REGEXP_H_WCHARS */
REGEXP_H_STEP_INIT /* get circf */
regexp_h_bol = p1;
#ifdef REGEXP_H_WCHARS
regexp_h_firstwc = NULL;
#endif /* REGEXP_H_WCHARS */
if (circf) {
loc1 = (char *)p1;
return(regexp_h_advance(p1, p2));
}
/* fast check for first character */
if (*p2==CCHR) {
c = p2[1] & 0377;
do {
if ((*p1 & 0377) != c)
continue;
if (regexp_h_advance(p1, p2)) {
loc1 = (char *)p1;
return(1);
}
} while (*p1++);
return(0);
}
#ifdef REGEXP_H_WCHARS
else if (*p2==CCH1) {
do {
if (p1[0] == p2[1] && regexp_h_advance(p1, p2)) {
loc1 = (char *)p1;
return(1);
}
c = regexp_h_fetch(p1, 1);
} while (c);
return(0);
} else if (*p2==CCH2) {
do {
if (p1[0] == p2[1] && p1[1] == p2[2] &&
regexp_h_advance(p1, p2)) {
loc1 = (char *)p1;
return(1);
}
c = regexp_h_fetch(p1, 1);
} while (c);
return(0);
} else if (*p2==CCH3) {
do {
if (p1[0] == p2[1] && p1[1] == p2[2] && p1[2] == p2[3]&&
regexp_h_advance(p1, p2)) {
loc1 = (char *)p1;
return(1);
}
c = regexp_h_fetch(p1, 1);
} while (c);
return(0);
} else if ((*p2&0377)==(CCHR|CMB)) {
d = regexp_h_fetch(p2, 0);
do {
c = regexp_h_fetch(p1, 1);
if (c == d && regexp_h_advance(p1, p2)) {
loc1 = (char *)p1;
return(1);
}
} while(c);
return(0);
}
/* regular algorithm */
if (regexp_h_wchars)
do {
if (regexp_h_advance(p1, p2)) {
loc1 = (char *)p1;
return(1);
}
c = regexp_h_fetch(p1, 1);
} while (c);
else
#endif /* REGEXP_H_WCHARS */
do {
if (regexp_h_advance(p1, p2)) {
loc1 = (char *)p1;
return(1);
}
} while (*p1++);
return(0);
}
#ifdef REGEXP_H_WCHARS
/*
* It is painfully slow to read character-wise backwards in a
* multibyte string (see regexp_h_previous() above). For the star
* algorithm, we therefore keep track of every character as it is
* read in forward direction.
*
* Don't use alloca() for stack blocks since there is no measurable
* speedup and huge amounts of memory are used up for long input
* lines.
*/
#ifndef REGEXP_H_STAKBLOK
#define REGEXP_H_STAKBLOK 1000
#endif
struct regexp_h_stack {
struct regexp_h_stack *s_nxt;
struct regexp_h_stack *s_prv;
const char *s_ptr[REGEXP_H_STAKBLOK];
};
#define regexp_h_push(sb, sp, sc, lp) (regexp_h_wchars ? \
regexp_h_pushwc(sb, sp, sc, lp) : (void)0)
static regexp_h_inline void
regexp_h_pushwc(struct regexp_h_stack **sb,
struct regexp_h_stack **sp,
const char ***sc, const char *lp)
{
if (regexp_h_firstwc == NULL || lp < regexp_h_firstwc)
return;
if (*sb == NULL) {
if ((*sb = regexp_h_malloc(sizeof **sb)) == NULL)
return;
(*sb)->s_nxt = (*sb)->s_prv = NULL;
*sp = *sb;
*sc = &(*sb)->s_ptr[0];
} else if (*sc >= &(*sp)->s_ptr[REGEXP_H_STAKBLOK]) {
if ((*sp)->s_nxt == NULL) {
struct regexp_h_stack *bq;
if ((bq = regexp_h_malloc(sizeof *bq)) == NULL)
return;
bq->s_nxt = NULL;
bq->s_prv = *sp;
(*sp)->s_nxt = bq;
*sp = bq;
} else
*sp = (*sp)->s_nxt;
*sc = &(*sp)->s_ptr[0];
}
*(*sc)++ = lp;
}
static regexp_h_inline const char *
regexp_h_pop(struct regexp_h_stack **sp, const char ***sc,
const char *lp)
{
if (regexp_h_firstwc == NULL || lp <= regexp_h_firstwc)
return &lp[-1];
if (*sp == NULL)
return regexp_h_firstwc;
if (*sc == &(*sp)->s_ptr[0]) {
if ((*sp)->s_prv == NULL) {
regexp_h_free(*sp);
*sp = NULL;
return regexp_h_firstwc;
}
*sp = (*sp)->s_prv;
regexp_h_free((*sp)->s_nxt);
(*sp)->s_nxt = NULL ;
*sc = &(*sp)->s_ptr[REGEXP_H_STAKBLOK];
}
return *(--(*sc));
}
static void
regexp_h_zerostak(struct regexp_h_stack **sb, struct regexp_h_stack **sp)
{
for (*sp = *sb; *sp && (*sp)->s_nxt; *sp = (*sp)->s_nxt)
if ((*sp)->s_prv)
regexp_h_free((*sp)->s_prv);
if (*sp) {
if ((*sp)->s_prv)
regexp_h_free((*sp)->s_prv);
regexp_h_free(*sp);
}
*sp = *sb = NULL;
}
#else /* !REGEXP_H_WCHARS */
#define regexp_h_push(sb, sp, sc, lp)
#endif /* !REGEXP_H_WCHARS */
static int
regexp_h_advance(const char *lp, const char *ep)
{
register const char *curlp;
int c, least;
#ifdef REGEXP_H_WCHARS
int d;
struct regexp_h_stack *sb = NULL, *sp = NULL;
const char **sc;
#endif /* REGEXP_H_WCHARS */
char *bbeg;
int ct;
for (;;) switch (least = *ep++ & 0377, least & ~REGEXP_H_LEAST) {
case CCHR:
#ifdef REGEXP_H_WCHARS
case CCH1:
#endif
if (*ep++ == *lp++)
continue;
return(0);
#ifdef REGEXP_H_WCHARS
case CCHR|CMB:
if (regexp_h_fetch(ep, 0) == regexp_h_fetch(lp, 1))
continue;
return(0);
case CCH2:
if (ep[0] == lp[0] && ep[1] == lp[1]) {
ep += 2, lp += 2;
continue;
}
return(0);
case CCH3:
if (ep[0] == lp[0] && ep[1] == lp[1] && ep[2] == lp[2]) {
ep += 3, lp += 3;
continue;
}
return(0);
#endif /* REGEXP_H_WCHARS */
case CDOT:
if (*lp++)
continue;
return(0);
#ifdef REGEXP_H_WCHARS
case CDOT|CMB:
if ((c = regexp_h_fetch(lp, 1)) != L'\0' && c != WEOF)
continue;
return(0);
#endif /* REGEXP_H_WCHARS */
case CDOL:
if (*lp==0)
continue;
return(0);
case CCEOF:
loc2 = (char *)lp;
return(1);
case CCL:
c = *lp++ & 0377;
if(ISTHERE(c)) {
ep += 32;
continue;
}
return(0);
#ifdef REGEXP_H_WCHARS
case CCL|CMB:
case CNCL|CMB:
c = regexp_h_fetch(lp, 1);
if (regexp_h_cclass(ep, c, (ep[-1] & 0377) == (CCL|CMB))) {
ep += (*ep & 0377) + 17;
continue;
}
return 0;
#endif /* REGEXP_H_WCHARS */
case CBRA:
braslist[*ep++ & 0377] = (char *)lp;
continue;
case CKET:
braelist[*ep++ & 0377] = (char *)lp;
continue;
case CBRC:
if (lp == regexp_h_bol && locs == NULL)
continue;
if ((isdigit(lp[0] & 0377) || regexp_h_uletter(lp[0] & 0377))
&& !regexp_h_uletter(lp[-1] & 0377)
&& !isdigit(lp[-1] & 0377))
continue;
return(0);
#ifdef REGEXP_H_WCHARS
case CBRC|CMB:
c = regexp_h_show(lp);
d = regexp_h_previous(lp);
if ((iswdigit(c) || regexp_h_wuletter(c))
&& !regexp_h_wuletter(d)
&& !iswdigit(d))
continue;
return(0);
#endif /* REGEXP_H_WCHARS */
case CLET:
if (!regexp_h_uletter(lp[0] & 0377) && !isdigit(lp[0] & 0377))
continue;
return(0);
#ifdef REGEXP_H_WCHARS
case CLET|CMB:
c = regexp_h_show(lp);
if (!regexp_h_wuletter(c) && !iswdigit(c))
continue;
return(0);
#endif /* REGEXP_H_WCHARS */
case CCHR|RNGE:
c = *ep++;
regexp_h_getrnge(ep, least);
while(low--)
if(*lp++ != c)
return(0);
curlp = lp;
while(size--) {
regexp_h_push(&sb, &sp, &sc, lp);
if(*lp++ != c)
break;
}
if(size < 0) {
regexp_h_push(&sb, &sp, &sc, lp);
lp++;
}
ep += 2;
goto star;
#ifdef REGEXP_H_WCHARS
case CCHR|RNGE|CMB:
case CCH1|RNGE:
case CCH2|RNGE:
case CCH3|RNGE:
c = regexp_h_fetch(ep, 0);
regexp_h_getrnge(ep, least);
while (low--)
if (regexp_h_fetch(lp, 1) != c)
return 0;
curlp = lp;
while (size--) {
regexp_h_push(&sb, &sp, &sc, lp);
if (regexp_h_fetch(lp, 1) != c)
break;
}
if(size < 0) {
regexp_h_push(&sb, &sp, &sc, lp);
regexp_h_fetch(lp, 1);
}
ep += 2;
goto star;
#endif /* REGEXP_H_WCHARS */
case CDOT|RNGE:
regexp_h_getrnge(ep, least);
while(low--)
if(*lp++ == '\0')
return(0);
curlp = lp;
while(size--) {
regexp_h_push(&sb, &sp, &sc, lp);
if(*lp++ == '\0')
break;
}
if(size < 0) {
regexp_h_push(&sb, &sp, &sc, lp);
lp++;
}
ep += 2;
goto star;
#ifdef REGEXP_H_WCHARS
case CDOT|RNGE|CMB:
regexp_h_getrnge(ep, least);
while (low--)
if ((c = regexp_h_fetch(lp, 1)) == L'\0' || c == WEOF)
return 0;
curlp = lp;
while (size--) {
regexp_h_push(&sb, &sp, &sc, lp);
if ((c = regexp_h_fetch(lp, 1)) == L'\0' || c == WEOF)
break;
}
if (size < 0) {
regexp_h_push(&sb, &sp, &sc, lp);
regexp_h_fetch(lp, 1);
}
ep += 2;
goto star;
#endif /* REGEXP_H_WCHARS */
case CCL|RNGE:
regexp_h_getrnge(ep + 32, least);
while(low--) {
c = *lp++ & 0377;
if(!ISTHERE(c))
return(0);
}
curlp = lp;
while(size--) {
regexp_h_push(&sb, &sp, &sc, lp);
c = *lp++ & 0377;
if(!ISTHERE(c))
break;
}
if(size < 0) {
regexp_h_push(&sb, &sp, &sc, lp);
lp++;
}
ep += 34; /* 32 + 2 */
goto star;
#ifdef REGEXP_H_WCHARS
case CCL|RNGE|CMB:
case CNCL|RNGE|CMB:
regexp_h_getrnge(ep + (*ep & 0377) + 17, least);
while (low--) {
c = regexp_h_fetch(lp, 1);
if (!regexp_h_cclass(ep, c,
(ep[-1] & 0377 & ~REGEXP_H_LEAST)
== (CCL|RNGE|CMB)))
return 0;
}
curlp = lp;
while (size--) {
regexp_h_push(&sb, &sp, &sc, lp);
c = regexp_h_fetch(lp, 1);
if (!regexp_h_cclass(ep, c,
(ep[-1] & 0377 & ~REGEXP_H_LEAST)
== (CCL|RNGE|CMB)))
break;
}
if (size < 0) {
regexp_h_push(&sb, &sp, &sc, lp);
regexp_h_fetch(lp, 1);
}
ep += (*ep & 0377) + 19;
goto star;
#endif /* REGEXP_H_WCHARS */
case CBACK:
bbeg = braslist[*ep & 0377];
ct = braelist[*ep++ & 0377] - bbeg;
if(strncmp(bbeg, lp, ct) == 0) {
lp += ct;
continue;
}
return(0);
case CBACK|STAR:
bbeg = braslist[*ep & 0377];
ct = braelist[*ep++ & 0377] - bbeg;
curlp = lp;
while(strncmp(bbeg, lp, ct) == 0)
lp += ct;
while(lp >= curlp) {
if(regexp_h_advance(lp, ep)) return(1);
lp -= ct;
}
return(0);
case CDOT|STAR:
curlp = lp;
do
regexp_h_push(&sb, &sp, &sc, lp);
while (*lp++);
goto star;
#ifdef REGEXP_H_WCHARS
case CDOT|STAR|CMB:
curlp = lp;
do
regexp_h_push(&sb, &sp, &sc, lp);
while ((c = regexp_h_fetch(lp, 1)) != L'\0' && c != WEOF);
goto star;
#endif /* REGEXP_H_WCHARS */
case CCHR|STAR:
curlp = lp;
do
regexp_h_push(&sb, &sp, &sc, lp);
while (*lp++ == *ep);
ep++;
goto star;
#ifdef REGEXP_H_WCHARS
case CCHR|STAR|CMB:
case CCH1|STAR:
case CCH2|STAR:
case CCH3|STAR:
curlp = lp;
d = regexp_h_fetch(ep, 0);
do
regexp_h_push(&sb, &sp, &sc, lp);
while (regexp_h_fetch(lp, 1) == d);
goto star;
#endif /* REGEXP_H_WCHARS */
case CCL|STAR:
curlp = lp;
do {
regexp_h_push(&sb, &sp, &sc, lp);
c = *lp++ & 0377;
} while(ISTHERE(c));
ep += 32;
goto star;
#ifdef REGEXP_H_WCHARS
case CCL|STAR|CMB:
case CNCL|STAR|CMB:
curlp = lp;
do {
regexp_h_push(&sb, &sp, &sc, lp);
c = regexp_h_fetch(lp, 1);
} while (regexp_h_cclass(ep, c, (ep[-1] & 0377)
== (CCL|STAR|CMB)));
ep += (*ep & 0377) + 17;
goto star;
#endif /* REGEXP_H_WCHARS */
star:
#ifdef REGEXP_H_WCHARS
if (regexp_h_wchars == 0) {
#endif
do {
if(--lp == locs)
break;
if (regexp_h_advance(lp, ep))
return(1);
} while (lp > curlp);
#ifdef REGEXP_H_WCHARS
} else {
do {
lp = regexp_h_pop(&sp, &sc, lp);
if (lp <= locs)
break;
if (regexp_h_advance(lp, ep)) {
regexp_h_zerostak(&sb, &sp);
return(1);
}
} while (lp > curlp);
regexp_h_zerostak(&sb, &sp);
}
#endif /* REGEXP_H_WCHARS */
return(0);
}
}
static void
regexp_h_getrnge(register const char *str, int least)
{
low = *str++ & 0377;
size = least & REGEXP_H_LEAST ? /*20000*/INT_MAX : (*str & 0377) - low;
}
int
advance(const char *lp, const char *ep)
{
REGEXP_H_ADVANCE_INIT /* skip past circf */
regexp_h_bol = lp;
#ifdef REGEXP_H_WCHARS
regexp_h_firstwc = NULL;
#endif /* REGEXP_H_WCHARS */
return regexp_h_advance(lp, ep);
}