1 | // SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. |
2 | // |
3 | // SPDX-License-Identifier: GPL-3.0-or-later |
4 | |
5 | #include "xmlstreamreader.h" |
6 | #include "valgrind.h" |
7 | |
8 | #include "common/common.h" |
9 | |
10 | #include <QFile> |
11 | #include <QTreeWidget> |
12 | #include <QHeaderView> |
13 | #include <QLabel> |
14 | |
15 | XmlStreamReader::XmlStreamReader(QTreeWidget *tree) |
16 | { |
17 | treeWidget = tree; |
18 | |
19 | connect(treeWidget, &QTreeWidget::itemClicked, [=](QTreeWidgetItem *item, int column) { |
20 | QStringList toolTip = item->toolTip(column).split(":" ); |
21 | if (toolTip.count() > 1) { |
22 | QString filePath = toolTip.at(0); |
23 | QString line = toolTip.at(1); |
24 | editor.jumpToLine(filePath, line.toInt()); |
25 | } |
26 | }); |
27 | } |
28 | |
29 | bool XmlStreamReader::readFile(const QString &fileName) |
30 | { |
31 | QFile file(fileName); |
32 | |
33 | if (!file.open(QFile::ReadOnly)) |
34 | return false; |
35 | |
36 | reader.setDevice(&file); |
37 | reader.readNext(); |
38 | while (!reader.atEnd()) { |
39 | QString temp = reader.name().toString(); |
40 | if (reader.isStartElement() && reader.name() == "error" ) { |
41 | readErrorElement(); |
42 | } else { |
43 | reader.readNext(); |
44 | } |
45 | } |
46 | |
47 | return true; |
48 | } |
49 | |
50 | void XmlStreamReader::readErrorElement() |
51 | { |
52 | reader.readNext(); |
53 | while (!reader.atEnd()) { |
54 | QString temp = reader.name().toString(); |
55 | if (reader.isEndElement()) { |
56 | reader.readNext(); |
57 | break; |
58 | } |
59 | |
60 | if (reader.isStartElement()) { |
61 | if ( reader.name() == "what" || reader.name() == "auxwhat" ) { |
62 | readWhatElement(); |
63 | } else if (reader.name() == "xwhat" ) { |
64 | readXWhatElement(); |
65 | } else if (reader.name() == "stack" ) { |
66 | readStackElement(treeWidget->invisibleRootItem()); |
67 | } else { |
68 | skipUnknownElement(); |
69 | } |
70 | } else { |
71 | reader.readNext(); |
72 | } |
73 | } |
74 | } |
75 | |
76 | void XmlStreamReader::readWhatElement() |
77 | { |
78 | currentIssue = reader.readElementText(); |
79 | if (reader.isEndElement()) |
80 | reader.readNext(); |
81 | } |
82 | |
83 | void XmlStreamReader::readXWhatElement() |
84 | { |
85 | reader.readNext(); |
86 | while (!reader.atEnd()) { |
87 | if (reader.isEndElement()) { |
88 | reader.readNext(); |
89 | break; |
90 | } |
91 | |
92 | if (reader.isStartElement()) { |
93 | if (reader.name() == "text" ) { |
94 | currentIssue = reader.readElementText(); |
95 | if (reader.isEndElement()) |
96 | reader.readNext(); |
97 | } else { |
98 | skipUnknownElement(); |
99 | } |
100 | } else { |
101 | reader.readNext(); |
102 | } |
103 | } |
104 | } |
105 | |
106 | void XmlStreamReader::readStackElement(QTreeWidgetItem *parent) |
107 | { |
108 | QTreeWidgetItem *item = new QTreeWidgetItem(parent); |
109 | item->setText(0, currentIssue); |
110 | |
111 | reader.readNext(); |
112 | while (!reader.atEnd()) { |
113 | QString temp = reader.name().toString(); |
114 | if (reader.isEndElement()) { |
115 | reader.readNext(); |
116 | break; |
117 | } |
118 | |
119 | if (reader.isStartElement()) { |
120 | if (reader.name() == "frame" ) { |
121 | readFrameElement(item); |
122 | } else { |
123 | skipUnknownElement(); |
124 | } |
125 | } else { |
126 | reader.readNext(); |
127 | } |
128 | } |
129 | } |
130 | |
131 | void XmlStreamReader::readFrameElement(QTreeWidgetItem *parent) |
132 | { |
133 | Tip tip; |
134 | |
135 | reader.readNext(); |
136 | while (!reader.atEnd()) { |
137 | QString temp = reader.name().toString(); |
138 | if (reader.isEndElement()) { |
139 | if (reader.name() == "frame" ) { |
140 | reader.readNext(); |
141 | break; |
142 | } |
143 | reader.readNext(); |
144 | } |
145 | |
146 | if (reader.isStartElement()) { |
147 | QString name = reader.name().toString(); |
148 | QString text = reader.readElementText(); |
149 | saveTip(tip, name, text); |
150 | } else { |
151 | reader.readNext(); |
152 | } |
153 | } |
154 | |
155 | setItem(tip, parent); |
156 | } |
157 | |
158 | void XmlStreamReader::skipUnknownElement() |
159 | { |
160 | reader.readNext(); |
161 | while (!reader.atEnd()) { |
162 | QString temp = reader.name().toString(); |
163 | if (reader.isEndElement()) { |
164 | reader.readNext(); |
165 | break; |
166 | } |
167 | |
168 | if (reader.isStartElement()) { |
169 | skipUnknownElement(); |
170 | } else { |
171 | reader.readNext(); |
172 | } |
173 | } |
174 | } |
175 | |
176 | void XmlStreamReader::saveTip(Tip &tip, const QString &name, const QString &text) |
177 | { |
178 | if (name == "ip" ) { |
179 | tip.pointer = text; |
180 | } else if (name == "obj" ) { |
181 | tip.object = text; |
182 | } else if (name == "fn" ) { |
183 | tip.function = text; |
184 | } else if (name == "dir" ) { |
185 | tip.dir = text; |
186 | } else if (name == "file" ) { |
187 | tip.file = text; |
188 | } else if (name == "line" ) { |
189 | tip.line = text; |
190 | } |
191 | |
192 | return ; |
193 | } |
194 | |
195 | void XmlStreamReader::setItem(Tip &tip, QTreeWidgetItem *parent) |
196 | { |
197 | if (!tip.function.isEmpty() && !tip.line.isEmpty()) { |
198 | QTreeWidgetItem *item = new QTreeWidgetItem(parent); |
199 | QString filePath = tip.dir + "/" + tip.file; |
200 | item->setText(0, tip.function); |
201 | item->setToolTip(0, toolTipContent(tip)); |
202 | item->setForeground(1, QColor("green" )); |
203 | item->setText(1, tip.function + ":" + tip.line + ":0" ); |
204 | item->setToolTip(1, filePath + ":" + tip.line + ":0" ); |
205 | } else if (!tip.function.isEmpty() && !tip.object.isEmpty()) { |
206 | QTreeWidgetItem *item = new QTreeWidgetItem(parent); |
207 | item->setText(0, tip.function + " in " + tip.object); |
208 | item->setToolTip(0, toolTipContent(tip)); |
209 | } |
210 | } |
211 | |
212 | QString XmlStreamReader::toolTipContent(Tip &tip) |
213 | { |
214 | QString toolTip = tr("Function:\n\t" ) + tip.function + "\n" + tr("Instruction Pointer:\n\t" ) + |
215 | tip.pointer + "\n" + tr("Object:\n\t" ) + tip.object; |
216 | if (!tip.dir.isEmpty()) { |
217 | toolTip += "\n" + tr("Location:\n\t" ) + tip.dir + tip.file + ":" + tip.line; |
218 | } |
219 | |
220 | return toolTip; |
221 | } |
222 | |
223 | |