Returns true if and only if regex matches a prefix of str. regex must be a valid simple regular expression and not start with "^", or the result is undefined.
| 10676 | // be a valid simple regular expression and not start with "^", or the |
| 10677 | // result is undefined. |
| 10678 | bool MatchRegexAtHead(const char* regex, const char* str) { |
| 10679 | if (*regex == '\0') // An empty regex matches a prefix of anything. |
| 10680 | return true; |
| 10681 | |
| 10682 | // "$" only matches the end of a string. Note that regex being |
| 10683 | // valid guarantees that there's nothing after "$" in it. |
| 10684 | if (*regex == '$') |
| 10685 | return *str == '\0'; |
| 10686 | |
| 10687 | // Is the first thing in regex an escape sequence? |
| 10688 | const bool escaped = *regex == '\\'; |
| 10689 | if (escaped) |
| 10690 | ++regex; |
| 10691 | if (IsRepeat(regex[1])) { |
| 10692 | // MatchRepetitionAndRegexAtHead() calls MatchRegexAtHead(), so |
| 10693 | // here's an indirect recursion. It terminates as the regex gets |
| 10694 | // shorter in each recursion. |
| 10695 | return MatchRepetitionAndRegexAtHead( |
| 10696 | escaped, regex[0], regex[1], regex + 2, str); |
| 10697 | } else { |
| 10698 | // regex isn't empty, isn't "$", and doesn't start with a |
| 10699 | // repetition. We match the first atom of regex with the first |
| 10700 | // character of str and recurse. |
| 10701 | return (*str != '\0') && AtomMatchesChar(escaped, *regex, *str) && |
| 10702 | MatchRegexAtHead(regex + 1, str + 1); |
| 10703 | } |
| 10704 | } |
| 10705 | |
| 10706 | // Returns true if and only if regex matches any substring of str. regex must |
| 10707 | // be a valid simple regular expression, or the result is undefined. |
no test coverage detected