| // Copyright 2019 The Fuchsia Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| #include "src/developer/debug/zxdb/expr/identifier_glob.h" | |
| #include "src/developer/debug/zxdb/expr/expr_parser.h" | |
| namespace zxdb { | |
| namespace { | |
| // Matches the template parameters of one component. Return value is the same as | |
| // IdentifierGlob::Matches. | |
| std::optional<int> MatchTemplateParams(const std::vector<std::string>& glob, | |
| const std::vector<std::string>& type) { | |
| if (type.size() < glob.size()) | |
| return std::nullopt; // Glob trying to match more parameters than the type has. | |
| int last_score = 0; | |
| for (size_t i = 0; i < glob.size(); i++) { | |
| if (glob[i] == "*") { | |
| if (i == glob.size() - 1) { | |
| // Last glob "*" matches all remaining type parameters. | |
| last_score = static_cast<int>(type.size()) - i; | |
| break; | |
| } else { | |
| last_score = 1; | |
| } | |
| } else { | |
| // Non-wildcards must be an exact match. | |
| if (glob[i] != type[i]) | |
| return std::nullopt; | |
| // Last glob template was not a whilecard, and there are still more type params to match. | |
| if (i == glob.size() - 1 && type.size() > glob.size()) | |
| return std::nullopt; | |
| } | |
| } | |
| return last_score; | |
| } | |
| } // namespace | |
| Err IdentifierGlob::Init(const std::string& glob) { | |
| return ExprParser::ParseIdentifier(glob, &parsed_); | |
| } | |
| std::optional<int> IdentifierGlob::Matches(const ParsedIdentifier& type) const { | |
| if (type.components().size() != parsed_.components().size()) | |
| return std::nullopt; | |
| int max_component_score = 0; | |
| for (size_t i = 0; i < type.components().size(); i++) { | |
| // The name must match exactly. | |
| if (parsed_.components()[i].name() != type.components()[i].name() || | |
| parsed_.components()[i].has_template() != type.components()[i].has_template()) | |
| return std::nullopt; | |
| if (parsed_.components()[i].has_template()) { | |
| // Check template parameters. | |
| if (auto score = MatchTemplateParams(parsed_.components()[i].template_contents(), | |
| type.components()[i].template_contents())) { | |
| // Want the largest score. | |
| if (*score > max_component_score) | |
| max_component_score = *score; | |
| } else { | |
| return std::nullopt; // Template params don't match. | |
| } | |
| } | |
| } | |
| return max_component_score; | |
| } | |
| } // namespace zxdb |