Unravel Engine C++ Reference
Loading...
Searching...
No Matches
pattern_filter.cpp
Go to the documentation of this file.
1#include "pattern_filter.h"
2#include <algorithm>
3
4namespace fs
5{
6
7wildcard_pattern::wildcard_pattern(const std::string& pattern)
8 : pattern_(pattern)
9{
10}
11
12auto wildcard_pattern::matches(const std::string& str) const -> bool
13{
14 return match_impl(pattern_.c_str(), str.c_str());
15}
16
17auto wildcard_pattern::match_impl(const char* pattern, const char* str) const -> bool
18{
19 // Handle empty pattern
20 if (*pattern == '\0')
21 {
22 return *str == '\0';
23 }
24
25 // Handle '*' wildcard
26 if (*pattern == '*')
27 {
28 // Skip consecutive '*' characters
29 while (*pattern == '*')
30 {
31 ++pattern;
32 }
33
34 // If pattern ends with '*', it matches everything remaining
35 if (*pattern == '\0')
36 {
37 return true;
38 }
39
40 // Try matching '*' with empty string, or with one or more characters
41 while (*str != '\0')
42 {
43 if (match_impl(pattern, str))
44 {
45 return true;
46 }
47 ++str;
48 }
49
50 // Try matching '*' with empty string at end
51 return match_impl(pattern, str);
52 }
53
54 // Handle '?' wildcard (matches exactly one character)
55 if (*pattern == '?' && *str != '\0')
56 {
57 return match_impl(pattern + 1, str + 1);
58 }
59
60 // Handle regular character matching
61 if (*pattern == *str)
62 {
63 return match_impl(pattern + 1, str + 1);
64 }
65
66 // No match
67 return false;
68}
69
70pattern_filter::pattern_filter(const std::string& include_pattern)
71{
72 if (!include_pattern.empty())
73 {
74 add_include_pattern(include_pattern);
75 }
76}
77
78pattern_filter::pattern_filter(const std::vector<std::string>& include_patterns,
79 const std::vector<std::string>& exclude_patterns)
80{
81 for (const auto& pattern : include_patterns)
82 {
83 add_include_pattern(pattern);
84 }
85 for (const auto& pattern : exclude_patterns)
86 {
87 add_exclude_pattern(pattern);
88 }
89}
90
91void pattern_filter::add_include_pattern(const std::string& pattern)
92{
93 if (!pattern.empty())
94 {
95 include_patterns_.emplace_back(pattern);
96 }
97}
98
99void pattern_filter::add_exclude_pattern(const std::string& pattern)
100{
101 if (!pattern.empty())
102 {
103 exclude_patterns_.emplace_back(pattern);
104 }
105}
106
107auto pattern_filter::should_include(const fs::path& path) const -> bool
108{
109 return should_include_filename(path.filename().string());
110}
111
112auto pattern_filter::should_include_filename(const std::string& filename) const -> bool
113{
114 // First check exclude patterns - if any match, exclude the file
115 for (const auto& exclude_pattern : exclude_patterns_)
116 {
117 if (exclude_pattern.matches(filename))
118 {
119 return false;
120 }
121 }
122
123 // If no include patterns are specified, include everything (that wasn't excluded)
124 if (include_patterns_.empty())
125 {
126 return true;
127 }
128
129 // Check include patterns - if any match, include the file
130 for (const auto& include_pattern : include_patterns_)
131 {
132 if (include_pattern.matches(filename))
133 {
134 return true;
135 }
136 }
137
138 // No include patterns matched
139 return false;
140}
141
143{
144 return !include_patterns_.empty() || !exclude_patterns_.empty();
145}
146
147auto pattern_filter::is_wildcard() const -> bool
148{
149 // Consider it a wildcard if:
150 // 1. No patterns at all
151 // 2. Single include pattern that is "*" and no exclude patterns
152 if (!has_patterns())
153 {
154 return true;
155 }
156
157 if (include_patterns_.size() == 1 && exclude_patterns_.empty())
158 {
159 return include_patterns_[0].get_pattern() == "*";
160 }
161
162 return false;
163}
164
166{
167 return include_patterns_;
168}
169
171{
172 return exclude_patterns_;
173}
174
175auto make_pattern_filter(const std::string& pattern) -> pattern_filter
176{
177 return pattern_filter(pattern);
178}
179
180auto make_pattern_filter(const std::vector<std::string>& includes,
181 const std::vector<std::string>& excludes) -> pattern_filter
182{
183 return pattern_filter(includes, excludes);
184}
185
186} // namespace fs
A filter that combines include and exclude patterns for file/directory filtering.
pattern_filter()=default
Default constructor creates a filter that accepts everything.
auto has_patterns() const -> bool
Checks if this filter has any patterns.
void add_exclude_pattern(const std::string &pattern)
Adds an exclude pattern to the filter.
auto get_include_patterns() const -> const std::vector< wildcard_pattern > &
Gets all include patterns.
auto get_exclude_patterns() const -> const std::vector< wildcard_pattern > &
Gets all exclude patterns.
auto should_include_filename(const std::string &filename) const -> bool
Tests if a filename should be included based on the filter rules.
void add_include_pattern(const std::string &pattern)
Adds an include pattern to the filter.
auto should_include(const fs::path &path) const -> bool
Tests if a path should be included based on the filter rules Logic: (matches any include pattern OR n...
auto is_wildcard() const -> bool
Checks if this filter is effectively a wildcard (no restrictions)
A wildcard pattern matcher that supports * (match any sequence) and ? (match single character)
wildcard_pattern(const std::string &pattern)
Constructs a wildcard pattern from a string.
auto matches(const std::string &str) const -> bool
Tests if the given string matches this pattern.
Definition cache.hpp:11
auto make_pattern_filter(const std::string &pattern) -> pattern_filter
Convenience function to create a pattern filter from a single wildcard string Maintains backward comp...