in Source/kwsys/RegularExpression.cxx [971:1193]
int RegExpFind::regmatch(char const* prog)
{
char const* scan; // Current node.
char const* next; // Next node.
scan = prog;
while (scan) {
next = regnext(scan);
switch (OP(scan)) {
case BOL:
if (reginput != regbol)
return (0);
break;
case EOL:
if (*reginput != '\0')
return (0);
break;
case ANY:
if (*reginput == '\0')
return (0);
reginput++;
break;
case EXACTLY: {
size_t len;
char const* opnd;
opnd = OPERAND(scan);
// Inline the first character, for speed.
if (*opnd != *reginput)
return (0);
len = strlen(opnd);
if (len > 1 && strncmp(opnd, reginput, len) != 0)
return (0);
reginput += len;
} break;
case ANYOF:
if (*reginput == '\0' || !strchr(OPERAND(scan), *reginput))
return (0);
reginput++;
break;
case ANYBUT:
if (*reginput == '\0' || strchr(OPERAND(scan), *reginput))
return (0);
reginput++;
break;
case NOTHING:
break;
case BACK:
break;
case OPEN + 1:
case OPEN + 2:
case OPEN + 3:
case OPEN + 4:
case OPEN + 5:
case OPEN + 6:
case OPEN + 7:
case OPEN + 8:
case OPEN + 9:
case OPEN + 10:
case OPEN + 11:
case OPEN + 12:
case OPEN + 13:
case OPEN + 14:
case OPEN + 15:
case OPEN + 16:
case OPEN + 17:
case OPEN + 18:
case OPEN + 19:
case OPEN + 20:
case OPEN + 21:
case OPEN + 22:
case OPEN + 23:
case OPEN + 24:
case OPEN + 25:
case OPEN + 26:
case OPEN + 27:
case OPEN + 28:
case OPEN + 29:
case OPEN + 30:
case OPEN + 31:
case OPEN + 32: {
int no;
char const* save;
no = OP(scan) - OPEN;
save = reginput;
if (regmatch(next)) {
//
// Don't set startp if some later invocation of the
// same parentheses already has.
//
if (!regstartp[no])
regstartp[no] = save;
return (1);
} else
return (0);
}
// break;
case CLOSE + 1:
case CLOSE + 2:
case CLOSE + 3:
case CLOSE + 4:
case CLOSE + 5:
case CLOSE + 6:
case CLOSE + 7:
case CLOSE + 8:
case CLOSE + 9:
case CLOSE + 10:
case CLOSE + 11:
case CLOSE + 12:
case CLOSE + 13:
case CLOSE + 14:
case CLOSE + 15:
case CLOSE + 16:
case CLOSE + 17:
case CLOSE + 18:
case CLOSE + 19:
case CLOSE + 20:
case CLOSE + 21:
case CLOSE + 22:
case CLOSE + 23:
case CLOSE + 24:
case CLOSE + 25:
case CLOSE + 26:
case CLOSE + 27:
case CLOSE + 28:
case CLOSE + 29:
case CLOSE + 30:
case CLOSE + 31:
case CLOSE + 32: {
int no;
char const* save;
no = OP(scan) - CLOSE;
save = reginput;
if (regmatch(next)) {
//
// Don't set endp if some later invocation of the
// same parentheses already has.
//
if (!regendp[no])
regendp[no] = save;
return (1);
} else
return (0);
}
// break;
case BRANCH: {
char const* save;
if (OP(next) != BRANCH) // No choice.
next = OPERAND(scan); // Avoid recursion.
else {
do {
save = reginput;
if (regmatch(OPERAND(scan)))
return (1);
reginput = save;
scan = regnext(scan);
} while (scan && OP(scan) == BRANCH);
return (0);
// NOTREACHED
}
} break;
case STAR:
case PLUS: {
char nextch;
int no;
char const* save;
int min_no;
//
// Lookahead to avoid useless match attempts when we know
// what character comes next.
//
nextch = '\0';
if (OP(next) == EXACTLY)
nextch = *OPERAND(next);
min_no = (OP(scan) == STAR) ? 0 : 1;
save = reginput;
no = regrepeat(OPERAND(scan));
while (no >= min_no) {
// If it could work, try it.
if (nextch == '\0' || *reginput == nextch)
if (regmatch(next))
return (1);
// Couldn't or didn't -- back up.
no--;
reginput = save + no;
}
return (0);
}
// break;
case END:
if (reginput == regreject)
return (0); // Can't end a match here
return (1); // Success!
default:
// RAISE Error, SYM(RegularExpression), SYM(Internal_Error),
printf(
"RegularExpression::find(): Internal error -- memory corrupted.\n");
return 0;
}
scan = next;
}
//
// We get here only if there's trouble -- normally "case END" is the
// terminating point.
//
// RAISE Error, SYM(RegularExpression), SYM(Internal_Error),
printf("RegularExpression::find(): Internal error -- corrupted pointers.\n");
return (0);
}