|
30 | 30 |
|
31 | 31 | namespace llvm {
|
32 | 32 |
|
33 |
| -Error SpecialCaseList::Matcher::insert(StringRef Pattern, unsigned LineNumber, |
34 |
| - bool UseGlobs) { |
| 33 | +Error SpecialCaseList::RegexMatcher::insert(StringRef Pattern, |
| 34 | + unsigned LineNumber) { |
35 | 35 | if (Pattern.empty())
|
36 | 36 | return createStringError(errc::invalid_argument,
|
37 |
| - Twine("Supplied ") + |
38 |
| - (UseGlobs ? "glob" : "regex") + " was blank"); |
39 |
| - |
40 |
| - if (!UseGlobs) { |
41 |
| - // Replace * with .* |
42 |
| - auto Regexp = Pattern.str(); |
43 |
| - for (size_t pos = 0; (pos = Regexp.find('*', pos)) != std::string::npos; |
44 |
| - pos += strlen(".*")) { |
45 |
| - Regexp.replace(pos, strlen("*"), ".*"); |
46 |
| - } |
| 37 | + "Supplied regex was blank"); |
| 38 | + |
| 39 | + // Replace * with .* |
| 40 | + auto Regexp = Pattern.str(); |
| 41 | + for (size_t pos = 0; (pos = Regexp.find('*', pos)) != std::string::npos; |
| 42 | + pos += strlen(".*")) { |
| 43 | + Regexp.replace(pos, strlen("*"), ".*"); |
| 44 | + } |
47 | 45 |
|
48 |
| - Regexp = (Twine("^(") + StringRef(Regexp) + ")$").str(); |
| 46 | + Regexp = (Twine("^(") + StringRef(Regexp) + ")$").str(); |
49 | 47 |
|
50 |
| - // Check that the regexp is valid. |
51 |
| - Regex CheckRE(Regexp); |
52 |
| - std::string REError; |
53 |
| - if (!CheckRE.isValid(REError)) |
54 |
| - return createStringError(errc::invalid_argument, REError); |
| 48 | + // Check that the regexp is valid. |
| 49 | + Regex CheckRE(Regexp); |
| 50 | + std::string REError; |
| 51 | + if (!CheckRE.isValid(REError)) |
| 52 | + return createStringError(errc::invalid_argument, REError); |
55 | 53 |
|
56 |
| - auto Rg = |
57 |
| - std::make_unique<Matcher::Reg>(Pattern, LineNumber, std::move(CheckRE)); |
58 |
| - RegExes.emplace_back(std::move(Rg)); |
| 54 | + auto Rg = std::make_unique<Reg>(Pattern, LineNumber, std::move(CheckRE)); |
| 55 | + RegExes.emplace_back(std::move(Rg)); |
59 | 56 |
|
60 |
| - return Error::success(); |
61 |
| - } |
| 57 | + return Error::success(); |
| 58 | +} |
| 59 | + |
| 60 | +void SpecialCaseList::RegexMatcher::match( |
| 61 | + StringRef Query, |
| 62 | + llvm::function_ref<void(StringRef Rule, unsigned LineNo)> Cb) const { |
| 63 | + for (const auto &Regex : reverse(RegExes)) |
| 64 | + if (Regex->Rg.match(Query)) |
| 65 | + Cb(Regex->Name, Regex->LineNo); |
| 66 | +} |
| 67 | + |
| 68 | +Error SpecialCaseList::GlobMatcher::insert(StringRef Pattern, |
| 69 | + unsigned LineNumber) { |
| 70 | + if (Pattern.empty()) |
| 71 | + return createStringError(errc::invalid_argument, "Supplied glob was blank"); |
62 | 72 |
|
63 |
| - auto Glob = std::make_unique<Matcher::Glob>(Pattern, LineNumber); |
| 73 | + auto G = std::make_unique<Glob>(Pattern, LineNumber); |
64 | 74 | // We must be sure to use the string in `Glob` rather than the provided
|
65 | 75 | // reference which could be destroyed before match() is called
|
66 |
| - if (auto Err = GlobPattern::create(Glob->Name, /*MaxSubPatterns=*/1024) |
67 |
| - .moveInto(Glob->Pattern)) |
| 76 | + if (auto Err = GlobPattern::create(G->Name, /*MaxSubPatterns=*/1024) |
| 77 | + .moveInto(G->Pattern)) |
68 | 78 | return Err;
|
69 |
| - Globs.push_back(std::move(Glob)); |
| 79 | + Globs.emplace_back(std::move(G)); |
70 | 80 | return Error::success();
|
71 | 81 | }
|
72 | 82 |
|
73 |
| -void SpecialCaseList::Matcher::match( |
| 83 | +void SpecialCaseList::GlobMatcher::match( |
74 | 84 | StringRef Query,
|
75 | 85 | llvm::function_ref<void(StringRef Rule, unsigned LineNo)> Cb) const {
|
76 |
| - if (RemoveDotSlash) |
77 |
| - Query = llvm::sys::path::remove_leading_dotslash(Query); |
78 | 86 | for (const auto &Glob : reverse(Globs))
|
79 | 87 | if (Glob->Pattern.match(Query))
|
80 | 88 | Cb(Glob->Name, Glob->LineNo);
|
81 |
| - for (const auto &Regex : reverse(RegExes)) |
82 |
| - if (Regex->Rg.match(Query)) |
83 |
| - Cb(Regex->Name, Regex->LineNo); |
| 89 | +} |
| 90 | + |
| 91 | +SpecialCaseList::Matcher::Matcher(bool UseGlobs, bool RemoveDotSlash) |
| 92 | + : RemoveDotSlash(RemoveDotSlash) { |
| 93 | + if (UseGlobs) |
| 94 | + M.emplace<GlobMatcher>(); |
| 95 | + else |
| 96 | + M.emplace<RegexMatcher>(); |
| 97 | +} |
| 98 | + |
| 99 | +void SpecialCaseList::Matcher::match( |
| 100 | + StringRef Query, |
| 101 | + llvm::function_ref<void(StringRef Rule, unsigned LineNo)> Cb) const { |
| 102 | + if (RemoveDotSlash) |
| 103 | + Query = llvm::sys::path::remove_leading_dotslash(Query); |
| 104 | + return std::visit([&](auto &V) { return V.match(Query, Cb); }, M); |
| 105 | +} |
| 106 | + |
| 107 | +Error SpecialCaseList::Matcher::insert(StringRef Pattern, unsigned LineNumber) { |
| 108 | + return std::visit([&](auto &V) { return V.insert(Pattern, LineNumber); }, M); |
84 | 109 | }
|
85 | 110 |
|
86 | 111 | // TODO: Refactor this to return Expected<...>
|
@@ -139,10 +164,10 @@ bool SpecialCaseList::createInternal(const MemoryBuffer *MB,
|
139 | 164 | Expected<SpecialCaseList::Section *>
|
140 | 165 | SpecialCaseList::addSection(StringRef SectionStr, unsigned FileNo,
|
141 | 166 | unsigned LineNo, bool UseGlobs) {
|
142 |
| - Sections.emplace_back(SectionStr, FileNo); |
| 167 | + Sections.emplace_back(SectionStr, FileNo, UseGlobs); |
143 | 168 | auto &Section = Sections.back();
|
144 | 169 |
|
145 |
| - if (auto Err = Section.SectionMatcher.insert(SectionStr, LineNo, UseGlobs)) { |
| 170 | + if (auto Err = Section.SectionMatcher.insert(SectionStr, LineNo)) { |
146 | 171 | return createStringError(errc::invalid_argument,
|
147 | 172 | "malformed section at line " + Twine(LineNo) +
|
148 | 173 | ": '" + SectionStr +
|
@@ -170,7 +195,7 @@ bool SpecialCaseList::parse(unsigned FileIdx, const MemoryBuffer *MB,
|
170 | 195 | bool RemoveDotSlash = Version > 2;
|
171 | 196 |
|
172 | 197 | Section *CurrentSection;
|
173 |
| - if (auto Err = addSection("*", FileIdx, 1).moveInto(CurrentSection)) { |
| 198 | + if (auto Err = addSection("*", FileIdx, 1, true).moveInto(CurrentSection)) { |
174 | 199 | Error = toString(std::move(Err));
|
175 | 200 | return false;
|
176 | 201 | }
|
@@ -213,10 +238,10 @@ bool SpecialCaseList::parse(unsigned FileIdx, const MemoryBuffer *MB,
|
213 | 238 | }
|
214 | 239 |
|
215 | 240 | auto [Pattern, Category] = Postfix.split("=");
|
216 |
| - auto &Entry = CurrentSection->Entries[Prefix][Category]; |
217 |
| - Entry.RemoveDotSlash = |
218 |
| - RemoveDotSlash && llvm::is_contained(PathPrefixes, Prefix); |
219 |
| - if (auto Err = Entry.insert(Pattern, LineNo, UseGlobs)) { |
| 241 | + auto [It, _] = CurrentSection->Entries[Prefix].try_emplace( |
| 242 | + Category, UseGlobs, |
| 243 | + RemoveDotSlash && llvm::is_contained(PathPrefixes, Prefix)); |
| 244 | + if (auto Err = It->second.insert(Pattern, LineNo)) { |
220 | 245 | Error =
|
221 | 246 | (Twine("malformed ") + (UseGlobs ? "glob" : "regex") + " in line " +
|
222 | 247 | Twine(LineNo) + ": '" + Pattern + "': " + toString(std::move(Err)))
|
|
0 commit comments