/* - regtry - try match at specific point */ static int /* 0 failure, 1 success */ regtry( regexp *prog, const char *string ) { register int i; register const char **sp; register const char **ep; reginput = string; regstartp = prog->startp; regendp = prog->endp; sp = prog->startp; ep = prog->endp; for (i = NSUBEXP; i > 0; i--) { *sp++ = NULL; *ep++ = NULL; } if (regmatch(prog->program + 1)) { prog->startp[0] = string; prog->endp[0] = reginput; return(1); } else return(0); }
/* * regtry - try match at specific point */ static bool /* 0 failure, 1 success */ regtry(RE_EXP *prog, char *string) { register i4 i; register char **sp; register char **ep; reginput = string; regstartp = prog->startp; regendp = prog->endp; sp = prog->startp; ep = prog->endp; for (i = NSUBEXP; i > 0; i--) { *sp = NULL; # ifndef DOUBLEBYTE CMnext( *sp ); # else sp++; # endif /* #ifndef DOUBLEBYTE */ *ep = NULL; # ifndef DOUBLEBYTE CMnext( *ep ); # else ep++; # endif /* #ifndef DOUBLEBYTE */ } if (regmatch(prog->program + 1)) { prog->startp[0] = string; prog->endp[0] = reginput; return( TRUE ); } else return( FALSE ); }
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); }
std::string ezio::Regex::Match:: str(size_t n) const { // TODO: detect out-of-bounds? regmatch_t * regmatch(®match_[n-1]); return std::string(str_ + regmatch->rm_so, str_ + regmatch->rm_eo); }
static int regmatchrepeat(regex_t *preg, int scan, int matchmin) { int *scanpt = preg->program + scan; int max = scanpt[2]; int min = scanpt[3]; /* Have we reached min? */ if (scanpt[4] < min) { /* No, so get another one */ scanpt[4]++; if (regmatch(preg, scan + 5)) { return 1; } scanpt[4]--; return 0; } if (scanpt[4] > max) { return 0; } if (matchmin) { /* minimal, so try other branch first */ if (regmatch(preg, regnext(preg, scan))) { return 1; } /* No, so try one more */ scanpt[4]++; if (regmatch(preg, scan + 5)) { return 1; } scanpt[4]--; return 0; } /* maximal, so try this branch again */ if (scanpt[4] < max) { scanpt[4]++; if (regmatch(preg, scan + 5)) { return 1; } scanpt[4]--; } /* At this point we are at max with no match. Try the other branch */ return regmatch(preg, regnext(preg, scan)); }
bool regex_match(const string & str, smatch & matches, const regex & re){ Poco::RegularExpression::MatchVec pocomatches; auto ret = re.match( str, 0, pocomatches ); matches.clear(); for(const auto & m: pocomatches){ matches.push_back(regmatch(str,m)); } return ret; }
static int regmatch_sub_anytime(struct MatchingContext2 *c, Regex *regex, regexchar * pat2, char *str, char *end_p, int iter_limit, int firstp) { switch (c->label) { case 1: goto label1; case 2: goto label2; case 3: goto label3; } c->ctx = GC_malloc(sizeof(struct MatchingContext1)); c->ctx2 = GC_malloc(sizeof(struct MatchingContext2)); c->ctx->label = 0; c->regex = regex; c->n_any = 0; c->str = str; c->firstp = firstp; for (;;) { c->ctx->label = 0; while (regmatch_iter(c->ctx, c->regex->re, c->str, end_p, c->firstp)) { c->n_any = c->ctx->lastpos - c->str; if (c->n_any <= 0) continue; c->firstp = 0; if (RE_MODE(pat2) == RE_ENDMARK) { c->lastpos = c->str + c->n_any; YIELD(1, c, 1); } else if (regmatch(pat2, c->str + c->n_any, end_p, c->firstp, &c->lastpos) == 1) { YIELD(1, c, 2); } if (iter_limit == 1) continue; c->ctx2->label = 0; while (regmatch_sub_anytime(c->ctx2, regex, pat2, c->str + c->n_any, end_p, iter_limit - 1, c->firstp)) { c->lastpos = c->ctx2->lastpos; YIELD(1, c, 3); } } if (c->regex->alt_regex == NULL) break; c->regex = c->regex->alt_regex; } return 0; }
static int patmatch(struct grep_pat *p, char *line, char *eol, regmatch_t *match, int eflags) { int hit; if (p->fixed) hit = !fixmatch(p, line, eol, match); else if (p->pcre_regexp) hit = !pcrematch(p, line, eol, match, eflags); else hit = !regmatch(&p->regexp, line, eol, match, eflags); return hit; }
/* 0 failure, 1 success */ static int regtry( regex_t *preg, const char *string ) { int i; preg->reginput = string; for (i = 0; i < preg->nmatch; i++) { preg->pmatch[i].rm_so = -1; preg->pmatch[i].rm_eo = -1; } if (regmatch(preg, 1)) { preg->pmatch[0].rm_so = string - preg->start; preg->pmatch[0].rm_eo = preg->reginput - preg->start; return(1); } else return(0); }
string Validate(string file) { file=::Validate(file); // keine Unterverzeichnisse, gueltige Charnamen if (strstr(file,"/") == -1 && strlen(file) <= 11 // charnamen <=11 zeichen && (regmatch(file,"[a-zA-Z]+") == file // nur A-Z,a-z || strstr(file,"gast") == 0 // oder Gaeste ) ) { // Eigentlich P_COMPILER_PATH, aber hier geht jetzt auch __DIR__ return __DIR__ + file; } return 0; }
static int look_ahead(struct grep_opt *opt, unsigned long *left_p, unsigned *lno_p, char **bol_p) { unsigned lno = *lno_p; char *bol = *bol_p; struct grep_pat *p; char *sp, *last_bol; regoff_t earliest = -1; for (p = opt->pattern_list; p; p = p->next) { int hit; regmatch_t m; if (p->fixed) hit = !fixmatch(p, bol, bol + *left_p, &m); else hit = !regmatch(&p->regexp, bol, bol + *left_p, &m, 0); if (!hit || m.rm_so < 0 || m.rm_eo < 0) continue; if (earliest < 0 || m.rm_so < earliest) earliest = m.rm_so; } if (earliest < 0) { *bol_p = bol + *left_p; *left_p = 0; return 1; } for (sp = bol + earliest; bol < sp && sp[-1] != '\n'; sp--) ; /* find the beginning of the line */ last_bol = sp; for (sp = bol; sp < last_bol; sp++) { if (*sp == '\n') lno++; } *left_p -= last_bol - bol; *bol_p = last_bol; *lno_p = lno; return 0; }
/* - regtry - try match at specific point */ static int /* 0 failure, 1 success */ regtry(cst_regstate *state, const char *string, char *prog) { int i; const char **sp; const char **ep; state->input = string; sp = state->startp; ep = state->endp; for (i = CST_NSUBEXP; i > 0; i--) { *sp++ = NULL; *ep++ = NULL; } if (regmatch(state, prog)) { state->startp[0] = (char *)string; state->endp[0] = (char *)state->input; return(1); } else return(0); }
void travelers_requirement_celebration_do_speak(descriptor dxr) { if(Speech_Flag_Check(dxr, Speech_Flag_OOC)) return; object who = Speech_Query(dxr, Speech_Speaker); if(!who->query_intoxication()) return; string msg = Speech_Query(dxr, Speech_Original_Message); if(!regmatch("\\<[Gg][Aa][Nn][Ee][Ss][Hh][Aa]\\>", msg)) return; object env = environment(who); if(!env) return; int count = 0; for(object obj = first_inventory(env); obj; obj = next_inventory(obj)) if(obj != who && obj->is_character() && obj->sentience() && obj->sentience()->query_sentience_emotion() && obj->query_intoxication()) count++; if(count < 3) return; object challenge = Travelers_Find_Challenge(who); if(challenge->ganesha_challenge_query_taboo() == "speaking other than by shouting" && Speech_Query(dxr, Speech_Command) != Speech_Command_Shout) return; challenge->ganesha_challenge_overcome(); }
int CRegExp::regtry(TCHAR *string) { int i; TCHAR **stp; TCHAR **enp; reginput = string; stp = startp; enp = endp; for (i = NSUBEXP; i > 0; i--) { *stp++ = NULL; *enp++ = NULL; } if (regmatch(program)) { startp[0] = string; endp[0] = reginput; return(1); } else return(0); }
int RegexMatch(Regex *re, char *str, int len, int firstp) { char *p, *ep; char *lpos; Regex *r; if (str == NULL) return 0; if (len < 0) len = strlen(str); re->position = NULL; ep = str + len; for (p = str; p <= ep; p++) { lpos = NULL; re->lposition = NULL; for (r = re; r != NULL; r = r->alt_regex) { switch (regmatch(r->re, p, ep, firstp && (p == str), &lpos)) { case 1: /* matched */ re->position = p; if (re->lposition == NULL || re->lposition < lpos) re->lposition = lpos; break; case -1: /* error */ re->position = NULL; return -1; } } if (re->lposition != NULL) { /* matched */ return 1; } p += get_mclen(p) - 1; } return 0; }
/* - regtry - try match at specific point 0 failure, 1 success */ int ossimRegExp::regtry (const char* string, const char* *start, const char* *end, const char* prog) { int i; const char* *sp1; const char* *ep; reginput = string; regstartp = start; regendp = end; sp1 = start; ep = end; for (i = NSUBEXP; i > 0; i--) { *sp1++ = NULL; *ep++ = NULL; } if (regmatch(prog + 1)) { start[0] = string; end[0] = reginput; return (1); } else 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); }
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. */ 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); }
/* - 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); }
int regevaluate (struct Expr *expr, uchar *val, int amt) { struct Probe *base = (struct Probe *)((uchar *)expr + expr->size); struct Probe *probe, *stack, *clone; int idx, queue; // reset evaluator expr->val = val; expr->amt = amt; expr->top = 0; // if using new compiled node tree if( !expr->memo ) expr->memo = (uchar *)(expr + 1) + expr->tree; // calculate size of memo array in bits // by calculating number of nodes // and multiplying by source len idx = (expr->memo - (uchar *)(expr + 1)) / sizeof(struct Node); // convert number of bits to number of bytes // and clear memo array idx = (idx * (amt + 1) + 7) / 8; expr->tree = idx + (expr->memo - (uchar *)(expr + 1)); if( expr->tree + sizeof(struct Expr) > expr->size ) return 0; // out of memory else memset (expr->memo, 0, idx); // launch initial probe on root of parse tree if( probe = regprobe (expr) ) probe->node = (struct Node *)(expr + 1); else return 0; // out of memory queue = base - probe; // evaluate input string against parse tree // until a probe reaches both the end of the // parse tree and the end of the input string while( idx = queue ) { probe = base - idx; queue = probe->next; // continue our node down to a // pattern match node. while( ++expr->steps ) { // if maximum occurrences reached // move to sibling node // if no sibling, either return // success if done, or kill probe if( probe->occurrence == probe->node->maximum ) if( regnext (expr, probe) ) continue; else if( probe->off == expr->amt ) return 1; else break; // if another probe began evaluation // of this node at this offset before, // abandon our probe. idx = probe->node - (struct Node *)(expr + 1); idx *= amt + 1; idx += probe->off; if( ++probe->occurrence > probe->node->minimum ) if( expr->memo[idx/8] & (1 << (idx % 8)) ) break; else expr->memo[idx/8] |= 1 << (idx % 8); // if minimum requirement met // clone another probe to continue // with alternate if( probe->occurrence > probe->node->minimum ) if( clone = regclone (expr, probe) ) { clone->occurrence = clone->node->maximum; clone->next = queue; queue = base - clone; } else return 0; // out of memory // descend probe into subexpressions if( probe->node->typelen <= 0 ) { // make a stack node // to remember parent if( stack = regprobe (expr) ) stack->next = probe->stack; else return 0; // out of memory stack->occurrence = probe->occurrence; stack->off = probe->off; probe->node = probe->node->type->child; probe->stack = base - stack; probe->occurrence = 0; continue; } // advance to next input character, // or kill probe if no pattern match, if( regmatch (expr, probe) ) probe->off++; else break; } // delete our probe and continue // with next queued clone regkill (expr, probe); } // when run queue is exhausted, // delete all probes and return failure return 0; }
static int regmatch_iter(struct MatchingContext1 *c, regexchar * re, char *str, char *end_p, int firstp) { switch (c->label) { case 1: goto label1; case 2: goto label2; case 3: goto label3; case 4: goto label4; case 5: goto label5; case 6: goto label6; case 7: goto label7; } if (RE_MODE(re) == RE_ENDMARK) return 0; c->re = re; c->firstp = firstp; c->str = str; c->end_p = end_p; c->sub_ctx = NULL; c->lastpos = NULL; while (RE_MODE(c->re) != RE_ENDMARK) { if (c->re->mode & (RE_ANYTIME | RE_OPT)) { if (c->re->mode & RE_ANYTIME) c->iter_limit = RE_ITER_LIMIT; else c->iter_limit = 1; c->n_any = -1; while (c->n_any < c->iter_limit) { if (c->str + c->n_any >= c->end_p) { return 0; } if (c->n_any >= 0) { if (RE_MODE(c->re) == RE_SUBREGEX) { c->ctx2 = GC_malloc(sizeof(struct MatchingContext2)); c->ctx2->label = 0; while (regmatch_sub_anytime(c->ctx2, c->re->p.sub, c->re + 1, c->str + c->n_any, c->end_p, c->iter_limit, c->firstp)) { c->n_any = c->ctx2->lastpos - c->str; c->lastpos = c->ctx2->lastpos; YIELD(1, c, 1); } return 0; } else { longchar k; k = set_longchar(c->str + c->n_any); if (regmatch1(c->re, &k)) { c->n_any += get_mclen(c->str + c->n_any); } else { return 0; } c->firstp = 0; } } else c->n_any++; if (RE_MODE(c->re + 1) == RE_ENDMARK) { c->lastpos = c->str + c->n_any; YIELD(1, c, 2); } else if (regmatch(c->re + 1, c->str + c->n_any, c->end_p, c->firstp, &c->lastpos) == 1) { YIELD(1, c, 3); } } return 0; } /* regexp other than pat*, pat+ and pat? */ switch (RE_MODE(c->re)) { case RE_BEGIN: if (!c->firstp) return 0; c->re++; break; case RE_END: if (c->str >= c->end_p) { c->lastpos = c->str; c->re++; YIELD(1, c, 4); } else { c->lastpos = NULL; return 0; } break; case RE_SUBREGEX: if (c->sub_ctx == NULL) { c->sub_ctx = GC_malloc(sizeof(struct MatchingContext1)); } c->sub_regex = c->re->p.sub; for (;;) { c->sub_ctx->label = 0; while (regmatch_iter(c->sub_ctx, c->sub_regex->re, c->str, c->end_p, c->firstp)) { if (c->sub_ctx->lastpos != c->str) c->firstp = 0; if (RE_MODE(c->re + 1) == RE_ENDMARK) { c->lastpos = c->sub_ctx->lastpos; YIELD(1, c, 5); } else if (regmatch(c->re + 1, c->sub_ctx->lastpos, c->end_p, c->firstp, &c->lastpos) == 1) { YIELD(1, c, 6); } } if (c->sub_regex->alt_regex == NULL) break; c->sub_regex = c->sub_regex->alt_regex; } return 0; default: { longchar k; k = set_longchar(c->str); c->str += get_mclen(c->str); if (!regmatch1(c->re, &k)) return 0; } c->re++; c->firstp = 0; } if (c->str > c->end_p) { return 0; } } c->lastpos = c->str; #ifdef REGEX_DEBUG if (verbose) printf("Succeed: %s %d\n", c->str, c->lastpos - c->str); #endif YIELD(1, c, 7); 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); }
/* * Parser for command line options * See getopt(3)... */ int parseopt(int argc, char **argv) { char c; // Command line options and default values int dport = 0, // destination port xport = 1025, // first source port yport = 65534, // last source port time = 10000, // sleep time alarm = 40, // alarm time window = 5840, // tcp window size frag = 0, // fragment offset fragc = 1, // fragment counter syn = 0, // syn flooding only ack = 0, // send acknowledgment packets fin = 0, // send finalize packets rst = 0, // send reset packets mlt = 0, // multistage payload loop = 0, // infinite loop ipver = 0, // ip version verbose = 1; // verbosity char dstaddr[MIN_ARG], // destination address *srcaddr = NULL, // source address *device = NULL, // network interface *firewall = NULL, // firewall rule *payload = NULL, // payload file *mpayload = NULL; // multistage payload file struct addrinfo hints, *res=NULL; void *addr=NULL; int single = 1; // cleaning dstaddr[0] = '\0'; memset(&progopt, 0, sizeof(struct options)); memset(&hints, 0, sizeof(hints)); // short options for getopt() char shortopt[] = "d:p:x:y:ls:i:t:a:f:v:L:W:O:C:P:M:"; // getopt() loop while ((c = getopt (argc, argv, shortopt)) != -1) switch (c) { case 'd': // Destination // ip address if(regmatch(optarg, reg_ipv4_addr)) { strncpy(dstaddr, optarg, MIN_ARG-1); single = 1; } // dns name else if(getaddrinfo(optarg, NULL, &hints, &res) == 0) { if (res->ai_family == AF_INET) { // IPv4 struct sockaddr_in *ipv4 = (struct sockaddr_in *) res->ai_addr; addr = &(ipv4->sin_addr); ipver=VER_IPV4; } else if (res->ai_family == AF_INET6) { // IPv6 struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)res->ai_addr; addr = &(ipv6->sin6_addr); ipver=VER_IPV6; } // convert the IP to a string inet_ntop(res->ai_family, addr, dstaddr, MIN_ARG-1); single=1; freeaddrinfo(res); } else { usage(stderr, "\nArgument -d is invalid.\n"); } break; case 'p': // Port if(!regmatch(optarg, reg_number)) usage(stderr, "\nArgument -p is invalid.\n"); dport = atoi(optarg); // check value if(dport < 1 || dport > 65355) usage(stderr, "\nArgument -p is invalid.\n"); break; case 'x': // First source port if(!regmatch(optarg, reg_number)) usage(stderr, "\nArgument -x is invalid.\n"); xport = atoi(optarg); // check value if(xport < 1 || xport > 65355) usage(stderr, "\nArgument -x is invalid.\n"); break; case 'y': // Last source port if(!regmatch(optarg, reg_number)) usage(stderr, "\nArgument -y is invalid.\n"); yport = atoi(optarg); // check value if(yport < 1 || yport > 65355) usage(stderr, "\nArgument -y is invalid.\n"); break; case 'l': // Infinite loop loop = 1; break; case 's': // Source address if(!regmatch(optarg, reg_ipv4_addr)) usage(stderr, "\nArgument -s is invalid.\n"); srcaddr = optarg; break; case 'i': // Interface device = optarg; break; case 't': // Sleep time if(!regmatch(optarg, reg_number)) usage(stderr, "\nArgument -t is invalid.\n"); time = atoi(optarg); break; case 'a': // Alarm time if(!regmatch(optarg, reg_number)) usage(stderr, "\nArgument -a is invalid.\n"); alarm = atoi(optarg); break; case 'f': // Firewall rule firewall = optarg; break; case 'v': // Verbosity level if(!regmatch(optarg, reg_number)) usage(stderr, "\nArgument -v is invalid.\n"); verbose = atoi(optarg); break; case 'L': // Level of interaction // rst (include ack) if(strstr(optarg, "r")) { ack = 1; rst = 1; } // fin (include ack) else if(strstr(optarg, "f")) { ack = 1; fin = 1; } // ack (polite mode) else if(strstr(optarg, "a")) { ack = 1; } // syn flood else if(strstr(optarg, "s")) { syn = 1; } else { usage(stderr, "\nArgument -L is invalid.\n"); } break; case 'W': // Window size if(!regmatch(optarg, reg_number)) usage(stderr, "\nArgument -W is invalid.\n"); window = atoi(optarg); break; case 'O': // Fragment offset if(!regmatch(optarg, reg_number)) usage(stderr, "\nArgument -O is invalid.\n"); frag = atoi(optarg); break; case 'C': // Fragment counter if(!regmatch(optarg, reg_number)) usage(stderr, "\nArgument -C is invalid.\n"); fragc = atoi(optarg); break; case 'P': // Payload payload = optarg; break; case 'M': // Multistage payload mpayload = optarg; mlt = 1; break; case '?': default: usage(stderr, NULL); } //check collected args and fill options struct if(dstaddr[0]=='\0' || dport<1) usage(stderr, NULL); else { strncpy(progopt.dstaddr, dstaddr, MIN_ARG-1); progopt.dport=dport; } if(srcaddr) strncpy(progopt.srcaddr, srcaddr, MIN_ARG-1); if(time<0) time = 0; if(alarm<0) alarm = 0; if(xport>yport) usage(stderr, "\nAre you ok? Check -x and -y please ;)\n"); if(verbose<0) verbose = 0; if(firewall) { if(!strcmp("iptables", firewall)) { strncpy(progopt.firewall[0], IPTABLES_ENABLE, MAX_ARG-1); strncpy(progopt.firewall[1], IPTABLES_DISABLE, MAX_ARG-1); } else if(!strcmp("blackhole", firewall)) { strncpy(progopt.firewall[0], BLACKHOLE_ENABLE, MAX_ARG-1); strncpy(progopt.firewall[1], BLACKHOLE_DISABLE, MAX_ARG-1); } else usage(stderr, "\nI don't know this firewall\n"); } // TODO Check ipversion progopt.xport=xport; progopt.yport=yport; progopt.loop=loop; progopt.time=time; progopt.alarm=alarm; progopt.window=window; progopt.frag=frag; progopt.fragc=fragc; progopt.syn=syn; progopt.ack=ack; progopt.fin=fin; progopt.rst=rst; progopt.mlt=mlt; progopt.verbose=verbose; if(device) strncpy(progopt.device, device, MIN_ARG-1); if(payload) getpayload(payload); if(mpayload) { strncpy(progopt.mlt_payload, mpayload, MAX_ARG-1); progopt.ack = 1; } return 1; }
static int match_one_pattern(struct grep_pat *p, char *bol, char *eol, enum grep_context ctx, regmatch_t *pmatch, int eflags) { int hit = 0; int saved_ch = 0; const char *start = bol; if ((p->token != GREP_PATTERN) && ((p->token == GREP_PATTERN_HEAD) != (ctx == GREP_CONTEXT_HEAD))) return 0; if (p->token == GREP_PATTERN_HEAD) { const char *field; size_t len; assert(p->field < ARRAY_SIZE(header_field)); field = header_field[p->field].field; len = header_field[p->field].len; if (strncmp(bol, field, len)) return 0; bol += len; saved_ch = strip_timestamp(bol, &eol); } again: if (p->fixed) hit = !fixmatch(p, bol, eol, pmatch); else hit = !regmatch(&p->regexp, bol, eol, pmatch, eflags); if (hit && p->word_regexp) { if ((pmatch[0].rm_so < 0) || (eol - bol) < pmatch[0].rm_so || (pmatch[0].rm_eo < 0) || (eol - bol) < pmatch[0].rm_eo) die("regexp returned nonsense"); /* Match beginning must be either beginning of the * line, or at word boundary (i.e. the last char must * not be a word char). Similarly, match end must be * either end of the line, or at word boundary * (i.e. the next char must not be a word char). */ if ( ((pmatch[0].rm_so == 0) || !word_char(bol[pmatch[0].rm_so-1])) && ((pmatch[0].rm_eo == (eol-bol)) || !word_char(bol[pmatch[0].rm_eo])) ) ; else hit = 0; /* Words consist of at least one character. */ if (pmatch->rm_so == pmatch->rm_eo) hit = 0; if (!hit && pmatch[0].rm_so + bol + 1 < eol) { /* There could be more than one match on the * line, and the first match might not be * strict word match. But later ones could be! * Forward to the next possible start, i.e. the * next position following a non-word char. */ bol = pmatch[0].rm_so + bol + 1; while (word_char(bol[-1]) && bol < eol) bol++; eflags |= REG_NOTBOL; if (bol < eol) goto again; } } if (p->token == GREP_PATTERN_HEAD && saved_ch) *eol = saved_ch; if (hit) { pmatch[0].rm_so += bol - start; pmatch[0].rm_eo += bol - start; } return hit; }
/* - 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); }
/* 0 failure, 1 success */ static int regmatch(regex_t *preg, int prog) { int scan; /* Current node. */ int next; /* Next node. */ const char *save; scan = prog; #ifdef DEBUG if (scan != 0 && regnarrate) fprintf(stderr, "%s(\n", regprop(scan)); #endif while (scan != 0) { int n; int c; #ifdef DEBUG if (regnarrate) { fprintf(stderr, "%3d: %s...\n", scan, regprop(OP(preg, scan))); /* Where, what. */ } #endif next = regnext(preg, scan); n = reg_utf8_tounicode_case(preg->reginput, &c, (preg->cflags & REG_ICASE)); switch (OP(preg, scan)) { case BOL: if (preg->reginput != preg->regbol) return(0); break; case EOL: if (!reg_iseol(preg, c)) { return(0); } break; case WORDA: /* Must be looking at a letter, digit, or _ */ if ((!isalnum(UCHAR(c))) && c != '_') return(0); /* Prev must be BOL or nonword */ if (preg->reginput > preg->regbol && (isalnum(UCHAR(preg->reginput[-1])) || preg->reginput[-1] == '_')) return(0); break; case WORDZ: /* Can't match at BOL */ if (preg->reginput > preg->regbol) { /* Current must be EOL or nonword */ if (reg_iseol(preg, c) || !isalnum(UCHAR(c)) || c != '_') { c = preg->reginput[-1]; /* Previous must be word */ if (isalnum(UCHAR(c)) || c == '_') { break; } } } /* No */ return(0); case ANY: if (reg_iseol(preg, c)) return 0; preg->reginput += n; break; case EXACTLY: { int opnd; int len; int slen; opnd = OPERAND(scan); len = str_int_len(preg->program + opnd); slen = prefix_cmp(preg->program + opnd, len, preg->reginput, preg->cflags & REG_ICASE); if (slen < 0) { return(0); } preg->reginput += slen; } break; case ANYOF: if (reg_iseol(preg, c) || reg_range_find(preg->program + OPERAND(scan), c) == 0) { return(0); } preg->reginput += n; break; case ANYBUT: if (reg_iseol(preg, c) || reg_range_find(preg->program + OPERAND(scan), c) != 0) { return(0); } preg->reginput += n; break; case NOTHING: break; case BACK: break; case BRANCH: if (OP(preg, next) != BRANCH) /* No choice. */ next = OPERAND(scan); /* Avoid recursion. */ else { do { save = preg->reginput; if (regmatch(preg, OPERAND(scan))) { return(1); } preg->reginput = save; scan = regnext(preg, scan); } while (scan != 0 && OP(preg, scan) == BRANCH); return(0); /* NOTREACHED */ } break; case REP: case REPMIN: return regmatchsimplerepeat(preg, scan, OP(preg, scan) == REPMIN); case REPX: case REPXMIN: return regmatchrepeat(preg, scan, OP(preg, scan) == REPXMIN); case END: return 1; /* Success! */ case OPENNC: case CLOSENC: return regmatch(preg, next); default: if (OP(preg, scan) >= OPEN+1 && OP(preg, scan) < CLOSE_END) { save = preg->reginput; if (regmatch(preg, next)) { if (OP(preg, scan) < CLOSE) { int no = OP(preg, scan) - OPEN; if (no < preg->nmatch && preg->pmatch[no].rm_so == -1) { preg->pmatch[no].rm_so = save - preg->start; } } else { int no = OP(preg, scan) - CLOSE; if (no < preg->nmatch && preg->pmatch[no].rm_eo == -1) { preg->pmatch[no].rm_eo = save - preg->start; } } return(1); } return(0); } return REG_ERR_INTERNAL; } scan = next; } /* * We get here only if there's trouble -- normally "case END" is * the terminating point. */ return REG_ERR_INTERNAL; }