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
15XmlStreamReader::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
29bool 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
50void 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
76void XmlStreamReader::readWhatElement()
77{
78 currentIssue = reader.readElementText();
79 if (reader.isEndElement())
80 reader.readNext();
81}
82
83void 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
106void 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
131void 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
158void 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
176void 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
195void 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
212QString 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