📄 pgpregexp.c
字号:
#if REGEXP_DEBUG
if (regnarrate)
fprintf(stderr, "%s...\n", regprop(scan));
#endif
next = regnext(scan);
switch (OP(scan)) {
case BOL:
if (res->reginput != res->regbol)
return(0);
break;
case EOL:
if (*res->reginput != '\0')
return(0);
break;
case ANY:
if (*res->reginput == '\0')
return(0);
res->reginput++;
break;
case EXACTLY: {
int len;
char const *opnd;
opnd = OPERAND(scan);
/* Inline the first character, for speed. */
if (*opnd != *res->reginput)
return(0);
len = strlen(opnd);
if (len > 1 && strncmp(opnd, res->reginput, len) != 0)
return(0);
res->reginput += len;
}
break;
case ANYOF:
if (*res->reginput == '\0' ||
strchr(OPERAND(scan), *res->reginput) == NULL)
return(0);
res->reginput++;
break;
case ANYBUT:
if (*res->reginput == '\0' ||
strchr(OPERAND(scan), *res->reginput) != NULL)
return(0);
res->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: {
int no;
char const *save;
no = OP(scan) - OPEN;
save = res->reginput;
if (regmatch(res, next)) {
/*
* Don't set startp if some later
* invocation of the same parentheses
* already has.
*/
if (res->regstartp[no] == NULL)
res->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: {
int no;
char const *save;
no = OP(scan) - CLOSE;
save = res->reginput;
if (regmatch(res, next)) {
/*
* Don't set endp if some later
* invocation of the same parentheses
* already has.
*/
if (res->regendp[no] == NULL)
res->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 = res->reginput;
if (regmatch(res, OPERAND(scan)))
return(1);
res->reginput = save;
scan = regnext(scan);
} while (scan != NULL && OP(scan) == BRANCH);
return(0);
/* NOTREACHED */
}
}
break;
case STAR:
case PLUS: {
char nextch;
int no;
char const *save;
int min;
/*
* Lookahead to avoid useless match attempts
* when we know what character comes next.
*/
nextch = '\0';
if (OP(next) == EXACTLY)
nextch = *OPERAND(next);
min = (OP(scan) == STAR) ? 0 : 1;
save = res->reginput;
no = regrepeat(res, OPERAND(scan));
while (no >= min) {
/* If it could work, try it. */
if (nextch == '\0' || *res->reginput == nextch)
if (regmatch(res, next))
return(1);
/* Couldn't or didn't -- back up. */
no--;
res->reginput = save + no;
}
return(0);
}
break;
case END:
return(1); /* Success! */
break;
default:
FAIL("memory corruption");
return(0);
break;
}
scan = next;
}
/*
* We get here only if there's trouble -- normally "case END" is
* the terminating point.
*/
FAIL("corrupted pointers");
return(0);
}
/*
- regrepeat - repeatedly match something simple, report how many
*/
static int
regrepeat(regexecState *res, char const *p)
{
int count = 0;
char const *scan;
char const *opnd;
scan = res->reginput;
opnd = OPERAND(p);
switch (OP(p)) {
case ANY:
count = strlen(scan);
scan += count;
break;
case EXACTLY:
while (*opnd == *scan) {
count++;
scan++;
}
break;
case ANYOF:
while (*scan != '\0' && strchr(opnd, *scan) != NULL) {
count++;
scan++;
}
break;
case ANYBUT:
while (*scan != '\0' && strchr(opnd, *scan) == NULL) {
count++;
scan++;
}
break;
default: /* Oh dear. Called inappropriately. */
FAIL("internal foulup");
count = 0; /* Best compromise. */
break;
}
res->reginput = scan;
return(count);
}
/*
- regnext - dig the "next" pointer out of a node
*/
static char *
regnext(char const *p)
{
int offset;
if (p == ®dummy)
return(NULL);
offset = NEXT(p);
if (offset == 0)
return(NULL);
if (OP(p) == BACK)
return(char *)(p-offset);
else
return(char *)(p+offset);
}
#if REGEXP_DEBUG
static char *regprop();
/*
- regdump - dump a regexp onto stdout in vaguely comprehensible form
*/
void
regdump(regexp const *r)
{
char *s;
char op = EXACTLY; /* Arbitrary non-END op. */
char *next;
extern char *strchr();
s = r->program + 1;
while (op != END) { /* While that wasn't END last time... */
op = OP(s);
printf("%2d%s", s-r->program, regprop(s)); /* Where, what. */
next = regnext(s);
if (next == NULL) /* Next ptr. */
printf("(0)");
else
printf("(%d)", (s-r->program)+(next-s));
s += 3;
if (op == ANYOF || op == ANYBUT || op == EXACTLY) {
/* Literal string, where present. */
while (*s != '\0') {
putchar(*s);
s++;
}
s++;
}
putchar('\n');
}
/* Header fields of interest. */
if (r->regstart != '\0')
printf("start `%c' ", r->regstart);
if (r->reganch)
printf("anchored ");
if (r->regmust != NULL)
printf("must have \"%s\"", r->regmust);
printf("\n");
}
/*
- regprop - printable representation of opcode
*/
static char *
regprop(op)
char *op;
{
char *p;
static char buf[50];
(void) strcpy(buf, ":");
switch (OP(op)) {
case BOL:
p = "BOL";
break;
case EOL:
p = "EOL";
break;
case ANY:
p = "ANY";
break;
case ANYOF:
p = "ANYOF";
break;
case ANYBUT:
p = "ANYBUT";
break;
case BRANCH:
p = "BRANCH";
break;
case EXACTLY:
p = "EXACTLY";
break;
case NOTHING:
p = "NOTHING";
break;
case BACK:
p = "BACK";
break;
case END:
p = "END";
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:
sprintf(buf+strlen(buf), "OPEN%d", OP(op)-OPEN);
p = NULL;
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:
sprintf(buf+strlen(buf), "CLOSE%d", OP(op)-CLOSE);
p = NULL;
break;
case STAR:
p = "STAR";
break;
case PLUS:
p = "PLUS";
break;
default:
regerror("corrupted opcode");
break;
}
if (p != NULL)
(void) strcat(buf, p);
return(buf);
}
#endif
/*
* The following is provided for those people who do not have strcspn() in
* their C libraries. They should get off their butts and do something
* about it; at least one public-domain implementation of those (highly
* useful) string routines has been published on Usenet.
*/
/*
* strcspn_ - find length of initial segment of s1 consisting entirely
* of characters not from s2
*/
static int
strcspn_(const char *s1, const char *s2)
{
char const *scan1;
char const *scan2;
int count;
count = 0;
for (scan1 = s1; *scan1 != '\0'; scan1++) {
for (scan2 = s2; *scan2 != '\0';) /* ++ moved down. */
if (*scan1 == *scan2++)
return(count);
count++;
}
return(count);
}
/*__Editor_settings____
Local Variables:
tab-width: 4
comment-column: 40
End:
vi: ts=4 sw=4
vim: si
_____________________*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -