2 // localbrowser.cpp - Local variables
6 // JPM = Jean-Paul Mari <djipi.mari@gmail.com>
7 // RG = Richard Goedeken
10 // --- ---------- -----------------------------------------------------------
11 // JPM 11/03/2017 Created this file
12 // JPM Sept./2018 Added a status bar and better status report, and set information values in a tab
13 // RG Jan./2021 Linux build fixes
14 // JPM May/2021 Display the structure's members
18 // Feature to list the pointer(s) in the code using the allocation
19 // To set the information display at the right
20 // To support the array
21 // To support the union
22 // To support the static variables
28 #include "debugger/localbrowser.h"
30 #include "debugger/DBGManager.h"
32 #include "m68000/m68kinterface.h"
36 LocalBrowserWindow::LocalBrowserWindow(QWidget
* parent
/*= 0*/) : QWidget(parent
, Qt::Dialog
),
37 layout(new QVBoxLayout
),
38 TableView(new QTreeView
),
39 model(new QStandardItemModel
),
43 statusbar(new QStatusBar
)
45 setWindowTitle(tr("Locals"));
48 QFont
fixedFont("Lucida Console", 8, QFont::Normal
);
49 fixedFont
.setStyleHint(QFont::TypeWriter
);
51 // Set the new layout with proper identation and readibility
52 model
->setColumnCount(3);
53 model
->setHeaderData(0, Qt::Horizontal
, QObject::tr("Name"));
54 model
->setHeaderData(1, Qt::Horizontal
, QObject::tr("Value"));
55 model
->setHeaderData(2, Qt::Horizontal
, QObject::tr("Type"));
57 TableView
->setModel(model
);
58 TableView
->setEditTriggers(QAbstractItemView::NoEditTriggers
);
60 TableView
->setFont(fixedFont
);
62 layout
->addWidget(TableView
);
65 layout
->addWidget(statusbar
);
71 LocalBrowserWindow::~LocalBrowserWindow(void)
77 // Get the local variables information
78 // Return true for a new local variables set
79 bool LocalBrowserWindow::UpdateInfos(void)
84 // get number of local variables located in the M68K PC address
85 if ((NbLocal
= DBGManager_GetNbVariables(Adr
= m68k_get_reg(NULL
, M68K_REG_PC
))))
87 // get function name from the M68K PC address
88 if ((Ptr
= DBGManager_GetFunctionName(Adr
)))
90 // avoid to read the same information in case of the function has not changed
91 if (!FuncName
|| strcmp(FuncName
, Ptr
))
93 // function is different
95 if (LocalInfo
= (S_LocalInfo
*)realloc(LocalInfo
, (sizeof(S_LocalInfo
) * NbLocal
)))
97 for (size_t i
= 0; i
< NbLocal
; i
++)
99 // get local variable name and his information
100 if ((LocalInfo
[i
].PtrVariable
= DBGManager_GetInfosVariable(Adr
, i
+ 1)))
102 LocalInfo
[i
].Adr
= 0;
103 LocalInfo
[i
].PtrCPURegisterName
= NULL
;
123 // Prepare a complete row based on the variable information
124 // The row will append rows if necessary
125 QList
<QStandardItem
*> LocalBrowserWindow::prepareRow(void* Info
)
128 QList
<QStandardItem
*> ptrRow
= { new QStandardItem(((S_VariablesStruct
*)Info
)->PtrName
), new QStandardItem(""), new QStandardItem(((S_VariablesStruct
*)Info
)->PtrTypeName
) };
130 // check if variable has additional variables (such as structure)
131 if (size_t nb
= ((S_VariablesStruct
*)Info
)->NbTabVariables
)
133 for (size_t i
= 0; i
< nb
; i
++)
135 ptrRow
.first()->appendRow(prepareRow(((S_VariablesStruct
*)Info
)->TabVariables
[i
]));
144 // Set the values of each line in accordance of the rows created from prepareRow() function
145 void LocalBrowserWindow::setValueRow(QStandardItem
*Row
, size_t Adr
, char* Value
, void* Info
)
147 QStandardItem
*child
= Row
->child(0, 1);
150 // check if variable has additional variables list (such as structure)
151 if (size_t nb
= ((S_VariablesStruct
*)Info
)->NbTabVariables
)
153 // get the pointer's value
154 Adr
= GET32(jagMemSpace
, Adr
);
156 for (size_t i
= 0; i
< nb
; i
++)
158 // do not display arrays
159 if (!((((S_VariablesStruct
*)Info
)->TabVariables
[i
]->TypeTag
& DBG_TAG_TYPE_array
)))
161 // set value in the row
162 Value
= DBGManager_GetVariableValueFromAdr(Adr
+ ((S_VariablesStruct
*)Info
)->TabVariables
[i
]->Offset
, ((S_VariablesStruct
*)Info
)->TabVariables
[i
]->TypeEncoding
, ((S_VariablesStruct
*)Info
)->TabVariables
[i
]->TypeByteSize
);
163 child
= Row
->child((int)i
, 1);
164 child
->setText(QString("%1").arg(Value
));
165 setValueRow(child
, Adr
+ ((S_VariablesStruct
*)Info
)->TabVariables
[i
]->Offset
, Value
, (void*)((S_VariablesStruct
*)Info
)->TabVariables
[i
]);
173 // Refresh the local and/or parameters contents list
174 void LocalBrowserWindow::RefreshContents(void)
176 size_t Error
= LOCAL_NOERROR
;
182 // local variables may come from M68K registers
183 const char *CPURegName
[] = { "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7", "A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7" };
185 // refresh only if local's window is displayed
188 // get local's information
191 // erase the previous variables list
192 model
->setRowCount(0);
194 // loop on the locals found
195 for (size_t i
= 0; i
< NbLocal
; i
++)
197 // check variable's name validity
198 if (((S_VariablesStruct
*)(LocalInfo
[i
].PtrVariable
))->PtrName
)
201 model
->appendRow(prepareRow(LocalInfo
[i
].PtrVariable
));
203 // check if the local variable is use by the code
204 if (((S_VariablesStruct
*)(LocalInfo
[i
].PtrVariable
))->Op
)
206 // local or parameters variables
207 if (((((S_VariablesStruct
*)(LocalInfo
[i
].PtrVariable
))->Op
>= DBG_OP_breg0
) && (((S_VariablesStruct
*)(LocalInfo
[i
].PtrVariable
))->Op
<= DBG_OP_breg31
)) || (((S_VariablesStruct
*)(LocalInfo
[i
].PtrVariable
))->Op
== DBG_OP_fbreg
))
209 // get variable's address
210 LocalInfo
[i
].Adr
= m68k_get_reg(NULL
, M68K_REG_A6
) + ((S_VariablesStruct
*)(LocalInfo
[i
].PtrVariable
))->Offset
;
211 // check variable's parameter op
212 if ((((S_VariablesStruct
*)(LocalInfo
[i
].PtrVariable
))->Op
== DBG_OP_fbreg
))
214 LocalInfo
[i
].Adr
+= 8;
219 // variable type from CPU register
220 if ((((S_VariablesStruct
*)(LocalInfo
[i
].PtrVariable
))->Op
>= DBG_OP_reg0
) && (((S_VariablesStruct
*)(LocalInfo
[i
].PtrVariable
))->Op
<= DBG_OP_reg31
))
222 // set color text for a register type variable
223 model
->item((int)i
, 0)->setForeground(QColor(0, 0, 0xfe));
224 model
->item((int)i
, 1)->setForeground(QColor(0, 0, 0xfe));
225 model
->item((int)i
, 2)->setForeground(QColor(0, 0, 0xfe));
226 // get the register's name
227 LocalInfo
[i
].PtrCPURegisterName
= (char *)CPURegName
[(((S_VariablesStruct
*)(LocalInfo
[i
].PtrVariable
))->Op
- DBG_OP_reg0
)];
233 // set color text for unused variable (no need to set it for the value's field as no values will be displayed)
234 model
->item((int)i
, 0)->setForeground(QColor(0xc8, 0xc8, 0xc8));
235 model
->item((int)i
, 2)->setForeground(QColor(0xc8, 0xc8, 0xc8));
241 // set the values in the fields
244 // loop on the locals found
245 for (size_t i
= 0; i
< NbLocal
; i
++)
247 // variable's address must fit in RAM
248 if ((LocalInfo
[i
].Adr
>= 4) && (LocalInfo
[i
].Adr
< vjs
.DRAM_size
))
250 // get the variable's value
251 PtrValue
= DBGManager_GetVariableValueFromAdr(LocalInfo
[i
].Adr
, ((S_VariablesStruct
*)(LocalInfo
[i
].PtrVariable
))->TypeEncoding
, ((S_VariablesStruct
*)(LocalInfo
[i
].PtrVariable
))->TypeByteSize
);
255 // check CPU register's type variable
256 if (LocalInfo
[i
].PtrCPURegisterName
)
258 // get the value from register
259 memset(Value1
, 0, sizeof(Value1
));
260 sprintf(Value1
, "0x%x", m68k_get_reg(NULL
, (m68k_register_t
)((size_t)M68K_REG_D0
+ (((S_VariablesStruct
*)(LocalInfo
[i
].PtrVariable
))->Op
- DBG_OP_reg0
))));
265 // no value can be found
270 // do not display arrays
271 if (!(((S_VariablesStruct
*)LocalInfo
[i
].PtrVariable
)->TypeTag
& DBG_TAG_TYPE_array
))
273 // set the local's variable value
274 model
->item((int)i
, 1)->setText(QString("%1").arg(PtrValue
));
275 setValueRow(model
->item((int)i
), LocalInfo
[i
].Adr
, PtrValue
, (S_VariablesStruct
*)(LocalInfo
[i
].PtrVariable
));
279 MSG
+= QString("Ready");
283 // erase the previous variables list
284 model
->setRowCount(0);
287 MSG
+= QString("No locals");
288 Error
= LOCAL_NOLOCALS
;
291 // display status bar
294 if ((Error
& LOCAL_WARNING
))
296 statusbar
->setStyleSheet("background-color: lightyellow; font: bold");
300 statusbar
->setStyleSheet("background-color: tomato; font: bold");
305 statusbar
->setStyleSheet("background-color: lightgreen; font: bold");
307 statusbar
->showMessage(MSG
);
312 // Handle keyboard actions
313 void LocalBrowserWindow::keyPressEvent(QKeyEvent
* e
)
315 // close / hide the window
316 if (e
->key() == Qt::Key_Escape
)