Returns true iff regex matches a prefix of str. regex must be a valid simple regular expression and not start with "^", or the result is undefined.
| 9386 | // valid simple regular expression and not start with "^", or the |
| 9387 | // result is undefined. |
| 9388 | bool MatchRegexAtHead(const char* regex, const char* str) { |
| 9389 | if (*regex == '\0') // An empty regex matches a prefix of anything. |
| 9390 | return true; |
| 9391 | |
| 9392 | // "$" only matches the end of a string. Note that regex being |
| 9393 | // valid guarantees that there's nothing after "$" in it. |
| 9394 | if (*regex == '$') |
| 9395 | return *str == '\0'; |
| 9396 | |
| 9397 | // Is the first thing in regex an escape sequence? |
| 9398 | const bool escaped = *regex == '\\'; |
| 9399 | if (escaped) |
| 9400 | ++regex; |
| 9401 | if (IsRepeat(regex[1])) { |
| 9402 | // MatchRepetitionAndRegexAtHead() calls MatchRegexAtHead(), so |
| 9403 | // here's an indirect recursion. It terminates as the regex gets |
| 9404 | // shorter in each recursion. |
| 9405 | return MatchRepetitionAndRegexAtHead( |
| 9406 | escaped, regex[0], regex[1], regex + 2, str); |
| 9407 | } else { |
| 9408 | // regex isn't empty, isn't "$", and doesn't start with a |
| 9409 | // repetition. We match the first atom of regex with the first |
| 9410 | // character of str and recurse. |
| 9411 | return (*str != '\0') && AtomMatchesChar(escaped, *regex, *str) && |
| 9412 | MatchRegexAtHead(regex + 1, str + 1); |
| 9413 | } |
| 9414 | } |
| 9415 | |
| 9416 | // Returns true iff regex matches any substring of str. regex must be |
| 9417 | // a valid simple regular expression, or the result is undefined. |
no test coverage detected