xref: /aosp_15_r20/external/abseil-cpp/absl/log/internal/fnmatch.cc (revision 9356374a3709195abf420251b3e825997ff56c0f)
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 Worker bool 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