46 #define matcher smatcher 49 #define dissect sdissect 50 #define backref sbackref 58 #define matcher lmatcher 61 #define dissect ldissect 62 #define backref lbackref 87 static int matcher(
struct re_guts *,
const char *,
size_t,
89 static const char *dissect(
struct match *,
const char *,
const char *,
sopno,
91 static const char *backref(
struct match *,
const char *,
const char *,
sopno,
93 static const char *fast(
struct match *,
const char *,
const char *,
sopno,
sopno);
94 static const char *slow(
struct match *,
const char *,
const char *,
sopno,
sopno);
96 #define MAX_RECURSION 100 99 #define BOLEOL (BOL+2) 100 #define NOTHING (BOL+3) 103 #define CODEMAX (BOL+5) 104 #define NONCHAR(c) ((c) > CHAR_MAX) 105 #define NNONCHAR (CODEMAX-CHAR_MAX) 113 static char *pchar(
int);
117 #define SP(t, s, c) print(m, t, s, c, stdout) 118 #define AT(t, p1, p2, s1, s2) at(m, t, p1, p2, s1, s2) 119 #define NOTE(str) { if (m->eflags®_TRACE) (void)printf("=%s\n", (str)); } 123 #define AT(t, p1, p2, s1, s2) 131 matcher(
struct re_guts *g,
const char *
string,
size_t nmatch,
138 struct match *m = &mv;
149 start =
string + pmatch[0].
rm_so;
150 stop =
string + pmatch[0].
rm_eo;
153 stop = start + strlen(start);
159 if (g->
must != NULL) {
160 for (dp = start; dp < stop; dp++)
161 if (*dp == g->
must[0] && stop - dp >= g->
mlen &&
185 endp = fast(m, start, stop, gf, gl);
188 free((
void*)m->lastpos);
198 NOTE(
"finding start");
199 endp = slow(m, m->coldp, stop, gf, gl);
202 assert(m->coldp < m->endp);
209 if (m->pmatch == NULL)
212 if (m->pmatch == NULL) {
216 for (i = 1; i <= m->g->nsub; i++)
217 m->pmatch[i].rm_so = m->pmatch[i].rm_eo = -1;
220 dp = dissect(m, m->coldp, endp, gf, gl);
222 if (g->
nplus > 0 && m->lastpos == NULL)
223 m->lastpos = (
const char **)malloc((g->
nplus+1) *
225 if (g->
nplus > 0 && m->lastpos == NULL) {
230 NOTE(
"backref dissect");
231 dp = backref(m, m->coldp, endp, gf, gl, (
sopno)0, 0);
240 if (dp != NULL || endp <= m->coldp)
243 endp = slow(m, m->coldp, endp-1, gf, gl);
248 for (i = 1; i <= m->g->nsub; i++) {
249 assert(m->pmatch[i].rm_so == -1);
250 assert(m->pmatch[i].rm_eo == -1);
253 NOTE(
"backoff dissect");
254 dp = backref(m, m->coldp, endp, gf, gl, (
sopno)0, 0);
256 assert(dp == NULL || dp == endp);
262 if (m->coldp == stop)
264 start = m->coldp + 1;
269 pmatch[0].
rm_so = m->coldp - m->offp;
270 pmatch[0].
rm_eo = endp - m->offp;
273 assert(m->pmatch != NULL);
274 for (i = 1; i < nmatch; i++)
276 pmatch[i] = m->pmatch[i];
278 pmatch[i].
rm_so = -1;
279 pmatch[i].
rm_eo = -1;
283 if (m->pmatch != NULL)
284 free((
char *)m->pmatch);
285 if (m->lastpos != NULL)
286 free((
char *)m->lastpos);
295 dissect(
struct match *m,
const char *start,
const char *stop,
sopno startst,
311 AT(
"diss", start, stop, startst, stopst);
313 for (ss = startst; ss < stopst; ss = es) {
316 switch (
OP(m->g->strip[es])) {
319 es +=
OPND(m->g->strip[es]);
322 while (
OP(m->g->strip[es]) !=
O_CH)
323 es +=
OPND(m->g->strip[es]);
329 switch (
OP(m->g->strip[ss])) {
354 rest = slow(m, sp, stp, ss, es);
357 tail = slow(m, rest, stop, es, stopst);
367 if (slow(m, sp, rest, ssub, esub) != NULL) {
368 const char *dp = dissect(m, sp, rest, ssub, esub);
379 rest = slow(m, sp, stp, ss, es);
382 tail = slow(m, rest, stop, es, stopst);
394 sep = slow(m, ssp, rest, ssub, esub);
395 if (sep == NULL || sep == ssp)
406 assert(slow(m, ssp, sep, ssub, esub) == rest);
408 const char *dp = dissect(m, ssp, sep, ssub, esub);
418 rest = slow(m, sp, stp, ss, es);
421 tail = slow(m, rest, stop, es, stopst);
429 esub = ss +
OPND(m->g->strip[ss]) - 1;
432 if (slow(m, sp, rest, ssub, esub) == rest)
439 esub +=
OPND(m->g->strip[esub]);
440 if (
OP(m->g->strip[esub]) ==
OOR2)
446 const char *dp = dissect(m, sp, rest, ssub, esub);
460 i =
OPND(m->g->strip[ss]);
462 m->pmatch[i].rm_so = sp - m->offp;
465 i =
OPND(m->g->strip[ss]);
467 m->pmatch[i].rm_eo = sp - m->offp;
483 backref(
struct match *m,
const char *start,
const char *stop,
sopno startst,
499 AT(
"back", start, stop, startst, stopst);
504 for (ss = startst; !hard && ss < stopst; ss++)
505 switch (
OP(s = m->g->strip[ss])) {
507 if (sp == stop || *sp++ != (
char)
OPND(s))
516 cs = &m->g->sets[
OPND(s)];
517 if (sp == stop || !
CHIN(cs, *sp++))
521 if ( (sp == m->beginp && !(m->eflags&
REG_NOTBOL)) ||
522 (sp < m->endp && *(sp-1) ==
'\n' &&
529 if ( (sp == m->endp && !(m->eflags&
REG_NOTEOL)) ||
530 (sp < m->endp && *sp ==
'\n' &&
537 if (( (sp == m->beginp && !(m->eflags&
REG_NOTBOL)) ||
538 (sp < m->endp && *(sp-1) ==
'\n' &&
542 (sp < m->endp &&
ISWORD(*sp)) )
548 if (( (sp == m->endp && !(m->eflags&
REG_NOTEOL)) ||
549 (sp < m->endp && *sp ==
'\n' &&
551 (sp < m->endp && !
ISWORD(*sp)) ) &&
552 (sp > m->beginp &&
ISWORD(*(sp-1))) )
565 }
while (
OP(s = m->g->strip[ss]) !=
O_CH);
580 AT(
"hard", sp, stop, ss, stopst);
586 if (m->pmatch[i].rm_eo == -1)
588 assert(m->pmatch[i].rm_so != -1);
589 len = m->pmatch[i].rm_eo - m->pmatch[i].rm_so;
590 if (len == 0 && rec++ > MAX_RECURSION)
592 assert(stop - m->beginp >= len);
595 ssp = m->offp + m->pmatch[i].rm_so;
596 if (
memcmp(sp, ssp, len) != 0)
598 while (m->g->strip[ss] !=
SOP(
O_BACK, i))
600 return(backref(m, sp+len, stop, ss+1, stopst, lev, rec));
603 dp = backref(m, sp, stop, ss+1, stopst, lev, rec);
606 return(backref(m, sp, stop, ss+
OPND(s)+1, stopst, lev, rec));
609 assert(m->lastpos != NULL);
610 assert(lev+1 <= m->g->nplus);
611 m->lastpos[lev+1] = sp;
612 return(backref(m, sp, stop, ss+1, stopst, lev+1, rec));
615 if (sp == m->lastpos[lev])
616 return(backref(m, sp, stop, ss+1, stopst, lev-1, rec));
618 m->lastpos[lev] = sp;
619 dp = backref(m, sp, stop, ss-
OPND(s)+1, stopst, lev, rec);
621 return(backref(m, sp, stop, ss+1, stopst, lev-1, rec));
627 esub = ss +
OPND(s) - 1;
630 dp = backref(m, sp, stop, ssub, esub, lev, rec);
634 if (
OP(m->g->strip[esub]) ==
O_CH)
639 esub +=
OPND(m->g->strip[esub]);
640 if (
OP(m->g->strip[esub]) ==
OOR2)
649 offsave = m->pmatch[i].rm_so;
650 m->pmatch[i].rm_so = sp - m->offp;
651 dp = backref(m, sp, stop, ss+1, stopst, lev, rec);
654 m->pmatch[i].rm_so = offsave;
660 offsave = m->pmatch[i].rm_eo;
661 m->pmatch[i].rm_eo = sp - m->offp;
662 dp = backref(m, sp, stop, ss+1, stopst, lev, rec);
665 m->pmatch[i].rm_eo = offsave;
683 fast(
struct match *m,
const char *start,
const char *stop,
sopno startst,
689 const char *p = start;
690 int c = (start == m->beginp) ?
OUT : *(start-1);
698 st = step(m->g, startst, stopst, st, NOTHING, st);
705 c = (p == m->endp) ?
OUT : *p;
712 if ( (lastc ==
'\n' && m->g->cflags&
REG_NEWLINE) ||
719 flagch = (flagch == BOL) ? BOLEOL : EOL;
724 st = step(m->g, startst, stopst, st, flagch, st);
729 if ( (flagch == BOL || (lastc !=
OUT && !
ISWORD(lastc))) &&
734 (flagch == EOL || (c !=
OUT && !
ISWORD(c))) ) {
737 if (flagch == BOW || flagch == EOW) {
738 st = step(m->g, startst, stopst, st, flagch, st);
743 if (
ISSET(st, stopst) || p == stop)
750 st = step(m->g, startst, stopst, tmp, c, st);
752 assert(
EQ(step(m->g, startst, stopst, st, NOTHING, st), st));
758 if (
ISSET(st, stopst))
768 slow(
struct match *m,
const char *start,
const char *stop,
sopno startst,
774 const char *p = start;
775 int c = (start == m->beginp) ?
OUT : *(start-1);
781 AT(
"slow", start, stop, startst, stopst);
784 SP(
"sstart", st, *p);
785 st = step(m->g, startst, stopst, st, NOTHING, st);
790 c = (p == m->endp) ?
OUT : *p;
795 if ( (lastc ==
'\n' && m->g->cflags&
REG_NEWLINE) ||
802 flagch = (flagch == BOL) ? BOLEOL : EOL;
807 st = step(m->g, startst, stopst, st, flagch, st);
808 SP(
"sboleol", st, c);
812 if ( (flagch == BOL || (lastc !=
OUT && !
ISWORD(lastc))) &&
817 (flagch == EOL || (c !=
OUT && !
ISWORD(c))) ) {
820 if (flagch == BOW || flagch == EOW) {
821 st = step(m->g, startst, stopst, st, flagch, st);
822 SP(
"sboweow", st, c);
826 if (
ISSET(st, stopst))
828 if (
EQ(st, empty) || p == stop)
835 st = step(m->g, startst, stopst, tmp, c, st);
837 assert(
EQ(step(m->g, startst, stopst, st, NOTHING, st), st));
863 for (pc = start,
INIT(here, pc); pc != stop; pc++,
INC(here)) {
872 if (ch == (
char)
OPND(s))
876 if (ch == BOL || ch == BOLEOL)
880 if (ch == EOL || ch == BOLEOL)
897 if (!NONCHAR(ch) &&
CHIN(cs, ch))
975 (void)fprintf(d,
"%s", caption);
977 (void)fprintf(d,
" %s", pchar(ch));
978 for (i = 0; i < g->
nstates; i++)
980 (void)fprintf(d,
"%s%d", (first) ?
"\t" :
", ", i);
983 (void)fprintf(d,
"\n");
990 at(
struct match *m,
char *title,
char *start,
char *stop,
sopno startst,
996 (void)printf(
"%s %s-", title, pchar(*start));
997 (void)printf(
"%s ", pchar(*stop));
998 (void)printf(
"%ld-%ld\n", (
long)startst, (long)stopst);
1014 static char pbuf[10];
1017 (void)snprintf(pbuf,
sizeof pbuf,
"%c", ch);
1019 (
void)snprintf(pbuf,
sizeof pbuf,
"\\%o", ch);
bool isPrint(char C)
Checks whether character C is printable.
bool match(Val *V, const Pattern &P)
* if(!EatIfPresent(lltok::kw_thread_local)) return false
ParseOptionalThreadLocal := /*empty.
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
constexpr bool empty(const T &RangeOrContainer)
Test whether RangeOrContainer is empty. Similar to C++17 std::empty.
#define BACK(dst, src, n)
Merge contiguous icmps into a memcmp
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())