Changeset View
Changeset View
Standalone View
Standalone View
lib/libc/regex/engine.c
Show First 20 Lines • Show All 42 Lines • ▼ Show 20 Lines | |||||
/* | /* | ||||
* The matching engine and friends. This file is #included by regexec.c | * The matching engine and friends. This file is #included by regexec.c | ||||
* after suitable #defines of a variety of macros used herein, so that | * after suitable #defines of a variety of macros used herein, so that | ||||
* different state representations can be used without duplicating masses | * different state representations can be used without duplicating masses | ||||
* of code. | * of code. | ||||
*/ | */ | ||||
#ifdef SNAMES | #ifdef SNAMES | ||||
#define stepback sstepback | |||||
#define matcher smatcher | #define matcher smatcher | ||||
#define walk swalk | #define walk swalk | ||||
#define dissect sdissect | #define dissect sdissect | ||||
#define backref sbackref | #define backref sbackref | ||||
#define step sstep | #define step sstep | ||||
#define print sprint | #define print sprint | ||||
#define at sat | #define at sat | ||||
#define match smat | #define match smat | ||||
#endif | #endif | ||||
#ifdef LNAMES | #ifdef LNAMES | ||||
#define stepback lstepback | |||||
#define matcher lmatcher | #define matcher lmatcher | ||||
#define walk lwalk | #define walk lwalk | ||||
#define dissect ldissect | #define dissect ldissect | ||||
#define backref lbackref | #define backref lbackref | ||||
#define step lstep | #define step lstep | ||||
#define print lprint | #define print lprint | ||||
#define at lat | #define at lat | ||||
#define match lmat | #define match lmat | ||||
#endif | #endif | ||||
#ifdef MNAMES | #ifdef MNAMES | ||||
#define stepback mstepback | |||||
#define matcher mmatcher | #define matcher mmatcher | ||||
#define walk mwalk | #define walk mwalk | ||||
#define dissect mdissect | #define dissect mdissect | ||||
#define backref mbackref | #define backref mbackref | ||||
#define step mstep | #define step mstep | ||||
#define print mprint | #define print mprint | ||||
#define at mat | #define at mat | ||||
#define match mmat | #define match mmat | ||||
▲ Show 20 Lines • Show All 58 Lines • ▼ Show 20 Lines | |||||
#define NOTE(str) { if (m->eflags®_TRACE) printf("=%s\n", (str)); } | #define NOTE(str) { if (m->eflags®_TRACE) printf("=%s\n", (str)); } | ||||
#else | #else | ||||
#define SP(t, s, c) /* nothing */ | #define SP(t, s, c) /* nothing */ | ||||
#define AT(t, p1, p2, s1, s2) /* nothing */ | #define AT(t, p1, p2, s1, s2) /* nothing */ | ||||
#define NOTE(s) /* nothing */ | #define NOTE(s) /* nothing */ | ||||
#endif | #endif | ||||
/* | /* | ||||
* Given a multibyte string starting at start, step back nchar characters | |||||
* from current position pointed to by pos. | |||||
*/ | |||||
static const char * | |||||
stepback(const char *start, const char *cur, size_t nchar) | |||||
{ | |||||
const char *ret; | |||||
int wc, mbc; | |||||
mbstate_t mbs; | |||||
size_t clen; | |||||
if (MB_CUR_MAX == 1) | |||||
return ((cur - nchar) > start ? cur - nchar : NULL); | |||||
ret = cur; | |||||
for (wc = nchar; wc > 0; wc--) { | |||||
for (mbc = 1; mbc <= MB_CUR_MAX; mbc++) { | |||||
if ((ret - mbc) < start) | |||||
return (NULL); | |||||
memset(&mbs, 0, sizeof(mbs)); | |||||
clen = mbrtowc(NULL, cur - mbc, mbc, &mbs); | |||||
if (clen != (size_t)-1 && clen != (size_t)-2) | |||||
break; | |||||
} | |||||
if (mbc > MB_CUR_MAX) | |||||
return (NULL); | |||||
ret -= mbc; | |||||
} | |||||
return (ret); | |||||
} | |||||
/* | |||||
- matcher - the actual matching engine | - matcher - the actual matching engine | ||||
== static int matcher(struct re_guts *g, const char *string, \ | == static int matcher(struct re_guts *g, const char *string, \ | ||||
== size_t nmatch, regmatch_t pmatch[], int eflags); | == size_t nmatch, regmatch_t pmatch[], int eflags); | ||||
*/ | */ | ||||
static int /* 0 success, REG_NOMATCH failure */ | static int /* 0 success, REG_NOMATCH failure */ | ||||
matcher(struct re_guts *g, | matcher(struct re_guts *g, | ||||
const char *string, | const char *string, | ||||
size_t nmatch, | size_t nmatch, | ||||
▲ Show 20 Lines • Show All 86 Lines • ▼ Show 20 Lines | matcher(struct re_guts *g, | ||||
SETUP(m->st); | SETUP(m->st); | ||||
SETUP(m->fresh); | SETUP(m->fresh); | ||||
SETUP(m->tmp); | SETUP(m->tmp); | ||||
SETUP(m->empty); | SETUP(m->empty); | ||||
CLEAR(m->empty); | CLEAR(m->empty); | ||||
ZAPSTATE(&m->mbs); | ZAPSTATE(&m->mbs); | ||||
/* Adjust start according to moffset, to speed things up */ | /* Adjust start according to moffset, to speed things up */ | ||||
if (dp != NULL && g->moffset > -1) | if (dp != NULL && g->moffset > -1) { | ||||
start = ((dp - g->moffset) < start) ? start : dp - g->moffset; | const char *nstart; | ||||
nstart = stepback(start, dp, g->moffset); | |||||
if (nstart != NULL) | |||||
start = nstart; | |||||
} | |||||
SP("mloop", m->st, *start); | SP("mloop", m->st, *start); | ||||
/* this loop does only one repetition except for backrefs */ | /* this loop does only one repetition except for backrefs */ | ||||
for (;;) { | for (;;) { | ||||
endp = walk(m, start, stop, gf, gl, true); | endp = walk(m, start, stop, gf, gl, true); | ||||
if (endp == NULL) { /* a miss */ | if (endp == NULL) { /* a miss */ | ||||
if (m->pmatch != NULL) | if (m->pmatch != NULL) | ||||
free((char *)m->pmatch); | free((char *)m->pmatch); | ||||
▲ Show 20 Lines • Show All 820 Lines • ▼ Show 20 Lines | if (isprint((uch)ch) || ch == ' ') | ||||
sprintf(pbuf, "%c", ch); | sprintf(pbuf, "%c", ch); | ||||
else | else | ||||
sprintf(pbuf, "\\%o", ch); | sprintf(pbuf, "\\%o", ch); | ||||
return(pbuf); | return(pbuf); | ||||
} | } | ||||
#endif | #endif | ||||
#endif | #endif | ||||
#undef stepback | |||||
#undef matcher | #undef matcher | ||||
#undef walk | #undef walk | ||||
#undef dissect | #undef dissect | ||||
#undef backref | #undef backref | ||||
#undef step | #undef step | ||||
#undef print | #undef print | ||||
#undef at | #undef at | ||||
#undef match | #undef match |