2525
2626namespace llvm {
2727
28- Error SpecialCaseList::Matcher ::insert (StringRef Pattern, unsigned LineNumber ,
29- bool UseGlobs ) {
30- if (Pattern.empty ())
28+ Error SpecialCaseList::RegexMatcher ::insert (StringRef Pattern,
29+ unsigned LineNumber ) {
30+ if (Pattern.empty ()) {
3131 return createStringError (errc::invalid_argument,
32- Twine (" Supplied " ) +
33- (UseGlobs ? " glob" : " regex" ) + " was blank" );
34-
35- if (!UseGlobs) {
36- // Replace * with .*
37- auto Regexp = Pattern.str ();
38- for (size_t pos = 0 ; (pos = Regexp.find (' *' , pos)) != std::string::npos;
39- pos += strlen (" .*" )) {
40- Regexp.replace (pos, strlen (" *" ), " .*" );
41- }
32+ " Supplied regex was blank" );
33+ }
4234
43- Regexp = (Twine (" ^(" ) + StringRef (Regexp) + " )$" ).str ();
35+ // Replace * with .*
36+ auto Regexp = Pattern.str ();
37+ for (size_t pos = 0 ; (pos = Regexp.find (' *' , pos)) != std::string::npos;
38+ pos += strlen (" .*" )) {
39+ Regexp.replace (pos, strlen (" *" ), " .*" );
40+ }
4441
45- // Check that the regexp is valid.
46- Regex CheckRE (Regexp);
47- std::string REError;
48- if (!CheckRE.isValid (REError))
49- return createStringError (errc::invalid_argument, REError);
42+ Regexp = (Twine (" ^(" ) + StringRef (Regexp) + " )$" ).str ();
5043
51- RegExes.emplace_back (std::make_pair (
52- std::make_unique<Regex>(std::move (CheckRE)), LineNumber));
44+ // Check that the regexp is valid.
45+ Regex CheckRE (Regexp);
46+ std::string REError;
47+ if (!CheckRE.isValid (REError))
48+ return createStringError (errc::invalid_argument, REError);
5349
54- return Error::success ();
55- }
50+ RegExes. emplace_back (
51+ std::make_pair (std::make_unique<Regex>( std::move (CheckRE)), LineNumber));
5652
57- auto Glob = std::make_unique<Matcher::Glob>();
58- Glob->Name = Pattern.str ();
59- Glob->LineNo = LineNumber;
60- // We must be sure to use the string in `Glob` rather than the provided
61- // reference which could be destroyed before match() is called
62- if (auto Err = GlobPattern::create (Glob->Name , /* MaxSubPatterns=*/ 1024 )
63- .moveInto (Glob->Pattern ))
64- return Err;
65- Globs.push_back (std::move (Glob));
6653 return Error::success ();
6754}
6855
69- unsigned SpecialCaseList::Matcher::match (StringRef Query) const {
70- for (const auto &Glob : reverse (Globs))
71- if (Glob->Pattern .match (Query))
72- return Glob->LineNo ;
56+ unsigned SpecialCaseList::RegexMatcher::match (StringRef Query) const {
7357 for (const auto &[Regex, LineNumber] : reverse (RegExes))
7458 if (Regex->match (Query))
7559 return LineNumber;
7660 return 0 ;
7761}
7862
63+ Error SpecialCaseList::GlobMatcher::insert (StringRef Pattern,
64+ unsigned LineNumber) {
65+ if (Pattern.empty ())
66+ return createStringError (errc::invalid_argument, " Supplied glob was blank" );
67+
68+ auto Res = GlobPattern::create (Pattern, /* MaxSubPatterns=*/ 1024 );
69+ if (auto Err = Res.takeError ())
70+ return Err;
71+ Globs.emplace_back (LineNumber, std::move (Res.get ()));
72+ return Error::success ();
73+ }
74+
75+ unsigned SpecialCaseList::GlobMatcher::match (StringRef Query) const {
76+ for (const auto &Glob : reverse (Globs))
77+ if (Glob.Pattern .match (Query))
78+ return Glob.LineNo ;
79+ return 0 ;
80+ }
81+
82+ SpecialCaseList::Matcher::Matcher (bool UseGlobs) {
83+ if (UseGlobs)
84+ M.emplace <GlobMatcher>();
85+ else
86+ M.emplace <RegexMatcher>();
87+ }
88+
89+ unsigned SpecialCaseList::Matcher::match (StringRef Query) const {
90+ return std::visit ([&](auto &V) { return V.match (Query); }, M);
91+ }
92+
93+ Error SpecialCaseList::Matcher::insert (StringRef Pattern, unsigned LineNumber) {
94+ return std::visit ([&](auto &V) { return V.insert (Pattern, LineNumber); }, M);
95+ }
96+
7997// TODO: Refactor this to return Expected<...>
8098std::unique_ptr<SpecialCaseList>
8199SpecialCaseList::create (const std::vector<std::string> &Paths,
@@ -132,10 +150,11 @@ bool SpecialCaseList::createInternal(const MemoryBuffer *MB,
132150Expected<SpecialCaseList::Section *>
133151SpecialCaseList::addSection (StringRef SectionStr, unsigned FileNo,
134152 unsigned LineNo, bool UseGlobs) {
135- Sections.emplace_back (SectionStr, FileNo);
153+ Sections.emplace_back (SectionStr, FileNo, UseGlobs );
136154 auto &Section = Sections.back ();
137155
138- if (auto Err = Section.SectionMatcher ->insert (SectionStr, LineNo, UseGlobs)) {
156+ SectionStr = SectionStr.copy (StrAlloc);
157+ if (auto Err = Section.SectionMatcher .insert (SectionStr, LineNo)) {
139158 return createStringError (errc::invalid_argument,
140159 " malformed section at line " + Twine (LineNo) +
141160 " : '" + SectionStr +
@@ -148,7 +167,7 @@ SpecialCaseList::addSection(StringRef SectionStr, unsigned FileNo,
148167bool SpecialCaseList::parse (unsigned FileIdx, const MemoryBuffer *MB,
149168 std::string &Error) {
150169 Section *CurrentSection;
151- if (auto Err = addSection (" *" , FileIdx, 1 ).moveInto (CurrentSection)) {
170+ if (auto Err = addSection (" *" , FileIdx, 1 , true ).moveInto (CurrentSection)) {
152171 Error = toString (std::move (Err));
153172 return false ;
154173 }
@@ -194,8 +213,10 @@ bool SpecialCaseList::parse(unsigned FileIdx, const MemoryBuffer *MB,
194213 }
195214
196215 auto [Pattern, Category] = Postfix.split (" =" );
197- auto &Entry = CurrentSection->Entries [Prefix][Category];
198- if (auto Err = Entry.insert (Pattern, LineNo, UseGlobs)) {
216+ auto [It, _] =
217+ CurrentSection->Entries [Prefix].try_emplace (Category, UseGlobs);
218+ Pattern = Pattern.copy (StrAlloc);
219+ if (auto Err = It->second .insert (Pattern, LineNo)) {
199220 Error =
200221 (Twine (" malformed " ) + (UseGlobs ? " glob" : " regex" ) + " in line " +
201222 Twine (LineNo) + " : '" + Pattern + " ': " + toString (std::move (Err)))
@@ -218,7 +239,7 @@ std::pair<unsigned, unsigned>
218239SpecialCaseList::inSectionBlame (StringRef Section, StringRef Prefix,
219240 StringRef Query, StringRef Category) const {
220241 for (const auto &S : reverse (Sections)) {
221- if (S.SectionMatcher -> match (Section)) {
242+ if (S.SectionMatcher . match (Section)) {
222243 unsigned Blame = inSectionBlame (S.Entries , Prefix, Query, Category);
223244 if (Blame)
224245 return {S.FileIdx , Blame};
0 commit comments