-//\r
-// localbrowser.cpp - Local variables\r
-//\r
-// by Jean-Paul Mari\r
-//\r
-// JPM = Jean-Paul Mari <djipi.mari@gmail.com>\r
-//\r
-// Who When What\r
-// --- ---------- -----------------------------------------------------------\r
-// JPM 11/03/2017 Created this file\r
-//\r
-\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), text(new QTextBrowser),\r
-// layout(new QVBoxLayout), text(new QLabel),\r
-// refresh(new QPushButton(tr("Refresh"))),\r
-// address(new QLineEdit),\r
-// go(new QPushButton(tr("Go"))),\r
-// memBase(0),\r
- NbLocal(0),\r
- FuncName((char *)calloc(1, 1)),\r
- LocalInfo(NULL)\r
-{\r
- setWindowTitle(tr("Local"));\r
-\r
-// address->setInputMask("hhhhhh");\r
-// QHBoxLayout * hbox1 = new QHBoxLayout;\r
-// hbox1->addWidget(refresh);\r
-// hbox1->addWidget(address);\r
-// hbox1->addWidget(go);\r
-\r
- // Need to set the size as well...\r
-// resize(560, 480);\r
-\r
- QFont fixedFont("Lucida Console", 8, QFont::Normal);\r
-// QFont fixedFont("", 8, QFont::Normal);\r
- fixedFont.setStyleHint(QFont::TypeWriter);\r
- text->setFont(fixedFont);\r
-//// layout->setSizeConstraint(QLayout::SetFixedSize);\r
- setLayout(layout);\r
-\r
- layout->addWidget(text);\r
-// layout->addWidget(refresh);\r
-// layout->addLayout(hbox1);\r
-\r
-// connect(refresh, SIGNAL(clicked()), this, SLOT(RefreshContents()));\r
-// connect(go, SIGNAL(clicked()), this, SLOT(GoToAddress()));\r
-}\r
-\r
-\r
-//\r
-LocalBrowserWindow::~LocalBrowserWindow(void)\r
-{\r
- free(LocalInfo);\r
- free(FuncName);\r
-// NbLocal = 0;\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
- FuncName = (char *)realloc(FuncName, strlen(Ptr) + 1);\r
- strcpy(FuncName, Ptr);\r
-\r
- LocalInfo = (WatchInfo *)realloc(LocalInfo, (sizeof(WatchInfo) * NbLocal));\r
- for (size_t i = 0; i < NbLocal; i++)\r
- {\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
- return true;\r
- }\r
- }\r
-\r
- *FuncName = 0;\r
-\r
- return false;\r
-}\r
-\r
-\r
-//\r
-void LocalBrowserWindow::RefreshContents(void)\r
-{\r
- char string[1024];\r
-// char buf[64];\r
- QString Local;\r
- char Value[100];\r
- char *PtrValue;\r
-// size_t NbWatch, Adr;\r
-// WatchInfo PtrLocalInfo;\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
- if (UpdateInfos())\r
- {\r
-//#ifdef _MSC_VER\r
- //#pragma message("Warning: !!! Need to check the memory desalocation for LocalInfo !!!")\r
-//#else\r
- //#warning "!!! Need to do the memory desalocation for LocalInfo !!!"\r
-//#endif // _MSC_VER\r
-//#ifdef _MSC_VER\r
- //#pragma message("Warning: !!! Need to check the memory desalocation for FuncName !!!")\r
-//#else\r
- //#warning "!!! Need to do the memory desalocation for FuncName !!!"\r
-//#endif // _MSC_VER\r
-\r
- for (size_t i = 0; i < NbLocal; i++)\r
- {\r
- if (LocalInfo[i].PtrVariableName)\r
- {\r
- if (((LocalInfo[i].Op >= DBG_OP_breg0) && (LocalInfo[i].Op <= DBG_OP_breg31)))\r
- {\r
- LocalInfo[i].Adr = m68k_get_reg(NULL, M68K_REG_A6) + LocalInfo[i].Offset;\r
-\r
- if ((LocalInfo[i].Adr >= 0) && (LocalInfo[i].Adr < vjs.DRAM_size))\r
- {\r
- PtrValue = DBGManager_GetVariableValueFromAdr(LocalInfo[i].Adr, LocalInfo[i].TypeEncoding, LocalInfo[i].TypeByteSize);\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
- PtrValue = itoa(m68k_get_reg(NULL, (m68k_register_t)((size_t)M68K_REG_D0 + (LocalInfo[i].Op - DBG_OP_reg0))), Value, 10);\r
- }\r
- else\r
- {\r
- PtrValue = NULL;\r
- }\r
- }\r
-\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
- 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
- Local += QString(string);\r
- sprintf(string, " | %s", (!PtrValue ? (char *)"<font color='#ff0000'>N/A</font>" : PtrValue));\r
- Local += QString(string);\r
- sprintf(string, "<br>");\r
- Local += QString(string);\r
- }\r
- }\r
-\r
- text->clear();\r
- text->setText(Local);\r
- }\r
- else\r
- {\r
- text->clear();\r
- }\r
- }\r
-}\r
-\r
-\r
-#if 0\r
-void LocalBrowserWindow::keyPressEvent(QKeyEvent * e)\r
-{\r
- if (e->key() == Qt::Key_Escape)\r
- hide();\r
- else if (e->key() == Qt::Key_PageUp)\r
- {\r
- memBase -= 480;\r
-\r
- if (memBase < 0)\r
- memBase = 0;\r
-\r
- RefreshContents();\r
- }\r
- else if (e->key() == Qt::Key_PageDown)\r
- {\r
- memBase += 480;\r
-\r
- if (memBase > (0x200000 - 480))\r
- memBase = 0x200000 - 480;\r
-\r
- RefreshContents();\r
- }\r
- else if (e->key() == Qt::Key_Up || e->key() == Qt::Key_Minus)\r
- {\r
- memBase -= 16;\r
-\r
- if (memBase < 0)\r
- memBase = 0;\r
-\r
- RefreshContents();\r
- }\r
- else if (e->key() == Qt::Key_Down || e->key() == Qt::Key_Equal)\r
- {\r
- memBase += 16;\r
-\r
- if (memBase > (0x200000 - 480))\r
- memBase = 0x200000 - 480;\r
-\r
- RefreshContents();\r
- }\r
-}\r
-#endif\r
-\r
-\r
-#if 0\r
-void LocalBrowserWindow::GoToAddress(void)\r
-{\r
- bool ok;\r
- QString newAddress = address->text();\r
- memBase = newAddress.toUInt(&ok, 16);\r
- RefreshContents();\r
-}\r
-#endif\r
-\r
+//\r
+// localbrowser.cpp - Local variables\r
+//\r
+// by Jean-Paul Mari\r
+//\r
+// JPM = Jean-Paul Mari <djipi.mari@gmail.com>\r
+//\r
+// Who When What\r
+// --- ---------- -----------------------------------------------------------\r
+// JPM 11/03/2017 Created this file\r
+// JPM 09/08/2018 Added a status bar and better status report\r
+// JPM 09/08/2018 Set information values in a tab\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
+//\r
+\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
+ PtrValue = itoa(m68k_get_reg(NULL, (m68k_register_t)((size_t)M68K_REG_D0 + (LocalInfo[i].Op - DBG_OP_reg0))), Value1, 10);\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