Display the structure's members in the Local variables window
authorJean-Paul Mari <djipi.mari@gmail.com>
Mon, 24 May 2021 05:44:41 +0000 (01:44 -0400)
committerJean-Paul Mari <djipi.mari@gmail.com>
Mon, 24 May 2021 05:44:41 +0000 (01:44 -0400)
docs/vj_HistoryNotes.txt
src/debugger/localbrowser.cpp
src/debugger/localbrowser.h

index f438507..ca4ccf8 100644 (file)
@@ -41,6 +41,7 @@ Release 5 (TBA)
 27) Added video output display in a specific window
 28) Fixed potential crash with the debugger tabs reset
 29) Added a search feature in the All Watch variables window
 27) Added video output display in a specific window
 28) Fixed potential crash with the debugger tabs reset
 29) Added a search feature in the All Watch variables window
+30) Support the structure's members in the Local variables window
 
 Release 4a (15th August 2019)
 -----------------------------
 
 Release 4a (15th August 2019)
 -----------------------------
dissimilarity index 64%
index 9cafa71..c59587f 100644 (file)
-//\r
-// localbrowser.cpp - Local variables\r
-//\r
-// by Jean-Paul Mari\r
-//\r
-// JPM = Jean-Paul Mari <djipi.mari@gmail.com>\r
-//  RG = Richard Goedeken\r
-//\r
-// Who  When        What\r
-// ---  ----------  -----------------------------------------------------------\r
-// JPM  11/03/2017  Created this file\r
-// JPM  Sept./2018  Added a status bar and better status report, and set information values in a tab\r
-//  RG   Jan./2021  Linux build fixes\r
-//\r
-\r
-// STILL TO DO:\r
-// Feature to list the pointer(s) in the code using the allocation\r
-// To set the information display at the right\r
-// To support the array\r
-// To support the static variables\r
-// To add a filter\r
-//\r
-\r
-#include <stdlib.h>\r
-\r
-#include "debugger/localbrowser.h"\r
-#include "memory.h"\r
-#include "debugger/DBGManager.h"\r
-#include "settings.h"\r
-#include "m68000/m68kinterface.h"\r
-\r
-\r
-// \r
-LocalBrowserWindow::LocalBrowserWindow(QWidget * parent/*= 0*/) : QWidget(parent, Qt::Dialog),\r
-layout(new QVBoxLayout),\r
-#ifdef LOCAL_LAYOUTTEXTS\r
-text(new QTextBrowser),\r
-#else\r
-TableView(new QTableView),\r
-model(new QStandardItemModel),\r
-#endif\r
-NbLocal(0),\r
-FuncName((char *)calloc(1, 1)),\r
-LocalInfo(NULL),\r
-statusbar(new QStatusBar)\r
-{\r
-       setWindowTitle(tr("Locals"));\r
-\r
-       // Set the font\r
-       QFont fixedFont("Lucida Console", 8, QFont::Normal);\r
-       fixedFont.setStyleHint(QFont::TypeWriter);\r
-\r
-#ifdef LOCAL_LAYOUTTEXTS\r
-       // Set original layout\r
-       text->setFont(fixedFont);\r
-       layout->addWidget(text);\r
-#else\r
-       // Set the new layout with proper identation and readibility\r
-       model->setColumnCount(3);\r
-       model->setHeaderData(0, Qt::Horizontal, QObject::tr("Name"));\r
-       model->setHeaderData(1, Qt::Horizontal, QObject::tr("Value"));\r
-       model->setHeaderData(2, Qt::Horizontal, QObject::tr("Type"));\r
-       // Information table\r
-       TableView->setModel(model);\r
-       TableView->setEditTriggers(QAbstractItemView::NoEditTriggers);\r
-       TableView->setShowGrid(0);\r
-       TableView->setFont(fixedFont);\r
-       TableView->verticalHeader()->setDefaultSectionSize(TableView->verticalHeader()->minimumSectionSize());\r
-       TableView->verticalHeader()->setDefaultAlignment(Qt::AlignRight);\r
-       layout->addWidget(TableView);\r
-#endif\r
-\r
-       // Status bar\r
-       layout->addWidget(statusbar);\r
-       setLayout(layout);\r
-}\r
-\r
-\r
-//\r
-LocalBrowserWindow::~LocalBrowserWindow(void)\r
-{\r
-       free(LocalInfo);\r
-       free(FuncName);\r
-}\r
-\r
-\r
-//\r
-bool LocalBrowserWindow::UpdateInfos(void)\r
-{\r
-       size_t Adr;\r
-       char *Ptr;\r
-\r
-       if (NbLocal = DBGManager_GetNbLocalVariables(Adr = m68k_get_reg(NULL, M68K_REG_PC)))\r
-       {\r
-               if (Ptr = DBGManager_GetFunctionName(Adr))\r
-               {\r
-                       if (strcmp(FuncName, Ptr))\r
-                       {\r
-                               if (FuncName = (char *)realloc(FuncName, strlen(Ptr) + 1))\r
-                               {\r
-                                       strcpy(FuncName, Ptr);\r
-\r
-                                       if (LocalInfo = (WatchInfo *)realloc(LocalInfo, (sizeof(WatchInfo) * NbLocal)))\r
-                                       {\r
-                                               for (size_t i = 0; i < NbLocal; i++)\r
-                                               {\r
-                                                       // Get local variable name and his information\r
-                                                       if (LocalInfo[i].PtrVariableName = DBGManager_GetLocalVariableName(Adr, i + 1))\r
-                                                       {\r
-                                                               LocalInfo[i].Op = DBGManager_GetLocalVariableOp(Adr, i + 1);\r
-                                                               LocalInfo[i].Adr = NULL;\r
-                                                               LocalInfo[i].PtrCPURegisterName = NULL;\r
-                                                               LocalInfo[i].TypeTag = DBGManager_GetLocalVariableTypeTag(Adr, i + 1);\r
-                                                               LocalInfo[i].PtrVariableBaseTypeName = DBGManager_GetLocalVariableTypeName(Adr, i + 1);\r
-                                                               LocalInfo[i].TypeEncoding = DBGManager_GetLocalVariableTypeEncoding(Adr, i + 1);\r
-                                                               LocalInfo[i].TypeByteSize = DBGManager_GetLocalVariableTypeByteSize(Adr, i + 1);\r
-                                                               LocalInfo[i].Offset = DBGManager_GetLocalVariableOffset(Adr, i + 1);\r
-                                                       }\r
-                                               }\r
-                                       }\r
-                               }\r
-                       }\r
-\r
-                       return true;\r
-               }\r
-       }\r
-\r
-       *FuncName = 0;\r
-\r
-       return false;\r
-}\r
-\r
-\r
-//\r
-void LocalBrowserWindow::RefreshContents(void)\r
-{\r
-#ifdef LOCAL_LAYOUTTEXTS\r
-       char string[1024];\r
-#endif\r
-       size_t Error = LOCAL_NOERROR;\r
-       QString Local;\r
-       QString MSG;\r
-       char Value1[100];\r
-#ifdef LOCAL_SUPPORTARRAY\r
-       char Value[100];\r
-#endif\r
-       char *PtrValue;\r
-\r
-       const char *CPURegName[] = { "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7", "A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7" };\r
-\r
-       if (isVisible())\r
-       {\r
-#ifndef LOCAL_LAYOUTTEXTS\r
-               model->setRowCount(0);\r
-#endif\r
-               if (UpdateInfos())\r
-               {\r
-                       for (size_t i = 0; i < NbLocal; i++)\r
-                       {\r
-                               if (LocalInfo[i].PtrVariableName)\r
-                               {\r
-                                       memset(Value1, 0, sizeof(Value1));\r
-#ifdef LOCAL_LAYOUTTEXTS\r
-                                       if (i)\r
-                                       {\r
-                                               Local += QString("<br>");\r
-                                       }\r
-#else\r
-                                       model->insertRow(i);\r
-#endif\r
-                                       // Local or parameters variables\r
-                                       if (((LocalInfo[i].Op >= DBG_OP_breg0) && (LocalInfo[i].Op <= DBG_OP_breg31)) || (LocalInfo[i].Op == DBG_OP_fbreg))\r
-                                       {\r
-                                               LocalInfo[i].Adr = m68k_get_reg(NULL, M68K_REG_A6) + LocalInfo[i].Offset;\r
-\r
-                                               if ((LocalInfo[i].Op == DBG_OP_fbreg))\r
-                                               {\r
-                                                       LocalInfo[i].Adr += 8;\r
-                                               }\r
-\r
-                                               if ((LocalInfo[i].Adr >= 0) && (LocalInfo[i].Adr < vjs.DRAM_size))\r
-                                               {\r
-                                                       if ((LocalInfo[i].TypeTag & (DBG_TAG_TYPE_array | DBG_TAG_TYPE_structure)))\r
-                                                       {\r
-#if defined(LOCAL_SUPPORTARRAY) || defined(LOCAL_SUPPORTSTRUCTURE)\r
-                                                               //memcpy(Value1, &jaguarMainRAM[LocalInfo[i].Adr], 20);\r
-#ifdef LOCAL_LAYOUTTEXTS\r
-                                                               //sprintf(Value, "\"%s\"", Value1);\r
-#else\r
-                                                               //sprintf(Value, "0x%06X, \"%s\"", LocalInfo[i].Adr, Value1);\r
-#endif\r
-                                                               //PtrValue = Value;\r
-                                                               PtrValue = NULL;\r
-#else\r
-                                                               PtrValue = NULL;\r
-#endif\r
-                                                       }\r
-                                                       else\r
-                                                       {\r
-                                                               PtrValue = DBGManager_GetVariableValueFromAdr(LocalInfo[i].Adr, LocalInfo[i].TypeEncoding, LocalInfo[i].TypeByteSize);\r
-                                                       }\r
-                                               }\r
-                                               else\r
-                                               {\r
-                                                       PtrValue = NULL;\r
-                                               }\r
-                                       }\r
-                                       else\r
-                                       {\r
-                                               // Value from CPU register\r
-                                               if ((LocalInfo[i].Op >= DBG_OP_reg0) && (LocalInfo[i].Op <= DBG_OP_reg31))\r
-                                               {\r
-                                                       LocalInfo[i].PtrCPURegisterName = (char *)CPURegName[(LocalInfo[i].Op - DBG_OP_reg0)];\r
-                                                       sprintf(Value1, "%d", m68k_get_reg(NULL, (m68k_register_t)((size_t)M68K_REG_D0 + (LocalInfo[i].Op - DBG_OP_reg0))));\r
-                                                       PtrValue = Value1;\r
-                                               }\r
-                                               else\r
-                                               {\r
-                                                       PtrValue = NULL;\r
-                                               }\r
-                                       }\r
-\r
-#ifndef LOCAL_LAYOUTTEXTS\r
-                                       model->setItem(i, 0, new QStandardItem(QString("%1").arg(LocalInfo[i].PtrVariableName)));\r
-#endif\r
-                                       // Check if the local variable is use by the code\r
-                                       if (!LocalInfo[i].Op)\r
-                                       {\r
-#ifdef LOCAL_LAYOUTTEXTS\r
-                                               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
-#else\r
-#endif\r
-                                       }\r
-                                       else\r
-                                       {\r
-#ifndef LOCAL_LAYOUTTEXTS\r
-                                               model->setItem(i, 1, new QStandardItem(QString("%1").arg(PtrValue)));\r
-#else\r
-                                               sprintf(string, "%i : %s | %s | ", (i + 1), (LocalInfo[i].PtrVariableBaseTypeName ? LocalInfo[i].PtrVariableBaseTypeName : (char *)"<font color='#ff0000'>N/A</font>"), LocalInfo[i].PtrVariableName);\r
-                                               Local += QString(string);\r
-\r
-                                               if ((unsigned int)LocalInfo[i].Adr)\r
-                                               {\r
-                                                       sprintf(string, "0x%06X", (unsigned int)LocalInfo[i].Adr);\r
-                                               }\r
-                                               else\r
-                                               {\r
-                                                       if (LocalInfo[i].PtrCPURegisterName)\r
-                                                       {\r
-                                                               sprintf(string, "<font color='#0000FF'>%s</font>", LocalInfo[i].PtrCPURegisterName);\r
-                                                       }\r
-                                                       else\r
-                                                       {\r
-                                                               sprintf(string, "%s", (char *)"<font color='#ff0000'>N/A</font>");\r
-                                                       }\r
-                                               }\r
-\r
-                                               Local += QString(string);\r
-                                               sprintf(string, " | %s", (!PtrValue ? (char *)"<font color='#ff0000'>N/A</font>" : PtrValue));\r
-#endif\r
-                                       }\r
-#ifndef LOCAL_LAYOUTTEXTS\r
-                                       model->setItem(i, 2, new QStandardItem(QString("%1").arg((LocalInfo[i].PtrVariableBaseTypeName ? LocalInfo[i].PtrVariableBaseTypeName : (char *)"<font color='#ff0000'>N/A</font>"))));\r
-#else\r
-                                       Local += QString(string);\r
-#endif\r
-                               }\r
-                       }\r
-\r
-                       MSG += QString("Ready");\r
-#ifdef LOCAL_LAYOUTTEXTS\r
-                       text->clear();\r
-                       text->setText(Local);\r
-#endif\r
-               }\r
-               else\r
-               {\r
-                       // No locals\r
-                       MSG += QString("No locals");\r
-                       Error = LOCAL_NOLOCALS;\r
-#ifdef LOCAL_LAYOUTTEXTS\r
-                       text->clear();\r
-#endif\r
-               }\r
-\r
-               // Display status bar\r
-               if (Error)\r
-               {\r
-                       if ((Error & LOCAL_WARNING))\r
-                       {\r
-                               statusbar->setStyleSheet("background-color: lightyellow; font: bold");\r
-                       }\r
-                       else\r
-                       {\r
-                               statusbar->setStyleSheet("background-color: tomato; font: bold");\r
-                       }\r
-               }\r
-               else\r
-               {\r
-                       statusbar->setStyleSheet("background-color: lightgreen; font: bold");\r
-               }\r
-               statusbar->showMessage(MSG);\r
-       }\r
-}\r
-\r
-\r
-// \r
-void LocalBrowserWindow::keyPressEvent(QKeyEvent * e)\r
-{\r
-       if (e->key() == Qt::Key_Escape)\r
-       {\r
-               hide();\r
-       }\r
-}\r
+//\r
+// localbrowser.cpp - Local variables\r
+//\r
+// by Jean-Paul Mari\r
+//\r
+// JPM = Jean-Paul Mari <djipi.mari@gmail.com>\r
+//  RG = Richard Goedeken\r
+//\r
+// Who  When        What\r
+// ---  ----------  -----------------------------------------------------------\r
+// JPM  11/03/2017  Created this file\r
+// JPM  Sept./2018  Added a status bar and better status report, and set information values in a tab\r
+//  RG   Jan./2021  Linux build fixes\r
+// JPM    May/2021  Display the structure's members\r
+//\r
+\r
+// STILL TO DO:\r
+// Feature to list the pointer(s) in the code using the allocation\r
+// To set the information display at the right\r
+// To support the array\r
+// To support the union\r
+// To support the static variables\r
+// To add a filter\r
+//\r
+\r
+#include <stdlib.h>\r
+\r
+#include "debugger/localbrowser.h"\r
+#include "memory.h"\r
+#include "debugger/DBGManager.h"\r
+#include "settings.h"\r
+#include "m68000/m68kinterface.h"\r
+\r
+\r
+// \r
+LocalBrowserWindow::LocalBrowserWindow(QWidget * parent/*= 0*/) : QWidget(parent, Qt::Dialog),\r
+layout(new QVBoxLayout),\r
+TableView(new QTreeView),\r
+model(new QStandardItemModel),\r
+NbLocal(0),\r
+FuncName(NULL),\r
+LocalInfo(NULL),\r
+statusbar(new QStatusBar)\r
+{\r
+       setWindowTitle(tr("Locals"));\r
+#ifdef LOCAL_FONTS\r
+       // Set the font\r
+       QFont fixedFont("Lucida Console", 8, QFont::Normal);\r
+       fixedFont.setStyleHint(QFont::TypeWriter);\r
+#endif\r
+       // Set the new layout with proper identation and readibility\r
+       model->setColumnCount(3);\r
+       model->setHeaderData(0, Qt::Horizontal, QObject::tr("Name"));\r
+       model->setHeaderData(1, Qt::Horizontal, QObject::tr("Value"));\r
+       model->setHeaderData(2, Qt::Horizontal, QObject::tr("Type"));\r
+       // Information table\r
+       TableView->setModel(model);\r
+       TableView->setEditTriggers(QAbstractItemView::NoEditTriggers);\r
+#ifdef LOCAL_FONTS\r
+       TableView->setFont(fixedFont);\r
+#endif\r
+       layout->addWidget(TableView);\r
+\r
+       // Status bar\r
+       layout->addWidget(statusbar);\r
+       setLayout(layout);\r
+}\r
+\r
+\r
+//\r
+LocalBrowserWindow::~LocalBrowserWindow(void)\r
+{\r
+       free(LocalInfo);\r
+}\r
+\r
+\r
+// Get the local variables information\r
+// Return true for a new local variables set\r
+bool LocalBrowserWindow::UpdateInfos(void)\r
+{\r
+       size_t Adr;\r
+       char *Ptr;\r
+\r
+       // get number of local variables located in the M68K PC address\r
+       if ((NbLocal = DBGManager_GetNbVariables(Adr = m68k_get_reg(NULL, M68K_REG_PC))))\r
+       {\r
+               // get function name from the M68K PC address\r
+               if ((Ptr = DBGManager_GetFunctionName(Adr)))\r
+               {\r
+                       // avoid to read the same information in case of the function has not changed\r
+                       if (!FuncName || strcmp(FuncName, Ptr))\r
+                       {\r
+                               // function is different\r
+                               FuncName = Ptr;\r
+                               if (LocalInfo = (S_LocalInfo*)realloc(LocalInfo, (sizeof(S_LocalInfo) * NbLocal)))\r
+                               {\r
+                                       for (size_t i = 0; i < NbLocal; i++)\r
+                                       {\r
+                                               // get local variable name and his information\r
+                                               if ((LocalInfo[i].PtrVariable = DBGManager_GetInfosVariable(Adr, i + 1)))\r
+                                               {\r
+                                                       LocalInfo[i].Adr = 0;\r
+                                                       LocalInfo[i].PtrCPURegisterName = NULL;\r
+                                               }\r
+                                       }\r
+                               }\r
+\r
+                               return true;\r
+                       }\r
+                       else\r
+                       {\r
+                               return false;\r
+                       }\r
+               }\r
+       }\r
+\r
+       FuncName = NULL;\r
+\r
+       return false;\r
+}\r
+\r
+\r
+// Prepare a complete row based on the variable information\r
+// The row will append rows if necessary\r
+QList<QStandardItem *> LocalBrowserWindow::prepareRow(void* Info)\r
+{\r
+       // set the list\r
+       QList<QStandardItem *> ptrRow = { new QStandardItem(((S_VariablesStruct*)Info)->PtrName), new QStandardItem(""), new QStandardItem(((S_VariablesStruct*)Info)->PtrTypeName) };\r
+\r
+       // check if variable has additional variables (such as structure)\r
+       if (size_t nb = ((S_VariablesStruct*)Info)->NbTabVariables)\r
+       {\r
+               for (size_t i = 0; i < nb; i++)\r
+               {\r
+                       ptrRow.first()->appendRow(prepareRow(((S_VariablesStruct*)Info)->TabVariables[i]));\r
+               }\r
+       }\r
+\r
+       // return the list\r
+       return ptrRow;\r
+}\r
+\r
+\r
+// Set the values of each line in accordance of the rows created from prepareRow() function\r
+void LocalBrowserWindow::setValueRow(QStandardItem *Row, size_t Adr, char* Value, void* Info)\r
+{\r
+       QStandardItem *child = Row->child(0, 1);\r
+       if (child)\r
+       {\r
+               // check if variable has additional variables list (such as structure)\r
+               if (size_t nb = ((S_VariablesStruct*)Info)->NbTabVariables)\r
+               {\r
+                       // get the pointer's value\r
+                       Adr = GET32(jagMemSpace, Adr);\r
+\r
+                       for (size_t i = 0; i < nb; i++)\r
+                       {\r
+                               // do not display arrays\r
+                               if (!((((S_VariablesStruct*)Info)->TabVariables[i]->TypeTag & DBG_TAG_TYPE_array)))\r
+                               {\r
+                                       // set value in the row\r
+                                       Value = DBGManager_GetVariableValueFromAdr(Adr + ((S_VariablesStruct*)Info)->TabVariables[i]->Offset, ((S_VariablesStruct*)Info)->TabVariables[i]->TypeEncoding, ((S_VariablesStruct*)Info)->TabVariables[i]->TypeByteSize);\r
+                                       child = Row->child((int)i, 1);\r
+                                       child->setText(QString("%1").arg(Value));\r
+                                       setValueRow(child, Adr + ((S_VariablesStruct*)Info)->TabVariables[i]->Offset, Value, (void*)((S_VariablesStruct*)Info)->TabVariables[i]);\r
+                               }\r
+                       }\r
+               }\r
+       }\r
+}\r
+\r
+\r
+// Refresh the local and/or parameters contents list\r
+void LocalBrowserWindow::RefreshContents(void)\r
+{\r
+       size_t Error = LOCAL_NOERROR;\r
+       QString Local;\r
+       QString MSG;\r
+       char Value1[100];\r
+       char *PtrValue;\r
+\r
+       // local variables may come from M68K registers\r
+       const char *CPURegName[] = { "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7", "A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7" };\r
+\r
+       // refresh only if local's window is displayed\r
+       if (isVisible())\r
+       {\r
+               // get local's information\r
+               if (UpdateInfos())\r
+               {\r
+                       // erase the previous variables list\r
+                       model->setRowCount(0);\r
+\r
+                       // loop on the locals found\r
+                       for (size_t i = 0; i < NbLocal; i++)\r
+                       {\r
+                               // check variable's name validity\r
+                               if (((S_VariablesStruct*)(LocalInfo[i].PtrVariable))->PtrName)\r
+                               {\r
+                                       // insert the row\r
+                                       model->appendRow(prepareRow(LocalInfo[i].PtrVariable));\r
+\r
+                                       // check if the local variable is use by the code\r
+                                       if (((S_VariablesStruct*)(LocalInfo[i].PtrVariable))->Op)\r
+                                       {\r
+                                               // local or parameters variables\r
+                                               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))\r
+                                               {\r
+                                                       // get variable's address\r
+                                                       LocalInfo[i].Adr = m68k_get_reg(NULL, M68K_REG_A6) + ((S_VariablesStruct*)(LocalInfo[i].PtrVariable))->Offset;\r
+                                                       // check variable's parameter op\r
+                                                       if ((((S_VariablesStruct*)(LocalInfo[i].PtrVariable))->Op == DBG_OP_fbreg))\r
+                                                       {\r
+                                                               LocalInfo[i].Adr += 8;\r
+                                                       }\r
+                                               }\r
+                                               else\r
+                                               {\r
+                                                       // variable type from CPU register\r
+                                                       if ((((S_VariablesStruct*)(LocalInfo[i].PtrVariable))->Op >= DBG_OP_reg0) && (((S_VariablesStruct*)(LocalInfo[i].PtrVariable))->Op <= DBG_OP_reg31))\r
+                                                       {\r
+                                                               // set color text for a register type variable\r
+                                                               model->item((int)i, 0)->setForeground(QColor(0, 0, 0xfe));\r
+                                                               model->item((int)i, 1)->setForeground(QColor(0, 0, 0xfe));\r
+                                                               model->item((int)i, 2)->setForeground(QColor(0, 0, 0xfe));\r
+                                                               // get the register's name\r
+                                                               LocalInfo[i].PtrCPURegisterName = (char *)CPURegName[(((S_VariablesStruct*)(LocalInfo[i].PtrVariable))->Op - DBG_OP_reg0)];\r
+                                                       }\r
+                                               }\r
+                                       }\r
+                                       else\r
+                                       {\r
+                                               // set color text for unused variable (no need to set it for the value's field as no values will be displayed)\r
+                                               model->item((int)i, 0)->setForeground(QColor(0xc8, 0xc8, 0xc8));\r
+                                               model->item((int)i, 2)->setForeground(QColor(0xc8, 0xc8, 0xc8));\r
+                                       }\r
+                               }\r
+                       }\r
+               }\r
+\r
+               // set the values in the fields\r
+               if (NbLocal)\r
+               {\r
+                       // loop on the locals found\r
+                       for (size_t i = 0; i < NbLocal; i++)\r
+                       {\r
+                               // variable's address must fit in RAM\r
+                               if ((LocalInfo[i].Adr >= 4) && (LocalInfo[i].Adr < vjs.DRAM_size))\r
+                               {\r
+                                       // get the variable's value\r
+                                       PtrValue = DBGManager_GetVariableValueFromAdr(LocalInfo[i].Adr, ((S_VariablesStruct*)(LocalInfo[i].PtrVariable))->TypeEncoding, ((S_VariablesStruct*)(LocalInfo[i].PtrVariable))->TypeByteSize);\r
+                               }\r
+                               else\r
+                               {\r
+                                       // check CPU register's type variable\r
+                                       if (LocalInfo[i].PtrCPURegisterName)\r
+                                       {\r
+                                               // get the value from register\r
+                                               memset(Value1, 0, sizeof(Value1));\r
+                                               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))));\r
+                                               PtrValue = Value1;\r
+                                       }\r
+                                       else\r
+                                       {\r
+                                               // no value can be found\r
+                                               PtrValue = NULL;\r
+                                       }\r
+                               }\r
+\r
+                               // do not display arrays\r
+                               if (!(((S_VariablesStruct*)LocalInfo[i].PtrVariable)->TypeTag & DBG_TAG_TYPE_array))\r
+                               {\r
+                                       // set the local's variable value\r
+                                       model->item((int)i, 1)->setText(QString("%1").arg(PtrValue));\r
+                                       setValueRow(model->item((int)i), LocalInfo[i].Adr, PtrValue, (S_VariablesStruct*)(LocalInfo[i].PtrVariable));\r
+                               }\r
+                       }\r
+\r
+                       MSG += QString("Ready");\r
+               }\r
+               else\r
+               {\r
+                       // erase the previous variables list\r
+                       model->setRowCount(0);\r
+\r
+                       // No locals\r
+                       MSG += QString("No locals");\r
+                       Error = LOCAL_NOLOCALS;\r
+               }\r
+\r
+               // display status bar\r
+               if (Error)\r
+               {\r
+                       if ((Error & LOCAL_WARNING))\r
+                       {\r
+                               statusbar->setStyleSheet("background-color: lightyellow; font: bold");\r
+                       }\r
+                       else\r
+                       {\r
+                               statusbar->setStyleSheet("background-color: tomato; font: bold");\r
+                       }\r
+               }\r
+               else\r
+               {\r
+                       statusbar->setStyleSheet("background-color: lightgreen; font: bold");\r
+               }\r
+               statusbar->showMessage(MSG);\r
+       }\r
+}\r
+\r
+\r
+// Handle keyboard actions\r
+void LocalBrowserWindow::keyPressEvent(QKeyEvent * e)\r
+{\r
+       // close / hide the window\r
+       if (e->key() == Qt::Key_Escape)\r
+       {\r
+               hide();\r
+       }\r
+}\r
index 9453353..249350f 100644 (file)
@@ -7,39 +7,30 @@
 #ifndef __LOCALBROWSER_H__\r
 #define __LOCALBROWSER_H__\r
 \r
 #ifndef __LOCALBROWSER_H__\r
 #define __LOCALBROWSER_H__\r
 \r
-//#define LOCAL_LAYOUTTEXTS                                            // Use a layout with just texts\r
-//#define LOCAL_SUPPORTARRAY                                           // Support array\r
-//#define LOCAL_SUPPORTSTRUCTURE                                       // Support structure\r
+//#define LOCAL_FONTS                                                          // Support for fonts modifications\r
 \r
 #include <QtWidgets/QtWidgets>\r
 #include <stdint.h>\r
 
 // Error code definitions\r
 #define        LOCAL_NOERROR           0x00\r
 \r
 #include <QtWidgets/QtWidgets>\r
 #include <stdint.h>\r
 
 // Error code definitions\r
 #define        LOCAL_NOERROR           0x00\r
-#define        LOCAL_ERROR                     0x80
 #define        LOCAL_WARNING           0x40\r
 #define        LOCAL_WARNING           0x40\r
+#define        LOCAL_ERROR                     0x80
 #define        LOCAL_NOLOCALS          (0x01 | LOCAL_WARNING)\r
 \r
 #define        LOCAL_NOLOCALS          (0x01 | LOCAL_WARNING)\r
 \r
-\r
 // \r
 class LocalBrowserWindow: public QWidget\r
 {\r
        Q_OBJECT\r
 \r
        //\r
 // \r
 class LocalBrowserWindow: public QWidget\r
 {\r
        Q_OBJECT\r
 \r
        //\r
-       typedef struct WatchInfo\r
+       typedef struct LocalInfo\r
        {\r
        {\r
-               size_t Op;\r
                size_t Adr;\r
                size_t Adr;\r
-               int Offset;\r
-               size_t TypeTag;\r
-               size_t TypeEncoding;\r
-               size_t TypeByteSize;\r
-               char *PtrVariableName;\r
-               char *PtrVariableBaseTypeName;\r
                char *PtrCPURegisterName;\r
                char *PtrCPURegisterName;\r
+               void *PtrVariable;\r
        }\r
        }\r
-       S_WatchInfo;\r
+       S_LocalInfo;\r
 \r
        public:\r
                LocalBrowserWindow(QWidget *parent = 0);\r
 \r
        public:\r
                LocalBrowserWindow(QWidget *parent = 0);\r
@@ -50,17 +41,15 @@ class LocalBrowserWindow: public QWidget
                bool UpdateInfos(void);\r
 \r
        protected:\r
                bool UpdateInfos(void);\r
 \r
        protected:\r
+               QList<QStandardItem *> prepareRow(void* Info);\r
+               void setValueRow(QStandardItem *Row, size_t Adr, char* Value, void* Info);\r
                void keyPressEvent(QKeyEvent *);\r
 \r
        private:\r
                QVBoxLayout *layout;\r
                void keyPressEvent(QKeyEvent *);\r
 \r
        private:\r
                QVBoxLayout *layout;\r
-#ifdef LOCAL_LAYOUTTEXTS\r
-               QTextBrowser *text;\r
-#else\r
-               QTableView *TableView;\r
+               QTreeView *TableView;\r
                QStandardItemModel *model;\r
                QStandardItemModel *model;\r
-#endif\r
-               WatchInfo *LocalInfo;\r
+               S_LocalInfo *LocalInfo;\r
                QStatusBar *statusbar;\r
                size_t NbLocal;\r
                char *FuncName;\r
                QStatusBar *statusbar;\r
                size_t NbLocal;\r
                char *FuncName;\r