LLVM: lib/DebugInfo/Symbolize/Markup.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
15
17
18namespace llvm {
20
21
22
23
24
25static const char SGRSyntaxStr[] = "\033\\[([0-1]|3[0-7])m";
26
29
36
38 Buffer.clear();
39 NextIdx = 0;
40 FinishedMultiline.clear();
41 this->Line = Line;
42}
43
45
46 if (!Buffer.empty()) {
47 if (NextIdx < Buffer.size())
48 return std::move(Buffer[NextIdx++]);
49 NextIdx = 0;
50 Buffer.clear();
51 }
52
53
54
55 if (Line.empty())
56 return std::nullopt;
57
58 if (!InProgressMultiline.empty()) {
59 if (std::optional MultilineEnd = parseMultiLineEnd(Line)) {
61 assert(FinishedMultiline.empty() &&
62 "At most one multi-line element can be finished at a time.");
63 FinishedMultiline.swap(InProgressMultiline);
64
65 advanceTo(Line, MultilineEnd->end());
66 return *parseElement(FinishedMultiline);
67 }
68
69
71 Line = Line.drop_front(Line.size());
72 return std::nullopt;
73 }
74
75
76 if (std::optional Element = parseElement(Line)) {
77 parseTextOutsideMarkup(takeTo(Line, Element->Text.begin()));
78 Buffer.push_back(std::move(*Element));
79 advanceTo(Line, Element->Text.end());
81 }
82
83
84
85 if (std::optional MultilineBegin = parseMultiLineBegin(Line)) {
86
87 parseTextOutsideMarkup(takeTo(Line, MultilineBegin->begin()));
88
89
91 Line = Line.drop_front(Line.size());
93 }
94
95
96 parseTextOutsideMarkup(Line);
97 Line = Line.drop_front(Line.size());
99}
100
102 Buffer.clear();
103 NextIdx = 0;
104 Line = {};
105 if (InProgressMultiline.empty())
106 return;
107 FinishedMultiline.swap(InProgressMultiline);
108 parseTextOutsideMarkup(FinishedMultiline);
109}
110
111
112
113std::optional MarkupParser::parseElement(StringRef Line) {
114 while (true) {
115
116 size_t BeginPos = Line.find("{{{");
118 return std::nullopt;
119 size_t EndPos = Line.find("}}}", BeginPos + 3);
121 return std::nullopt;
122 EndPos += 3;
124 Element.Text = Line.slice(BeginPos, EndPos);
125 Line = Line.substr(EndPos);
126
127
130 std::tie(Element.Tag, FieldsContent) = Content.split(':');
132 continue;
133
134
135 if (!FieldsContent.empty())
136 FieldsContent.split(Element.Fields, ":");
137 else if (Content.back() == ':')
138 Element.Fields.push_back(FieldsContent);
139
140 return Element;
141 }
142}
143
146 Node.Text = Text;
148}
149
150
151
152
153void MarkupParser::parseTextOutsideMarkup(StringRef Text) {
154 if (Text.empty())
155 return;
157 while (SGRSyntax.match(Text, &Matches)) {
158
159 if (Matches.begin()->begin() != Text.begin())
161
164 }
165 if (!Text.empty())
166 Buffer.push_back(textNode(Text));
167}
168
169
170
171std::optional MarkupParser::parseMultiLineBegin(StringRef Line) {
172
173 size_t BeginPos = Line.rfind("{{{");
175 return std::nullopt;
176 size_t BeginTagPos = BeginPos + 3;
177
178
179
180 size_t EndPos = Line.find("}}}", BeginTagPos);
182 return std::nullopt;
183
184
185 size_t EndTagPos = Line.find(':', BeginTagPos);
187 return std::nullopt;
188 StringRef Tag = Line.slice(BeginTagPos, EndTagPos);
189 if (!MultilineTags.contains(Tag))
190 return std::nullopt;
191 return Line.substr(BeginPos);
192}
193
194
195
196std::optional MarkupParser::parseMultiLineEnd(StringRef Line) {
197 size_t EndPos = Line.find("}}}");
199 return std::nullopt;
200 return Line.take_front(EndPos + 3);
201}
202
203}
204}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file declares the log symbolizer markup data model and parser.
LLVM_ABI bool match(StringRef String, SmallVectorImpl< StringRef > *Matches=nullptr, std::string *Error=nullptr) const
matches - Match the regex against a given String.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
static constexpr size_t npos
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
constexpr bool empty() const
empty - Check if the string is empty.
StringRef drop_front(size_t N=1) const
Return a StringRef equal to 'this' but with the first N elements dropped.
char back() const
back - Get the last character in the string.
StringRef slice(size_t Start, size_t End) const
Return a reference to the substring from [Start, End).
StringRef take_front(size_t N=1) const
Return a StringRef equal to 'this' but with only the first N elements remaining.
StringRef drop_back(size_t N=1) const
Return a StringRef equal to 'this' but with the last N elements dropped.
StringSet - A wrapper for StringMap that provides set-like functionality.
LLVM_ABI std::optional< MarkupNode > nextNode()
Returns the next node in the input sequence.
Definition Markup.cpp:44
LLVM_ABI void flush()
Inform the parser of that the input stream has ended.
Definition Markup.cpp:101
LLVM_ABI MarkupParser(StringSet<> MultilineTags={})
Definition Markup.cpp:27
LLVM_ABI void parseLine(StringRef Line)
Parses an individual Line of input.
Definition Markup.cpp:37
static MarkupNode textNode(StringRef Text)
Definition Markup.cpp:144
static void advanceTo(StringRef &Str, StringRef::iterator Pos)
Definition Markup.cpp:33
static const char SGRSyntaxStr[]
Definition Markup.cpp:25
static StringRef takeTo(StringRef Str, StringRef::iterator Pos)
Definition Markup.cpp:30
This is an optimization pass for GlobalISel generic memory operations.
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Implement std::hash so that hash_code can be used in STL containers.
A node of symbolizer markup.
StringRef Text
The full text of this node in the input.
SmallVector< StringRef > Fields
If this represents an element with fields, a list of the field contents.
StringRef Tag
If this represents an element, the tag. Otherwise, empty.