static bool match(const char *pattern, size_t patlen, const char *s, bool match_case, bool complete_match) { if (match_case) { for ( ; *pattern && patlen > 0 ; pattern++, s++, patlen--) { if (!*s) return false ; if (*pattern != MATCH_SINGLE && *pattern != *s) return false ; } } else { for ( ; *pattern && patlen > 0 ; pattern++, s++, patlen--) { if (!*s) return false ; if (*pattern != MATCH_SINGLE && Fr_toupper(*pattern) != Fr_toupper(*s)) return false ; } } return (complete_match ? (!*s) : true) ; }
int Fr_stricmp(const char *s1, const char *s2) { int diff = 0 ; while ((diff = (Fr_toupper(*s1) - Fr_toupper(*s2))) == 0 && *s1 && *s2) { s1++ ; s2++ ; } return diff ; }
static int Fr_memicmp(const char *s1, const char *s2, size_t len) { int diff = 0 ; while (len > 0 && (diff = (Fr_toupper(*s1) - Fr_toupper(*s2))) == 0) { len-- ; s1++ ; s2++ ; } return diff ; }
int Fr_wcsicmp(const FrChar16 *s1, const char *s2) { int diff = 0 ; while ((diff = (Fr_towupper(FrByteSwap16(*s1)) - (FrChar16)Fr_toupper(*s2))) == 0 && *s1) { s1++ ; s2++ ; } return diff ; }
int Fr_wcsnicmp(const FrChar16 *s1, const char *s2, size_t N) { if (N == 0) return 0 ; int diff = 0 ; while (--N > 0 && (diff = (Fr_towupper(FrByteSwap16(*s1)) - (FrChar16)Fr_toupper(*s2))) == 0 && *s1) { s1++ ; s2++ ; } return diff ; }
static const char *re_match(const FrRegExElt *re, const char *candidate, size_t min_reps, size_t &max_reps, char *&match, const char *matchbuf_end, char **groups, size_t num_groups) { assertq(re != 0 && match != 0 && matchbuf_end != 0) ; switch (re->reType()) { case FrRegExElt::End: // match end of word if (*candidate) { max_reps = 0 ; // uh oh, not at end of word.... return 0 ; } else { max_reps = 1 ; return candidate ; } case FrRegExElt::Char: { char c = Fr_toupper(re->getChar()) ; size_t i ; for (i = 0 ; i < max_reps ; i++) { if (Fr_toupper(*candidate) != c) break ; if (match < matchbuf_end) *match++ = *candidate ; candidate++ ; } max_reps = i ; if (i >= min_reps ) return candidate ; else return 0 ; } case FrRegExElt::CharSet: { const char *set = re->getCharSet() ; if (!set) { max_reps = 0 ; return 0 ; } size_t i ; for (i = 0 ; i < max_reps && *candidate ; i++) { if (!set[*(unsigned char*)candidate]) break ; if (match < matchbuf_end) *match++ = *candidate ; candidate++ ; } max_reps = i ; if (i >= min_reps) return candidate ; else return 0 ; } case FrRegExElt::String: { const char *string = re->getString() ; size_t len = re->stringLength() ; if (!string) { max_reps = 0 ; return 0 ; } size_t i ; for (i = 0 ; i < max_reps ; i++) { if (Fr_memicmp(candidate,string,len) != 0) break ; const char *tstr = string+len+1 ; size_t tlen = strlen(tstr) ; if (match+tlen < matchbuf_end) { memcpy(match,tstr,tlen) ; match += tlen ; } candidate += len ; } max_reps = i ; if (i >= min_reps) return candidate ; else return 0 ; } case FrRegExElt::Alt: { FrRegExElt **alts = re->getAlternatives() ; char *matchbuf = match ; const char *end = re_match_alt(alts,candidate,min_reps,max_reps, match,matchbuf_end,groups,num_groups) ; if (max_reps >= min_reps) { int group_num = re->groupNumber() ; if (end && group_num >= 0 && group_num < (int)num_groups) { // since the r.e. compiler ensures that only alternations can // be used for grouping, we can get away with only recording // groupings right here *match = '\0' ; FrFree(groups[group_num]) ; groups[group_num] = FrDupString(matchbuf) ; } return end ; } else return 0 ; } case FrRegExElt::Class: { const char *end = re_match_class(re,candidate,min_reps,max_reps, match,matchbuf_end,groups, num_groups) ; return (max_reps >= min_reps) ? end : 0 ; } case FrRegExElt::Accept: return strchr(candidate,'\0') ; default: max_reps = 0 ; FrMissedCase("re_match") ; return 0 ; } }