Commit | Line | Data |
---|---|---|
0203b5fd JPM |
1 | //\r |
2 | // localbrowser.cpp - Local variables\r | |
3 | //\r | |
4 | // by Jean-Paul Mari\r | |
5 | //\r | |
6 | // JPM = Jean-Paul Mari <djipi.mari@gmail.com>\r | |
c4fe5864 | 7 | // RG = Richard Goedeken\r |
0203b5fd JPM |
8 | //\r |
9 | // Who When What\r | |
10 | // --- ---------- -----------------------------------------------------------\r | |
11 | // JPM 11/03/2017 Created this file\r | |
6642f781 | 12 | // JPM Sept./2018 Added a status bar and better status report, and set information values in a tab\r |
c4fe5864 | 13 | // RG Jan./2021 Linux build fixes\r |
2b91c435 JPM |
14 | //\r |
15 | \r | |
16 | // STILL TO DO:\r | |
17 | // Feature to list the pointer(s) in the code using the allocation\r | |
18 | // To set the information display at the right\r | |
19 | // To support the array\r | |
6642f781 JPM |
20 | // To support the static variables\r |
21 | // To add a filter\r | |
0203b5fd JPM |
22 | //\r |
23 | \r | |
c89f8ff7 | 24 | #include <stdlib.h>\r |
0203b5fd JPM |
25 | \r |
26 | #include "debugger/localbrowser.h"\r | |
27 | #include "memory.h"\r | |
28 | #include "debugger/DBGManager.h"\r | |
29 | #include "settings.h"\r | |
30 | #include "m68000/m68kinterface.h"\r | |
31 | \r | |
32 | \r | |
33 | // \r | |
34 | LocalBrowserWindow::LocalBrowserWindow(QWidget * parent/*= 0*/) : QWidget(parent, Qt::Dialog),\r | |
2b91c435 JPM |
35 | layout(new QVBoxLayout),\r |
36 | #ifdef LOCAL_LAYOUTTEXTS\r | |
37 | text(new QTextBrowser),\r | |
38 | #else\r | |
39 | TableView(new QTableView),\r | |
40 | model(new QStandardItemModel),\r | |
41 | #endif\r | |
42 | NbLocal(0),\r | |
43 | FuncName((char *)calloc(1, 1)),\r | |
44 | LocalInfo(NULL),\r | |
45 | statusbar(new QStatusBar)\r | |
0203b5fd | 46 | {\r |
2b91c435 | 47 | setWindowTitle(tr("Locals"));\r |
0203b5fd | 48 | \r |
2b91c435 | 49 | // Set the font\r |
0203b5fd | 50 | QFont fixedFont("Lucida Console", 8, QFont::Normal);\r |
0203b5fd | 51 | fixedFont.setStyleHint(QFont::TypeWriter);\r |
0203b5fd | 52 | \r |
2b91c435 JPM |
53 | #ifdef LOCAL_LAYOUTTEXTS\r |
54 | // Set original layout\r | |
55 | text->setFont(fixedFont);\r | |
0203b5fd | 56 | layout->addWidget(text);\r |
2b91c435 JPM |
57 | #else\r |
58 | // Set the new layout with proper identation and readibility\r | |
59 | model->setColumnCount(3);\r | |
60 | model->setHeaderData(0, Qt::Horizontal, QObject::tr("Name"));\r | |
61 | model->setHeaderData(1, Qt::Horizontal, QObject::tr("Value"));\r | |
62 | model->setHeaderData(2, Qt::Horizontal, QObject::tr("Type"));\r | |
63 | // Information table\r | |
64 | TableView->setModel(model);\r | |
65 | TableView->setEditTriggers(QAbstractItemView::NoEditTriggers);\r | |
66 | TableView->setShowGrid(0);\r | |
67 | TableView->setFont(fixedFont);\r | |
68 | TableView->verticalHeader()->setDefaultSectionSize(TableView->verticalHeader()->minimumSectionSize());\r | |
69 | TableView->verticalHeader()->setDefaultAlignment(Qt::AlignRight);\r | |
70 | layout->addWidget(TableView);\r | |
71 | #endif\r | |
72 | \r | |
73 | // Status bar\r | |
74 | layout->addWidget(statusbar);\r | |
75 | setLayout(layout);\r | |
0203b5fd JPM |
76 | }\r |
77 | \r | |
78 | \r | |
79 | //\r | |
80 | LocalBrowserWindow::~LocalBrowserWindow(void)\r | |
81 | {\r | |
82 | free(LocalInfo);\r | |
83 | free(FuncName);\r | |
0203b5fd JPM |
84 | }\r |
85 | \r | |
86 | \r | |
87 | //\r | |
88 | bool LocalBrowserWindow::UpdateInfos(void)\r | |
89 | {\r | |
90 | size_t Adr;\r | |
91 | char *Ptr;\r | |
92 | \r | |
93 | if (NbLocal = DBGManager_GetNbLocalVariables(Adr = m68k_get_reg(NULL, M68K_REG_PC)))\r | |
94 | {\r | |
95 | if (Ptr = DBGManager_GetFunctionName(Adr))\r | |
96 | {\r | |
97 | if (strcmp(FuncName, Ptr))\r | |
98 | {\r | |
47b6ecae | 99 | if (FuncName = (char *)realloc(FuncName, strlen(Ptr) + 1))\r |
0203b5fd | 100 | {\r |
47b6ecae JPM |
101 | strcpy(FuncName, Ptr);\r |
102 | \r | |
103 | if (LocalInfo = (WatchInfo *)realloc(LocalInfo, (sizeof(WatchInfo) * NbLocal)))\r | |
0203b5fd | 104 | {\r |
47b6ecae JPM |
105 | for (size_t i = 0; i < NbLocal; i++)\r |
106 | {\r | |
107 | // Get local variable name and his information\r | |
108 | if (LocalInfo[i].PtrVariableName = DBGManager_GetLocalVariableName(Adr, i + 1))\r | |
109 | {\r | |
110 | LocalInfo[i].Op = DBGManager_GetLocalVariableOp(Adr, i + 1);\r | |
111 | LocalInfo[i].Adr = NULL;\r | |
112 | LocalInfo[i].PtrCPURegisterName = NULL;\r | |
113 | LocalInfo[i].TypeTag = DBGManager_GetLocalVariableTypeTag(Adr, i + 1);\r | |
114 | LocalInfo[i].PtrVariableBaseTypeName = DBGManager_GetLocalVariableTypeName(Adr, i + 1);\r | |
115 | LocalInfo[i].TypeEncoding = DBGManager_GetLocalVariableTypeEncoding(Adr, i + 1);\r | |
116 | LocalInfo[i].TypeByteSize = DBGManager_GetLocalVariableTypeByteSize(Adr, i + 1);\r | |
117 | LocalInfo[i].Offset = DBGManager_GetLocalVariableOffset(Adr, i + 1);\r | |
118 | }\r | |
119 | }\r | |
0203b5fd JPM |
120 | }\r |
121 | }\r | |
122 | }\r | |
123 | \r | |
124 | return true;\r | |
125 | }\r | |
126 | }\r | |
127 | \r | |
128 | *FuncName = 0;\r | |
129 | \r | |
130 | return false;\r | |
131 | }\r | |
132 | \r | |
133 | \r | |
134 | //\r | |
135 | void LocalBrowserWindow::RefreshContents(void)\r | |
136 | {\r | |
2b91c435 | 137 | #ifdef LOCAL_LAYOUTTEXTS\r |
0203b5fd | 138 | char string[1024];\r |
2b91c435 JPM |
139 | #endif\r |
140 | size_t Error = LOCAL_NOERROR;\r | |
0203b5fd | 141 | QString Local;\r |
2b91c435 JPM |
142 | QString MSG;\r |
143 | char Value1[100];\r | |
144 | #ifdef LOCAL_SUPPORTARRAY\r | |
0203b5fd | 145 | char Value[100];\r |
2b91c435 | 146 | #endif\r |
0203b5fd | 147 | char *PtrValue;\r |
0203b5fd | 148 | \r |
e857856a JPM |
149 | const char *CPURegName[] = { "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7", "A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7" };\r |
150 | \r | |
0203b5fd JPM |
151 | if (isVisible())\r |
152 | {\r | |
2b91c435 JPM |
153 | #ifndef LOCAL_LAYOUTTEXTS\r |
154 | model->setRowCount(0);\r | |
155 | #endif\r | |
0203b5fd JPM |
156 | if (UpdateInfos())\r |
157 | {\r | |
0203b5fd JPM |
158 | for (size_t i = 0; i < NbLocal; i++)\r |
159 | {\r | |
160 | if (LocalInfo[i].PtrVariableName)\r | |
161 | {\r | |
2b91c435 JPM |
162 | memset(Value1, 0, sizeof(Value1));\r |
163 | #ifdef LOCAL_LAYOUTTEXTS\r | |
164 | if (i)\r | |
165 | {\r | |
166 | Local += QString("<br>");\r | |
167 | }\r | |
168 | #else\r | |
169 | model->insertRow(i);\r | |
170 | #endif\r | |
169c1409 JPM |
171 | // Local or parameters variables\r |
172 | if (((LocalInfo[i].Op >= DBG_OP_breg0) && (LocalInfo[i].Op <= DBG_OP_breg31)) || (LocalInfo[i].Op == DBG_OP_fbreg))\r | |
0203b5fd JPM |
173 | {\r |
174 | LocalInfo[i].Adr = m68k_get_reg(NULL, M68K_REG_A6) + LocalInfo[i].Offset;\r | |
175 | \r | |
169c1409 JPM |
176 | if ((LocalInfo[i].Op == DBG_OP_fbreg))\r |
177 | {\r | |
178 | LocalInfo[i].Adr += 8;\r | |
179 | }\r | |
180 | \r | |
0203b5fd JPM |
181 | if ((LocalInfo[i].Adr >= 0) && (LocalInfo[i].Adr < vjs.DRAM_size))\r |
182 | {\r | |
2b91c435 JPM |
183 | if ((LocalInfo[i].TypeTag & (DBG_TAG_TYPE_array | DBG_TAG_TYPE_structure)))\r |
184 | {\r | |
185 | #if defined(LOCAL_SUPPORTARRAY) || defined(LOCAL_SUPPORTSTRUCTURE)\r | |
186 | //memcpy(Value1, &jaguarMainRAM[LocalInfo[i].Adr], 20);\r | |
187 | #ifdef LOCAL_LAYOUTTEXTS\r | |
188 | //sprintf(Value, "\"%s\"", Value1);\r | |
189 | #else\r | |
190 | //sprintf(Value, "0x%06X, \"%s\"", LocalInfo[i].Adr, Value1);\r | |
191 | #endif\r | |
192 | //PtrValue = Value;\r | |
193 | PtrValue = NULL;\r | |
194 | #else\r | |
195 | PtrValue = NULL;\r | |
196 | #endif\r | |
197 | }\r | |
198 | else\r | |
199 | {\r | |
200 | PtrValue = DBGManager_GetVariableValueFromAdr(LocalInfo[i].Adr, LocalInfo[i].TypeEncoding, LocalInfo[i].TypeByteSize);\r | |
201 | }\r | |
0203b5fd JPM |
202 | }\r |
203 | else\r | |
204 | {\r | |
205 | PtrValue = NULL;\r | |
206 | }\r | |
207 | }\r | |
208 | else\r | |
209 | {\r | |
e857856a | 210 | // Value from CPU register\r |
0203b5fd JPM |
211 | if ((LocalInfo[i].Op >= DBG_OP_reg0) && (LocalInfo[i].Op <= DBG_OP_reg31))\r |
212 | {\r | |
e857856a | 213 | LocalInfo[i].PtrCPURegisterName = (char *)CPURegName[(LocalInfo[i].Op - DBG_OP_reg0)];\r |
c89f8ff7 RG |
214 | sprintf(Value1, "%d", m68k_get_reg(NULL, (m68k_register_t)((size_t)M68K_REG_D0 + (LocalInfo[i].Op - DBG_OP_reg0))));\r |
215 | PtrValue = Value1;\r | |
0203b5fd JPM |
216 | }\r |
217 | else\r | |
218 | {\r | |
219 | PtrValue = NULL;\r | |
220 | }\r | |
221 | }\r | |
222 | \r | |
2b91c435 JPM |
223 | #ifndef LOCAL_LAYOUTTEXTS\r |
224 | model->setItem(i, 0, new QStandardItem(QString("%1").arg(LocalInfo[i].PtrVariableName)));\r | |
225 | #endif\r | |
226 | // Check if the local variable is use by the code\r | |
47b6ecae | 227 | if (!LocalInfo[i].Op)\r |
0203b5fd | 228 | {\r |
2b91c435 | 229 | #ifdef LOCAL_LAYOUTTEXTS\r |
47b6ecae | 230 | sprintf(string, "<font color='#A52A2A'>%i : %s | %s | [Not used]</font>", (i + 1), (LocalInfo[i].PtrVariableBaseTypeName ? LocalInfo[i].PtrVariableBaseTypeName : (char *)"<font color='#ff0000'>N/A</font>"), LocalInfo[i].PtrVariableName);\r |
2b91c435 JPM |
231 | #else\r |
232 | #endif\r | |
0203b5fd JPM |
233 | }\r |
234 | else\r | |
235 | {\r | |
2b91c435 JPM |
236 | #ifndef LOCAL_LAYOUTTEXTS\r |
237 | model->setItem(i, 1, new QStandardItem(QString("%1").arg(PtrValue)));\r | |
238 | #else\r | |
47b6ecae JPM |
239 | sprintf(string, "%i : %s | %s | ", (i + 1), (LocalInfo[i].PtrVariableBaseTypeName ? LocalInfo[i].PtrVariableBaseTypeName : (char *)"<font color='#ff0000'>N/A</font>"), LocalInfo[i].PtrVariableName);\r |
240 | Local += QString(string);\r | |
2b91c435 | 241 | \r |
47b6ecae | 242 | if ((unsigned int)LocalInfo[i].Adr)\r |
e857856a | 243 | {\r |
47b6ecae | 244 | sprintf(string, "0x%06X", (unsigned int)LocalInfo[i].Adr);\r |
e857856a JPM |
245 | }\r |
246 | else\r | |
247 | {\r | |
47b6ecae JPM |
248 | if (LocalInfo[i].PtrCPURegisterName)\r |
249 | {\r | |
250 | sprintf(string, "<font color='#0000FF'>%s</font>", LocalInfo[i].PtrCPURegisterName);\r | |
251 | }\r | |
252 | else\r | |
253 | {\r | |
254 | sprintf(string, "%s", (char *)"<font color='#ff0000'>N/A</font>");\r | |
255 | }\r | |
256 | }\r | |
2b91c435 | 257 | \r |
47b6ecae JPM |
258 | Local += QString(string);\r |
259 | sprintf(string, " | %s", (!PtrValue ? (char *)"<font color='#ff0000'>N/A</font>" : PtrValue));\r | |
2b91c435 | 260 | #endif\r |
0203b5fd | 261 | }\r |
2b91c435 JPM |
262 | #ifndef LOCAL_LAYOUTTEXTS\r |
263 | model->setItem(i, 2, new QStandardItem(QString("%1").arg((LocalInfo[i].PtrVariableBaseTypeName ? LocalInfo[i].PtrVariableBaseTypeName : (char *)"<font color='#ff0000'>N/A</font>"))));\r | |
264 | #else\r | |
0203b5fd | 265 | Local += QString(string);\r |
2b91c435 | 266 | #endif\r |
0203b5fd JPM |
267 | }\r |
268 | }\r | |
269 | \r | |
2b91c435 JPM |
270 | MSG += QString("Ready");\r |
271 | #ifdef LOCAL_LAYOUTTEXTS\r | |
0203b5fd JPM |
272 | text->clear();\r |
273 | text->setText(Local);\r | |
2b91c435 | 274 | #endif\r |
0203b5fd JPM |
275 | }\r |
276 | else\r | |
277 | {\r | |
2b91c435 JPM |
278 | // No locals\r |
279 | MSG += QString("No locals");\r | |
280 | Error = LOCAL_NOLOCALS;\r | |
281 | #ifdef LOCAL_LAYOUTTEXTS\r | |
0203b5fd | 282 | text->clear();\r |
2b91c435 JPM |
283 | #endif\r |
284 | }\r | |
285 | \r | |
286 | // Display status bar\r | |
287 | if (Error)\r | |
288 | {\r | |
289 | if ((Error & LOCAL_WARNING))\r | |
290 | {\r | |
291 | statusbar->setStyleSheet("background-color: lightyellow; font: bold");\r | |
292 | }\r | |
293 | else\r | |
294 | {\r | |
295 | statusbar->setStyleSheet("background-color: tomato; font: bold");\r | |
296 | }\r | |
297 | }\r | |
298 | else\r | |
299 | {\r | |
300 | statusbar->setStyleSheet("background-color: lightgreen; font: bold");\r | |
0203b5fd | 301 | }\r |
2b91c435 | 302 | statusbar->showMessage(MSG);\r |
0203b5fd JPM |
303 | }\r |
304 | }\r | |
305 | \r | |
306 | \r | |
a2dfb8e5 | 307 | // \r |
0203b5fd JPM |
308 | void LocalBrowserWindow::keyPressEvent(QKeyEvent * e)\r |
309 | {\r | |
310 | if (e->key() == Qt::Key_Escape)\r | |
a2dfb8e5 | 311 | {\r |
0203b5fd | 312 | hide();\r |
a2dfb8e5 | 313 | }\r |
0203b5fd | 314 | }\r |