| 72 | } |
| 73 | |
| 74 | std::string Glob::PatternToRegex(std::string const& pattern, |
| 75 | bool require_whole_string, bool preserve_case) |
| 76 | { |
| 77 | // Incrementally build the regular expression from the pattern. |
| 78 | std::string regex = require_whole_string ? "^" : ""; |
| 79 | std::string::const_iterator pattern_first = pattern.begin(); |
| 80 | std::string::const_iterator pattern_last = pattern.end(); |
| 81 | for (std::string::const_iterator i = pattern_first; i != pattern_last; ++i) { |
| 82 | int c = *i; |
| 83 | if (c == '*') { |
| 84 | // A '*' (not between brackets) matches any string. |
| 85 | // We modify this to not match slashes since the original glob |
| 86 | // pattern documentation was meant for matching file name |
| 87 | // components separated by slashes. |
| 88 | regex += "[^/]*"; |
| 89 | } else if (c == '?') { |
| 90 | // A '?' (not between brackets) matches any single character. |
| 91 | // We modify this to not match slashes since the original glob |
| 92 | // pattern documentation was meant for matching file name |
| 93 | // components separated by slashes. |
| 94 | regex += "[^/]"; |
| 95 | } else if (c == '[') { |
| 96 | // Parse out the bracket expression. It begins just after the |
| 97 | // opening character. |
| 98 | std::string::const_iterator bracket_first = i + 1; |
| 99 | std::string::const_iterator bracket_last = bracket_first; |
| 100 | |
| 101 | // The first character may be complementation '!' or '^'. |
| 102 | if (bracket_last != pattern_last && |
| 103 | (*bracket_last == '!' || *bracket_last == '^')) { |
| 104 | ++bracket_last; |
| 105 | } |
| 106 | |
| 107 | // If the next character is a ']' it is included in the brackets |
| 108 | // because the bracket string may not be empty. |
| 109 | if (bracket_last != pattern_last && *bracket_last == ']') { |
| 110 | ++bracket_last; |
| 111 | } |
| 112 | |
| 113 | // Search for the closing ']'. |
| 114 | while (bracket_last != pattern_last && *bracket_last != ']') { |
| 115 | ++bracket_last; |
| 116 | } |
| 117 | |
| 118 | // Check whether we have a complete bracket string. |
| 119 | if (bracket_last == pattern_last) { |
| 120 | // The bracket string did not end, so it was opened simply by |
| 121 | // a '[' that is supposed to be matched literally. |
| 122 | regex += "\\["; |
| 123 | } else { |
| 124 | // Convert the bracket string to its regex equivalent. |
| 125 | std::string::const_iterator k = bracket_first; |
| 126 | |
| 127 | // Open the regex block. |
| 128 | regex += "["; |
| 129 | |
| 130 | // A regex range complement uses '^' instead of '!'. |
| 131 | if (k != bracket_last && *k == '!') { |
no test coverage detected