static int regmatchsimplerepeat(regex_t *preg, int scan, int matchmin) { int nextch = '\0'; const char *save; int no; int c; int max = preg->program[scan + 2]; int min = preg->program[scan + 3]; int next = regnext(preg, scan); /* * Lookahead to avoid useless match attempts * when we know what character comes next. */ if (OP(preg, next) == EXACTLY) { nextch = preg->program[OPERAND(next)]; } save = preg->reginput; no = regrepeat(preg, scan + 5, max); if (no < min) { return 0; } if (matchmin) { /* from min up to no */ max = no; no = min; } /* else from no down to min */ while (1) { if (matchmin) { if (no > max) { break; } } else { if (no < min) { break; } } preg->reginput = save + utf8_index(save, no); reg_utf8_tounicode_case(preg->reginput, &c, (preg->cflags & REG_ICASE)); /* If it could work, try it. */ if (reg_iseol(preg, nextch) || c == nextch) { if (regmatch(preg, next)) { return(1); } } if (matchmin) { /* Couldn't or didn't, add one more */ no++; } else { /* Couldn't or didn't -- back up. */ no--; } } return(0); }
/* - regmatch - main matching routine * * Conceptually the strategy is simple: check to see whether the current * node matches, call self recursively to see whether the rest matches, * and then act accordingly. In practice we make some effort to avoid * recursion, in particular by going through "ordinary" nodes (that don't * need to know whether the rest of the match failed) by a loop instead of * by recursion. */ static int /* 0 failure, 1 success */ regmatch( char *prog ) { register char *scan; /* Current node. */ char *next; /* Next node. */ scan = prog; #ifdef DEBUG if (scan != NULL && regnarrate) fprintf(stderr, "%s(\n", regprop(scan)); #endif while (scan != NULL) { #ifdef DEBUG if (regnarrate) fprintf(stderr, "%s...\n", regprop(scan)); #endif next = regnext(scan); switch (OP(scan)) { case BOL: if (reginput != regbol) return(0); break; case EOL: if (*reginput != '\0') return(0); break; case WORDA: /* Must be looking at a letter, digit, or _ */ if ((!isalnum(*reginput)) && *reginput != '_') return(0); /* Prev must be BOL or nonword */ if (reginput > regbol && (isalnum(reginput[-1]) || reginput[-1] == '_')) return(0); break; case WORDZ: /* Must be looking at non letter, digit, or _ */ if (isalnum(*reginput) || *reginput == '_') return(0); /* We don't care what the previous char was */ break; case ANY: if (*reginput == '\0') return(0); reginput++; break; case EXACTLY: { register int len; register char *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) == NULL) return(0); reginput++; break; case ANYBUT: if (*reginput == '\0' || strchr(OPERAND(scan), *reginput) != NULL) 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: { register int no; register const char *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] == NULL) 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: { register int no; register const char *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] == NULL) regendp[no] = save; return(1); } else return(0); } break; case BRANCH: { register const char *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 != NULL && OP(scan) == BRANCH); return(0); /* NOTREACHED */ } } break; case STAR: case PLUS: { register char nextch; register int no; register const char *save; register 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 = reginput; no = regrepeat(OPERAND(scan)); while (no >= min) { /* 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: return(1); /* Success! */ break; default: regerror("memory corruption"); return(0); break; } scan = next; } /* * We get here only if there's trouble -- normally "case END" is * the terminating point. */ regerror("corrupted pointers"); return(0); }
int CRegExp::regmatch(TCHAR *prog) { TCHAR *scan; // Current node. TCHAR *next; // Next node. for (scan = prog; scan != NULL; scan = next) { next = regnext(scan); switch (OP(scan)) { case BOL: if (reginput != regbol) return(0); break; case EOL: if (*reginput != _T('\0')) return(0); break; case ANY: if (*reginput == _T('\0')) return(0); reginput++; break; case EXACTLY: { size_t len; TCHAR *const opnd = OPERAND(scan); // Inline the first character, for speed. if (*opnd != *reginput) return(0); len = _tcslen(opnd); if (len > 1 && _tcsncmp(opnd, reginput, len) != 0) return(0); reginput += len; break; } case ANYOF: if (*reginput == _T('\0') || _tcschr(OPERAND(scan), *reginput) == NULL) return(0); reginput++; break; case ANYBUT: if (*reginput == _T('\0') || _tcschr(OPERAND(scan), *reginput) != NULL) 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: { const int no = OP(scan) - OPEN; TCHAR *const input = reginput; if (regmatch(next)) { // Don't set startp if some later // invocation of the same parentheses // already has. if (startp[no] == NULL) startp[no] = input; 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: { const int no = OP(scan) - CLOSE; TCHAR *const input = reginput; if (regmatch(next)) { // Don't set endp if some later // invocation of the same parentheses // already has. if (endp[no] == NULL) endp[no] = input; return(1); } else return(0); break; } case BRANCH: { TCHAR *const save = reginput; if (OP(next) != BRANCH) // No choice. next = OPERAND(scan); // Avoid recursion. else { while (OP(scan) == BRANCH) { if (regmatch(OPERAND(scan))) return(1); reginput = save; scan = regnext(scan); } return(0); // NOTREACHED } break; } case STAR: case PLUS: { const TCHAR nextch = (OP(next) == EXACTLY) ? *OPERAND(next) : _T('\0'); size_t no; TCHAR *const save = reginput; const size_t min = (OP(scan) == STAR) ? 0 : 1; for (no = regrepeat(OPERAND(scan)) + 1; no > min; no--) { reginput = save + no - 1; // If it could work, try it. if (nextch == _T('\0') || *reginput == nextch) if (regmatch(next)) return(1); } return(0); break; } case END: return(1); // Success! break; default: TRACE0("regexp corruption\n"); return(0); break; } } // We get here only if there's trouble -- normally "case END" is // the terminating point. TRACE0("corrupted pointers\n"); return(0); }
/* - regmatch - main matching routine * * Conceptually the strategy is simple: check to see whether the current * node matches, call self recursively to see whether the rest matches, * and then act accordingly. In practice we make some effort to avoid * recursion, in particular by going through "ordinary" nodes (that don't * need to know whether the rest of the match failed) by a loop instead of * by recursion. * 0 failure, 1 success */ int ossimRegExp::regmatch (const char* prog) { const char* scan; // Current node. const char* next; // Next node. scan = prog; while (scan != NULL) { 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: { int len; const char* opnd; opnd = OPERAND(scan); // Inline the first character, for speed. if (*opnd != *reginput) return (0); len = (int)strlen(opnd); if (len > 1 && strncmp(opnd, reginput, len) != 0) return (0); reginput += len; } break; case ANYOF: if (*reginput == '\0' || strchr(OPERAND(scan), *reginput) == NULL) return (0); reginput++; break; case ANYBUT: if (*reginput == '\0' || strchr(OPERAND(scan), *reginput) != NULL) 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: { int no; const char* 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] == NULL) 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; const char* 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] == NULL) regendp[no] = save; return (1); } else return (0); } // break; case BRANCH: { const char* 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 != NULL && OP(scan) == BRANCH); return (0); // NOTREACHED } } break; case STAR: case PLUS: { char nextch; int no; const char* 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: return (1); // Success! default: //RAISE Error, SYM(ossimRegExp), SYM(Internal_Error), printf ("ossimRegExp::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(ossimRegExp), SYM(Internal_Error), printf ("ossimRegExp::find(): Internal error -- corrupted pointers.\n"); return (0); }
/* - regmatch - main matching routine * * Conceptually the strategy is simple: check to see whether the current * node matches, call self recursively to see whether the rest matches, * and then act accordingly. In practice we make some effort to avoid * recursion, in particular by going through "ordinary" nodes (that don't * need to know whether the rest of the match failed) by a loop instead of * by recursion. */ static int regmatch (char * prog) { register char *scan; /* Current node. */ char *nxt; /* nxt node. */ scan = prog; #ifdef DEBUG if (scan != (char *) NULL && regnarrate) debug_message("%s(\n", regprop(scan)); #endif while (scan != (char *) NULL) { #ifdef DEBUG if (regnarrate) debug_message("%s...\n", regprop(scan)); #endif nxt = 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 WORDSTART: if (reginput == regbol) break; if (*reginput == '\0' || ISWORDPART(*(reginput - 1)) || !ISWORDPART(*reginput)) return (0); break; case WORDEND: if (*reginput == '\0') break; if (reginput == regbol || !ISWORDPART(*(reginput - 1)) || ISWORDPART(*reginput)) return (0); break; case EXACTLY:{ register int len; register char *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) == (char *) NULL) return (0); reginput++; break; case ANYBUT: if (*reginput == '\0' || strchr(OPERAND(scan), *reginput) != (char *) NULL) 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:{ register int no; register const char *save; no = OP(scan) - OPEN; save = reginput; if (regmatch(nxt)) { /* * Don't set startp if some later invocation of the same * parentheses already has. */ if (regstartp[no] == (char *) NULL) 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:{ register int no; register const char *save; no = OP(scan) - CLOSE; save = reginput; if (regmatch(nxt)) { /* * Don't set endp if some later invocation of the same * parentheses already has. */ if (regendp[no] == (char *) NULL) regendp[no] = save; return (1); } else return (0); } break; case BRANCH:{ register const char *save; if (OP(nxt) != BRANCH) /* No choice. */ nxt = OPERAND(scan); /* Avoid recursion. */ else { do { save = reginput; if (regmatch(OPERAND(scan))) return (1); reginput = save; scan = regnext(scan); } while (scan != (char *) NULL && OP(scan) == BRANCH); return (0); /* NOTREACHED */ } } break; case STAR: case PLUS:{ register char nextch; register int no; register const char *save; register int minimum; /* * Lookahead to avoid useless match attempts when we know * what character comes next. */ nextch = '\0'; if (OP(nxt) == EXACTLY) nextch = *OPERAND(nxt); minimum = (OP(scan) == STAR) ? 0 : 1; save = reginput; no = regrepeat(OPERAND(scan)); while (no >= minimum) { /* If it could work, try it. */ if (nextch == '\0' || *reginput == nextch) if (regmatch(nxt)) return (1); /* Couldn't or didn't -- back up. */ no--; reginput = save + no; } return (0); } break; case END: return (1); /* Success! */ break; default: regerror("memory corruption\n"); return (0); break; } scan = nxt; } /* * We get here only if there's trouble -- normally "case END" is the * terminating point. */ regerror("corrupted pointers\n"); return (0); }
/* - regmatch - main matching routine * * Conceptually the strategy is simple: check to see whether the current * node matches, call self recursively to see whether the rest matches, * and then act accordingly. In practice we make some effort to avoid * recursion, in particular by going through "ordinary" nodes (that don't * need to know whether the rest of the match failed) by a loop instead of * by recursion. */ static int /* 0 failure, 1 success */ regmatch(char *prog) { register char *scan; /* Current node. */ char *next; /* Next node. */ wchar_t wc = L'\0'; int len; scan = prog; while (scan != NULL) { next = regnext(scan); switch (OP(scan)) { case BOL: if (reginput != regbol) return(0); break; case EOL: if (CHARLEN(reginput) != 0) return(0); break; case WORDA: /* Must be looking at a letter, digit, or _ */ len = mbtowc(&wc, reginput, MB_CUR_MAX); if (len == -1) wc = *reginput; if ((!iswalnum(wc)) && wc != L'_') return(0); /* Prev must be BOL or nonword */ len = mbtowc(&wc, reginput - reglmlen, MB_CUR_MAX); if (len == -1) { wc = *(reginput- reglmlen); len = 1; } if (reginput > regbol && (iswalnum(wc) || wc == L'_')) return(0); break; case WORDZ: len = mbtowc(&wc, reginput, MB_CUR_MAX); if (len == -1) { wc = *reginput; len = 1; } /* Must be looking at non letter, digit, or _ */ if (iswalnum(wc) || wc == L'_') return(0); /* We don't care what the previous char was */ break; case ANY: /* Solaris 2.6 Motif diff bug 1236359 - 1 line */ if ( (len = CHARLEN(reginput)) <= 0) return(0); reglmlen = len; reginput += INCRLEN(len); break; case EXACTLY: { register int len; register int clen; register char *opnd; register char *op, *ip; opnd = OPERAND(scan); len = strlen(opnd); for (clen = len, op = opnd, ip = reginput; clen; ) { int opl = CHARLEN(op), ipl = CHARLEN(ip); if (opl == ipl && !strncmp(op, ip, ipl)) { op += ipl; ip += ipl; clen -= ipl; reglmlen = ipl; } else break; } if (clen) return(0); reginput += len; } break; case ANYOF: /* Solaris 2.6 motif diff bug 1236359 - 1 line */ if ( ((len = CHARLEN(reginput)) <= 0) || !inclass(OPERAND(scan), reginput)) return 0; reginput += len; reglmlen = len; break; case ANYBUT: /* Solaris 2.6 motif diff bug 1236359 - 1 line */ if ( ((len = CHARLEN(reginput)) <= 0) || inclass(OPERAND(scan), reginput)) return 0; reginput += len; reglmlen = len; 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: { register int no; register char *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] == NULL) 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: { register int no; register char *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] == NULL) regendp[no] = save; return(1); } else return(0); } break; case BRANCH: { register char *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 != NULL && OP(scan) == BRANCH); return(0); /* NOTREACHED */ } } break; case STAR: case PLUS: { register char *nextch; register int no; register char *save; register int min; int nchars = 0; /* * 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 = reginput; no = regrepeat(OPERAND(scan)); while (no >= min) { /* Solaris 2.6 motif diff bug 1236359 - 1 line */ int mb_len = 0; /* If it could work, try it. */ if (!nextch || !(len = CHARLEN(nextch)) || !strncmp(reginput, nextch, len) ) if (regmatch(next)) return(1); /* Couldn't or didn't -- back up. */ no--; reginput = save; /* Solaris 2.6 motif diff bug 1236359 - 4 lines */ for (nchars = 0; nchars < no && mb_len >= 0; nchars++) { mb_len = CHARLEN(reginput); if (mb_len > 0) reginput += mb_len; } } return(0); } break; case END: return(1); /* Success! */ break; default: return(0); break; } scan = next; } /* * We get here only if there's trouble -- normally "case END" is * the terminating point. */ return(0); }
/* - regmatch - main matching routine * * Conceptually the strategy is simple: check to see whether the current * node matches, call self recursively to see whether the rest matches, * and then act accordingly. In practice we make some effort to avoid * recursion, in particular by going through "ordinary" nodes (that don't * need to know whether the rest of the match failed) by a loop instead of * by recursion. */ static int /* 0 failure, 1 success */ regmatch(char *prog) { register char *scan; /* Current node. */ char *next; /* Next node. */ extern char *strchr(); scan = prog; #ifdef DEBUG if (scan != NULL && regnarrate) { fprintf(stderr, "%s(\n", regprop(scan)); } #endif while (scan != NULL) { #ifdef DEBUG if (regnarrate) { fprintf(stderr, "%s...\n", regprop(scan)); } #endif next = regnext(scan); switch (OP(scan)) { case BOL: if (reginput != regbol) { return(0); } break; case EOL: if (regpeek(0) != '\0' && regpeek(0) != '\n') { return(0); } break; case BEGWORD: /* Match if current char isident * and previous char BOL or !ident */ if ((regpeek(0) == 0 || !isident(regpeek(0))) || (reginput != regbol && isident(regpeek(-1)))) { return(0); } break; case ENDWORD: /* Match if previous char isident * and current char EOL or !ident */ if ((regpeek(0) != 0 && isident(regpeek(0))) || reginput == regbol || !isident(regpeek(-1))) { return(0); } break; case WHITESP: /* match single whitespace */ if (regpeek(0) != 0 && !isspace(regpeek(0))) { return(0); } reginput++; break; case NWHITESP: /* don't match eol, or space or tab */ if (regpeek(0) == 0 || isspace(regpeek(0))) { return(0); } reginput++; break; case ALNUM: /* includes _ */ if (regpeek(0) == 0 || !isident(regpeek(0))) { return(0); } reginput++; break; case NALNUM: if (regpeek(0) == 0 || isident(regpeek(0))) { return(0); } reginput++; break; case DIGIT: if (regpeek(0) == 0 || !isdigit(regpeek(0))) { return(0); } reginput++; break; case NDIGIT: if (regpeek(0) == 0 || isdigit(regpeek(0))) { return(0); } reginput++; break; case PRINT: if (regpeek(0) == 0 || !(isprint(regpeek(0)) || isspace(regpeek(0)))) { return(0); } reginput++; break; case NPRINT: if (regpeek(0) == 0 || isprint(regpeek(0)) || isspace(regpeek(0))) { return(0); } reginput++; break; case ANY: if (regpeek(0) == '\0' || regpeek(0) == '\n') { return(0); } regseek(1); break; case EXACTLY: { register int len; register char *opnd; opnd = OPERAND(scan); /* Inline the first character, for speed. */ if (*opnd != regpeek(0)) { return(0); } len = strlen(opnd); if (len > 1 && strncmp(opnd, reginput, len) != 0) { return(0); } regseek(len); } break; case ANYOF: if (strchr(OPERAND(scan), regpeek(0)) == NULL) { return(0); } regseek(1); break; case ANYBUT: if (strchr(OPERAND(scan), regpeek(0)) != NULL) { return(0); } regseek(1); 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: { register int no; register char *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] == NULL) { 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: { register int no; register char *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] == NULL) { regendp[no] = save; } return(1); } else { return(0); } } break; case BRANCH: { register char *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 != NULL && OP(scan) == BRANCH); return(0); /* NOTREACHED */ } } break; case STAR: case PLUS: { register char nextch; register int no; register char *save; register 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 = reginput; no = regrepeat(OPERAND(scan)); while (no >= min) { /* If it could work, try it. */ if (nextch == '\0' || regpeek(0) == nextch) { if (regmatch(next)) { return(1); } } /* Couldn't or didn't -- back up. */ no--; reginput = save + no; } return(0); } break; case MINMAX: { register char *save; unsigned char min; unsigned char max; register int no; next = OPERAND(scan); min = OP(next); next = OPERAND(next); max = OP(next); next = OPERAND(next); save = reginput; for (no = 0 ; no < min ; no++) { if (!regmatch(next)) { reginput = save; return(0); } } for ( ; no < max ; no++) { if (!regmatch(next)) { break; } } return(1); } break; case END: return(1); /* Success! */ break; default: SREerror("memory corruption"); return(0); break; } scan = next; } /* * We get here only if there's trouble -- normally "case END" is * the terminating point. */ SREerror("corrupted pointers"); return(0); }