26 string::const_iterator pi;
27 pi = _pattern.begin();
28 while (pi != _pattern.end()) {
37 if (pi == _pattern.end()) {
58 while (p < _pattern.size()) {
59 switch (_pattern[p]) {
63 return prefix + _pattern.substr(q, p - q);
67 prefix += _pattern.substr(q, p - q);
73 return prefix += _pattern.substr(q, p - q);
91 string prefix, pattern, suffix;
93 string source = _pattern;
94 if (!source.empty() && source[0] ==
'/') {
97 source = source.substr(1);
100 size_t slash = source.find(
'/');
101 if (slash == string::npos) {
104 pattern = source.substr(0, slash);
105 suffix = source.substr(slash);
110 return glob.r_match_files(prefix, suffix, results, cwd);
117 r_match_files(
const Filename &prefix,
const string &suffix,
118 vector_string &results,
const Filename &cwd) {
119 string next_pattern, next_suffix;
121 size_t slash = suffix.find(
'/');
122 if (slash == string::npos) {
123 next_pattern = suffix;
124 }
else if (slash + 1 == suffix.size()) {
127 next_pattern = suffix.substr(0, slash);
130 next_pattern = suffix.substr(0, slash);
131 next_suffix = suffix.substr(slash + 1);
134 if (_pattern ==
"**" && next_pattern ==
"**") {
136 return r_match_files(prefix, next_suffix, results, cwd);
140 if (prefix.
is_local() && !cwd.empty()) {
147 next_glob.set_case_sensitive(_case_sensitive);
153 if (suffix.empty()) {
156 results.push_back(
Filename(prefix, _pattern));
160 }
else if (fn.is_directory()) {
163 results.push_back(
Filename(prefix, _pattern +
"/"));
166 return next_glob.r_match_files(
Filename(prefix, _pattern),
167 next_suffix, results, cwd);
175 vector_string dir_files;
186 if (_pattern ==
"**") {
188 if (suffix.empty()) {
190 results.push_back(
Filename(prefix));
192 }
else if (suffix ==
"/") {
194 results.push_back(
Filename(prefix,
""));
197 num_matched += next_glob.r_match_files(prefix, next_suffix, results, cwd);
199 next_suffix = suffix;
203 for (
const string &local_file : dir_files) {
204 if (_pattern[0] ==
'.' || (local_file.empty() || local_file[0] !=
'.')) {
208 if (suffix.empty() && _pattern !=
"**") {
209 results.push_back(
Filename(prefix, local_file));
211 }
else if (suffix ==
"/" && _pattern !=
"**") {
212 results.push_back(
Filename(prefix, local_file +
"/"));
215 num_matched += next_glob.r_match_files(
Filename(prefix, local_file),
216 next_suffix, results, cwd);
218 }
else if (suffix.empty()) {
219 results.push_back(
Filename(prefix, local_file));
237 if (_pattern.empty()) {
239 return candidate.empty();
243 if ((_pattern[0] !=
'/') != candidate.
is_local()) {
247 return r_matches_file(_pattern, candidate);
254 r_matches_file(
const string &pattern,
const Filename &candidate)
const {
256 std::string next_pattern;
262 size_t slash = pattern.find(
'/');
263 if (slash == string::npos) {
268 next_pattern = pattern.substr(slash + 1);
271 if (slash == 0 || (slash == 1 && pattern[0] ==
'.')) {
273 return r_matches_file(next_pattern, candidate);
282 size_t fn_slash = ((
const std::string &)candidate).find(
'/');
283 if (fn_slash == string::npos) {
285 candidate_end =
true;
287 part = candidate.substr(0, fn_slash);
288 next_candidate = candidate.substr(fn_slash + 1);
289 candidate_end =
false;
292 if (fn_slash == 0 || part ==
".") {
293 return r_matches_file(pattern, next_candidate);
307 return r_matches_file(next_pattern, candidate)
308 || (!candidate_end && r_matches_file(next_pattern, next_candidate))
309 || (!candidate_end && r_matches_file(pattern, next_candidate));
311 else if (glob.
get_pattern() ==
"*" && _nomatch_chars.empty()) {
315 else if ((glob.
get_pattern() ==
"." && part.empty())
321 part_matches = glob.
matches(part);
327 part_matches = (cmp_nocase(part, glob.
get_pattern()) == 0);
335 if (candidate_end && pattern_end) {
340 if (pattern_end != candidate_end) {
346 return r_matches_file(next_pattern, next_candidate);
355 matches_substr(string::const_iterator pi, string::const_iterator pend,
356 string::const_iterator ci, string::const_iterator cend)
const {
359 if (pi == pend || ci == cend) {
362 if ((ci == cend) && (std::distance(pi, pend) == 1) && (*pi) ==
'*') {
365 return (pi == pend && ci == cend);
375 if (_nomatch_chars.find(*ci) == string::npos) {
377 matches_substr(pi, pend, ci + 1, cend) ||
378 matches_substr(pi + 1, pend, ci, cend);
382 return matches_substr(pi + 1, pend, ci, cend);
388 return matches_substr(pi + 1, pend, ci + 1, cend);
395 if (matches_set(pi, pend, *ci)) {
399 if (!matches_set(pi, pend, *ci)) {
407 return matches_substr(pi + 1, pend, ci + 1, cend);
419 if (_case_sensitive) {
420 if ((*pi) != (*ci)) {
424 if (tolower(*pi) != tolower(*ci)) {
428 return matches_substr(pi + 1, pend, ci + 1, cend);
441 matches_set(string::const_iterator &pi, string::const_iterator pend,
443 bool matched =
false;
445 while (pi != pend && (*pi) !=
']') {
461 if (pi != pend && (*pi) ==
'-') {
463 if (pi != pend && (*pi) !=
']') {
477 if ((ch >= start && ch <= end) ||
479 ((tolower(ch) >= start && tolower(ch) <= end) ||
480 (toupper(ch) >= start && toupper(ch) <= end)))) {
set_pattern
Changes the pattern string that the GlobPattern object matches.
set_case_sensitive
Sets whether the match is case sensitive (true) or case insensitive (false).
set_nomatch_chars
Specifies a set of characters that are not matched by * or ?.
bool has_glob_characters() const
Returns true if the pattern includes any special globbing characters, or false if it is just a litera...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
bool matches(const std::string &candidate) const
Returns true if the candidate string matches the pattern, false otherwise.
get_case_sensitive
Returns whether the match is case sensitive (true) or case insensitive (false).
The name of a file, such as a texture file or an Egg file.
std::string get_const_prefix() const
Returns the initial part of the pattern before the first glob character.
bool matches_file(Filename candidate) const
Treats the GlobPattern as a filename pattern, and returns true if the given filename matches the patt...
int match_files(vector_string &results, const Filename &cwd=Filename()) const
Treats the GlobPattern as a filename pattern, and returns a list of any actual files that match the p...
bool is_local() const
Returns true if the filename is local, e.g.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
get_pattern
Returns the pattern string that the GlobPattern object matches.
bool is_directory() const
Returns true if the filename exists and is a directory name, false otherwise.
bool scan_directory(vector_string &contents) const
Attempts to open the named filename as if it were a directory and looks for the non-hidden files with...
This class can be used to test for string matches against standard Unix- shell filename globbing conv...