| 200 | } |
| 201 | |
| 202 | bool ModuleResourceContainer::Matches(const std::string& name, const std::string& filePattern) |
| 203 | { |
| 204 | // short-cut |
| 205 | if (filePattern == "*") return true; |
| 206 | |
| 207 | std::vector<std::string> tokens; |
| 208 | { |
| 209 | std::stringstream ss(filePattern); |
| 210 | std::string tok; |
| 211 | while (std::getline(ss, tok, '*')) |
| 212 | { |
| 213 | tokens.push_back(tok); |
| 214 | } |
| 215 | } |
| 216 | |
| 217 | if (tokens.empty()) return true; |
| 218 | |
| 219 | const bool startsWithWild = !filePattern.empty() && filePattern[0] == '*'; |
| 220 | const bool endsWithWild = !filePattern.empty() && filePattern[filePattern.size()-1] == '*'; |
| 221 | |
| 222 | // Locate the last non-empty token. Empty tokens result from consecutive |
| 223 | // '*' characters and act like a single wildcard. |
| 224 | std::size_t lastNonEmpty = tokens.size(); |
| 225 | while (lastNonEmpty > 0 && tokens[lastNonEmpty - 1].empty()) |
| 226 | { |
| 227 | --lastNonEmpty; |
| 228 | } |
| 229 | if (lastNonEmpty == 0) return true; // pattern is all wildcards |
| 230 | |
| 231 | std::size_t pos = 0; |
| 232 | for (std::size_t i = 0; i < lastNonEmpty; ++i) |
| 233 | { |
| 234 | const std::string& tok = tokens[i]; |
| 235 | if (tok.empty()) continue; |
| 236 | |
| 237 | const bool isFirstAnchored = (i == 0) && !startsWithWild; |
| 238 | const bool isLastAnchored = (i == lastNonEmpty - 1) && !endsWithWild; |
| 239 | |
| 240 | if (isFirstAnchored && isLastAnchored) |
| 241 | { |
| 242 | // Pattern has no wildcards: name must equal the token exactly. |
| 243 | if (name.size() != tok.size() || name.compare(0, tok.size(), tok) != 0) return false; |
| 244 | pos = name.size(); |
| 245 | } |
| 246 | else if (isFirstAnchored) |
| 247 | { |
| 248 | if (tok.size() > name.size() || name.compare(0, tok.size(), tok) != 0) return false; |
| 249 | pos = tok.size(); |
| 250 | } |
| 251 | else if (isLastAnchored) |
| 252 | { |
| 253 | // Anchor the final literal segment to the end of name. |
| 254 | if (tok.size() > name.size() - pos) return false; |
| 255 | const std::size_t expected = name.size() - tok.size(); |
| 256 | if (name.compare(expected, tok.size(), tok) != 0) return false; |
| 257 | pos = name.size(); |
| 258 | } |
| 259 | else |