static bool MatchName(char *theName,char *thePattern,UINT32 *patternIndex,bool *haveMatch) // match theName against thePattern // thePattern points to the start of a pattern terminated with a '\0', or a PATHSEP // update patternIndex to point to the character that stopped the match // if a match occurs, return true if have match // if there is a problem SetError, and return false { UINT32 nameIndex; UINT32 startPatternIndex; bool fail, done, matching; char theChar; fail=*haveMatch=done=false; matching=true; nameIndex=0; while(!done&&matching) { switch(thePattern[*patternIndex]) { case '\0': // ran out of characters of the pattern case PATHSEP: matching=(theName[nameIndex]=='\0'); done=true; break; case '*': (*patternIndex)++; // move past the * matching=false; do { startPatternIndex=*patternIndex; fail=!MatchName(&theName[nameIndex],thePattern,&startPatternIndex,&matching); } while(theName[nameIndex++]&&!fail&&!matching); // recurse trying to make a match if(matching) { *patternIndex=startPatternIndex; done=true; } break; case '?': (*patternIndex)++; matching=(theName[nameIndex++]!='\0'); break; case '[': (*patternIndex)++; if((theChar=theName[nameIndex++])) { fail=!MatchRange(theChar,thePattern,patternIndex,&matching); } else { matching=false; } break; case '\\': (*patternIndex)++; if((theChar=thePattern[(*patternIndex)++])) { matching=(theName[nameIndex++]==theChar); } else { SetError(localErrorFamily,errorMembers[DANGLINGQUOTE],errorDescriptions[DANGLINGQUOTE]); fail=true; } break; default: matching=(theName[nameIndex++]==thePattern[(*patternIndex)++]); break; } } if(!fail) { *haveMatch=matching; } return(!fail); }
int RegExpMatch::MatchOne(RegExpContext &context, const char *str) { if (MatchRange(context, str)) return 0; if (*str && IsSet(*str)) return 1; if (IsSet(M_MATCH)) { if (matchRange < context.matchCount) { int n = context.matchOffsets[matchRange][1] - context.matchOffsets[matchRange][0]; if (context.caseSensitive) { if (!strncmp(str, context.beginning + context.matchOffsets[matchRange][0], n)) return n; } else { bool matches = true; const char *p = context.beginning + context.matchOffsets[matchRange][0]; const char *q = str; for (int i=0; i < n && matches; i++) if (toupper(*p++) != toupper(*q++)) matches = false; if (matches) return n; } } } if (IsSet(RE_M_WORD)) { if (IsSet(wordChars, *str) && !IsSet(wordChars, str[-1])) { return 0; } if (!IsSet(wordChars, *str) && IsSet(wordChars, str[-1])) { return 0; } } if (IsSet(RE_M_IWORD)) { if (IsSet(wordChars, *str)) if (IsSet(wordChars, str[-1])) if (IsSet(wordChars, str[1])) return 0; } if (IsSet(RE_M_BWORD)) { if (IsSet(wordChars, *str)) if (!IsSet(wordChars, str[-1])) { return 0; } } if (IsSet(RE_M_EWORD)) { if (!IsSet(wordChars, *str)) if (IsSet(wordChars, str[-1])) { return 0; } } if (IsSet(RE_M_WORDCHAR)) { if (IsSet(wordChars, *str)) { return 1; } } if (IsSet(RE_M_NONWORDCHAR)) { if (!IsSet(wordChars, *str)) { return 1; } } if (IsSet(RE_M_BBUFFER)) if (str == context.beginning) return 0; if (IsSet(RE_M_EBUFFER)) if (!*str) return 0; if (IsSet(RE_M_SOL)) { if (str == context.beginning) return 0; if (str[-1] == '\n') return 0; } if (IsSet(RE_M_EOL)) { if (*str == '\n' || !*str) return 0; } return -1; }