int PROC amatch(char *pattern, char *start, char *endp) { int sarg = arg; /* save old arg match count for errors */ while (*pattern) { if (*pattern == CLOSURE) { /* Find the longest closure possible and work backwards trying * to match the rest of the pattern. */ char *oldstart = start; ++pattern; /* skip over the closure token */ while (start <= endp && omatch(pattern,&start,endp)) ; /* start points at the character that failed the search. * Try to match the rest of the pattern against it, working * back down the line if failure */ patsize(&pattern); while (start >= oldstart) if (amatch(pattern,start--,endp)) return TRUE; arg = sarg; return FALSE; } else { if (!omatch(pattern,&start,endp)) { arg = sarg; return FALSE; } patsize(&pattern); } } lastp = start-core; return TRUE; }
/*----------------------------------------------------------------------*/ const tchar * patcmp( const tchar * str, const pattern * pat, const tchar * start) { /* * Like strcmp, but compares str against pat. Each element of str is * compared with the template until either a mis-match is found or the end * of the template is reached. In the former case a 0 is returned; in the * latter, a pointer into str (pointing to the last character in the * matched pattern) is returned. Strstart points at the first character in * the string, which might not be the same thing as line if the search * started in the middle of the string. */ const tchar * bocl; /* beginning of closure string. */ const tchar * end=0; /* return value: end-of-string pointer. */ if (!pat) /* make sure pattern is valid */ return (NULL); while (*pat) { if (*pat == (pattern)M_OPT) { /* * Zero or one matches. It doesn't matter if omatch fails---it will * advance str past the character on success, though. Always advance * the pattern past both the M_OPT and the operand. */ omatch(&str, ++pat, start); ADVANCE(pat); } else if (!(*pat == (pattern)M_CLOSE || *pat == (pattern)M_PCLOSE)) { /* * Do a simple match. Note that omatch() fails if there's still * something in pat but we're at end of string. */ if (!omatch(&str, pat, start)) return NULL; ADVANCE(pat); } else { /* Process a Kleene or positive closure */ if (*pat++ == (pattern)M_PCLOSE) /* one match required */ if (!omatch(&str, pat, start)) return NULL; /* Match as many as possible, zero is okay */ bocl = str; while (*str && omatch(&str, pat, start)) { /* do nothing */ } /* * 'str' now points to the character that made made us fail. Try to * process the rest of the string. If the character following the * closure could have been in the closure (as in the pattern "[a-z]*t") * the final 't' will be sucked up in the while loop. So, if the match * fails, back up a notch and try to match the rest of the string * again, repeating this process recursively until we get back to the * beginning of the closure. The recursion goes, at most, one levels * deep. */ if (*ADVANCE(pat)) { for (; bocl <= str; --str) { end = patcmp(str, pat, start); if (end) break; } return end; } break; } } /* * omatch() advances str to point at the next character to be matched. So * str points at the character following the last character matched when * you reach the end of the template. The exceptions are templates * containing only a BOLN or EOLN token. In these cases omatch doesn't * advance. Since we must return a pointer to the last matched character, * decrement str to make it point at the end of the matched string, making * sure that the decrement hasn't gone past the beginning of the string. * * Note that $ is a position, not a character, but in the case of a pattern * ^$, a pointer to the end of line character is returned. In ^xyz$, a * pointer to the z is returned. * * The --str is done outside the return statement because __max() was a macro * with side-effects. */ --str; return (std::max(start, str)); }
virtual int omatch(const char* s, int si, int sn, Rxpart* res) const { return omatch(s, si, sn); }