31 for (
unsigned i = 0,
e = Matches[0]->first.size();
i !=
e; ++
i) {
33 char Letter = Matches[0]->first[
i];
36 if (
Match->first[
i] != Letter)
40 return Matches[0]->first.size();
48 bool StringMatcher::EmitStringMatcherForChar(
49 const std::vector<const StringPair *> &Matches,
unsigned CharNo,
50 unsigned IndentCount,
bool IgnoreDuplicates)
const {
51 assert(!Matches.empty() &&
"Must have at least one string to match!");
52 std::string Indent(IndentCount * 2 + 4,
' ');
56 if (CharNo == Matches[0]->first.size()) {
57 if (Matches.size() > 1 && !IgnoreDuplicates)
63 std::pair<StringRef, StringRef> Split =
Code.split(
'\n');
64 OS << Indent << Split.first <<
"\t // \"" << Matches[0]->first <<
"\"\n";
67 while (!
Code.empty()) {
68 Split =
Code.split(
'\n');
69 OS << Indent << Split.first <<
"\n";
76 std::map<char, std::vector<const StringPair*>> MatchesByLetter;
79 MatchesByLetter[
Match->first[CharNo]].push_back(Match);
83 if (MatchesByLetter.size() == 1) {
85 unsigned NumChars = FirstNonCommonLetter-CharNo;
91 OS << Indent <<
"if (" << StrVariableName <<
"[" << CharNo <<
"] != '"
92 << Matches[0]->first[CharNo] <<
"')\n";
93 OS << Indent <<
" break;\n";
97 OS << Indent <<
"if (memcmp(" << StrVariableName <<
".data()+" << CharNo
98 <<
", \"" << Matches[0]->first.
substr(CharNo, NumChars) <<
"\", "
99 << NumChars <<
") != 0)\n";
100 OS << Indent <<
" break;\n";
103 return EmitStringMatcherForChar(Matches, FirstNonCommonLetter, IndentCount,
109 OS << Indent <<
"switch (" << StrVariableName <<
"[" << CharNo <<
"]) {\n";
110 OS << Indent <<
"default: break;\n";
112 for (
const auto &LI : MatchesByLetter) {
114 OS << Indent <<
"case '" << LI.first <<
"':\t // " << LI.second.size()
116 if (LI.second.size() != 1)
118 OS <<
" to match.\n";
119 if (EmitStringMatcherForChar(LI.second, CharNo + 1, IndentCount + 1,
121 OS << Indent <<
" break;\n";
124 OS << Indent <<
"}\n";
132 if (Matches.empty())
return;
135 std::map<unsigned, std::vector<const StringPair*>> MatchesByLength;
138 MatchesByLength[
Match.first.size()].push_back(&
Match);
142 OS.
indent(Indent*2+2) <<
"switch (" << StrVariableName <<
".size()) {\n";
143 OS.
indent(Indent*2+2) <<
"default: break;\n";
145 for (
const auto &LI : MatchesByLength) {
147 <<
"case " << LI.first <<
":\t // " << LI.second.size() <<
" string"
148 << (LI.second.size() == 1 ?
"" :
"s") <<
" to match.\n";
149 if (EmitStringMatcherForChar(LI.second, 0, Indent, IgnoreDuplicates))
150 OS.
indent(Indent*2+4) <<
"break;\n";
153 OS.
indent(Indent*2+2) <<
"}\n";