- // An empty pattern here matches only an empty string.
- if (p.empty())
- return s.empty();
-
- // Coalesce runs of consecutive stars. There should be at least
- // one.
- while (!p.empty() && (p[0] == '*'))
- p.remove_prefix(1);
-
- // Since we moved past the stars, an empty pattern here matches
- // anything.
- if (p.empty())
- return true;
-
- // Since we moved past the stars and p is non-empty, if some
- // non-empty substring of s matches p, then we ourselves match.
- while (!s.empty()) {
- if (MatchVlogPattern(s, p))
- return true;
- s.remove_prefix(1);
+bool MatchVlogPattern(base::StringPiece string,
+ base::StringPiece vlog_pattern) {
+ // The code implements the glob matching using a greedy approach described in
+ // https://research.swtch.com/glob.
+ size_t s = 0, nexts = 0;
+ size_t p = 0, nextp = 0;
+ size_t slen = string.size(), plen = vlog_pattern.size();
+ while (s < slen || p < plen) {
+ if (p < plen) {
+ switch (vlog_pattern[p]) {
+ // A slash (forward or back) must match a slash (forward or back).
+ case '/':
+ case '\\':
+ if (s < slen && (string[s] == '/' || string[s] == '\\')) {
+ p++, s++;
+ continue;
+ }
+ break;
+ // A '?' matches anything.
+ case '?':
+ if (s < slen) {
+ p++, s++;
+ continue;
+ }
+ break;
+ case '*':
+ nextp = p;
+ nexts = s + 1;
+ p++;
+ continue;
+ // Anything else must match literally.
+ default:
+ if (s < slen && string[s] == vlog_pattern[p]) {
+ p++, s++;
+ continue;
+ }
+ break;
+ }
+ }
+ // Mismatch - maybe restart.
+ if (0 < nexts && nexts <= slen) {
+ p = nextp;
+ s = nexts;
+ continue;
+ }
+ return false;