1*9356374aSAndroid Build Coastguard Worker // Copyright 2023 The Abseil Authors 2*9356374aSAndroid Build Coastguard Worker // 3*9356374aSAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License"); 4*9356374aSAndroid Build Coastguard Worker // you may not use this file except in compliance with the License. 5*9356374aSAndroid Build Coastguard Worker // You may obtain a copy of the License at 6*9356374aSAndroid Build Coastguard Worker // 7*9356374aSAndroid Build Coastguard Worker // https://www.apache.org/licenses/LICENSE-2.0 8*9356374aSAndroid Build Coastguard Worker // 9*9356374aSAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software 10*9356374aSAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS, 11*9356374aSAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*9356374aSAndroid Build Coastguard Worker // See the License for the specific language governing permissions and 13*9356374aSAndroid Build Coastguard Worker // limitations under the License. 14*9356374aSAndroid Build Coastguard Worker 15*9356374aSAndroid Build Coastguard Worker #include "absl/log/internal/fnmatch.h" 16*9356374aSAndroid Build Coastguard Worker 17*9356374aSAndroid Build Coastguard Worker #include <cstddef> 18*9356374aSAndroid Build Coastguard Worker 19*9356374aSAndroid Build Coastguard Worker #include "absl/base/config.h" 20*9356374aSAndroid Build Coastguard Worker #include "absl/strings/string_view.h" 21*9356374aSAndroid Build Coastguard Worker 22*9356374aSAndroid Build Coastguard Worker namespace absl { 23*9356374aSAndroid Build Coastguard Worker ABSL_NAMESPACE_BEGIN 24*9356374aSAndroid Build Coastguard Worker namespace log_internal { FNMatch(absl::string_view pattern,absl::string_view str)25*9356374aSAndroid Build Coastguard Workerbool FNMatch(absl::string_view pattern, absl::string_view str) { 26*9356374aSAndroid Build Coastguard Worker bool in_wildcard_match = false; 27*9356374aSAndroid Build Coastguard Worker while (true) { 28*9356374aSAndroid Build Coastguard Worker if (pattern.empty()) { 29*9356374aSAndroid Build Coastguard Worker // `pattern` is exhausted; succeed if all of `str` was consumed matching 30*9356374aSAndroid Build Coastguard Worker // it. 31*9356374aSAndroid Build Coastguard Worker return in_wildcard_match || str.empty(); 32*9356374aSAndroid Build Coastguard Worker } 33*9356374aSAndroid Build Coastguard Worker if (str.empty()) { 34*9356374aSAndroid Build Coastguard Worker // `str` is exhausted; succeed if `pattern` is empty or all '*'s. 35*9356374aSAndroid Build Coastguard Worker return pattern.find_first_not_of('*') == pattern.npos; 36*9356374aSAndroid Build Coastguard Worker } 37*9356374aSAndroid Build Coastguard Worker switch (pattern.front()) { 38*9356374aSAndroid Build Coastguard Worker case '*': 39*9356374aSAndroid Build Coastguard Worker pattern.remove_prefix(1); 40*9356374aSAndroid Build Coastguard Worker in_wildcard_match = true; 41*9356374aSAndroid Build Coastguard Worker break; 42*9356374aSAndroid Build Coastguard Worker case '?': 43*9356374aSAndroid Build Coastguard Worker pattern.remove_prefix(1); 44*9356374aSAndroid Build Coastguard Worker str.remove_prefix(1); 45*9356374aSAndroid Build Coastguard Worker break; 46*9356374aSAndroid Build Coastguard Worker default: 47*9356374aSAndroid Build Coastguard Worker if (in_wildcard_match) { 48*9356374aSAndroid Build Coastguard Worker absl::string_view fixed_portion = pattern; 49*9356374aSAndroid Build Coastguard Worker const size_t end = fixed_portion.find_first_of("*?"); 50*9356374aSAndroid Build Coastguard Worker if (end != fixed_portion.npos) { 51*9356374aSAndroid Build Coastguard Worker fixed_portion = fixed_portion.substr(0, end); 52*9356374aSAndroid Build Coastguard Worker } 53*9356374aSAndroid Build Coastguard Worker const size_t match = str.find(fixed_portion); 54*9356374aSAndroid Build Coastguard Worker if (match == str.npos) { 55*9356374aSAndroid Build Coastguard Worker return false; 56*9356374aSAndroid Build Coastguard Worker } 57*9356374aSAndroid Build Coastguard Worker pattern.remove_prefix(fixed_portion.size()); 58*9356374aSAndroid Build Coastguard Worker str.remove_prefix(match + fixed_portion.size()); 59*9356374aSAndroid Build Coastguard Worker in_wildcard_match = false; 60*9356374aSAndroid Build Coastguard Worker } else { 61*9356374aSAndroid Build Coastguard Worker if (pattern.front() != str.front()) { 62*9356374aSAndroid Build Coastguard Worker return false; 63*9356374aSAndroid Build Coastguard Worker } 64*9356374aSAndroid Build Coastguard Worker pattern.remove_prefix(1); 65*9356374aSAndroid Build Coastguard Worker str.remove_prefix(1); 66*9356374aSAndroid Build Coastguard Worker } 67*9356374aSAndroid Build Coastguard Worker break; 68*9356374aSAndroid Build Coastguard Worker } 69*9356374aSAndroid Build Coastguard Worker } 70*9356374aSAndroid Build Coastguard Worker } 71*9356374aSAndroid Build Coastguard Worker } // namespace log_internal 72*9356374aSAndroid Build Coastguard Worker ABSL_NAMESPACE_END 73*9356374aSAndroid Build Coastguard Worker } // namespace absl 74