Breakpoint window added.
This commit is contained in:
parent
35f877d3e1
commit
5f2358fcf2
3 changed files with 287 additions and 120 deletions
|
|
@ -108,6 +108,7 @@
|
|||
#define CMD_DEBUG 152
|
||||
#define CMD_WIN_CALLSTACK 153
|
||||
#define CMD_WIN_WATCH 154
|
||||
#define CMD_WIN_BREAKPOINTS 155
|
||||
#define IDE_MAX_IMM 1024
|
||||
#define IDE_DESIGN_W 400
|
||||
#define IDE_DESIGN_H 300
|
||||
|
|
@ -184,11 +185,14 @@ static void debugSetBreakTitles(bool paused);
|
|||
static void debugUpdateWindows(void);
|
||||
static void onBreakpointHit(void *ctx, int32_t line);
|
||||
static void onGutterClick(WidgetT *w, int32_t lineNum);
|
||||
static void navigateToCodeLine(int32_t fileIdx, int32_t codeLine, const char *procName, bool setDbgLine);
|
||||
static void debugNavigateToLine(int32_t concatLine);
|
||||
static void buildVmBreakpoints(void);
|
||||
static void showBreakpointWindow(void);
|
||||
static void showCallStackWindow(void);
|
||||
static void showLocalsWindow(void);
|
||||
static void showWatchWindow(void);
|
||||
static void updateBreakpointWindow(void);
|
||||
static void toggleBreakpointLine(int32_t line);
|
||||
static void updateCallStackWindow(void);
|
||||
static void updateLocalsWindow(void);
|
||||
|
|
@ -318,6 +322,7 @@ typedef struct {
|
|||
int32_t fileIdx; // project file index
|
||||
int32_t codeLine; // line within file's code section (1-based)
|
||||
int32_t procIdx; // procedure index at time of toggle (-1 = general)
|
||||
char procName[64]; // procedure name at time of toggle
|
||||
} IdeBreakpointT;
|
||||
|
||||
static IdeDebugStateE sDbgState = DBG_IDLE;
|
||||
|
|
@ -337,6 +342,8 @@ static WindowT *sWatchWin = NULL; // Watch window
|
|||
static WidgetT *sWatchList = NULL; // Watch ListView widget
|
||||
static WidgetT *sWatchInput = NULL; // Watch expression input
|
||||
static char *sWatchExprs[16]; // watch expressions (strdup'd)
|
||||
static WindowT *sBreakpointWin = NULL; // Breakpoints window
|
||||
static WidgetT *sBreakpointList = NULL; // Breakpoints ListView widget
|
||||
static int32_t sWatchExprCount = 0;
|
||||
|
||||
// ============================================================
|
||||
|
|
@ -715,6 +722,7 @@ static void buildWindow(void) {
|
|||
wmAddMenuItem(winMenu, "&Locals", CMD_WIN_LOCALS);
|
||||
wmAddMenuItem(winMenu, "Call &Stack", CMD_WIN_CALLSTACK);
|
||||
wmAddMenuItem(winMenu, "&Watch", CMD_WIN_WATCH);
|
||||
wmAddMenuItem(winMenu, "&Breakpoints", CMD_WIN_BREAKPOINTS);
|
||||
wmAddMenuSeparator(winMenu);
|
||||
wmAddMenuItem(winMenu, "&Project Explorer", CMD_WIN_PROJECT);
|
||||
wmAddMenuItem(winMenu, "&Toolbox", CMD_WIN_TOOLBOX);
|
||||
|
|
@ -1122,24 +1130,33 @@ static void toggleBreakpointLine(int32_t editorLine) {
|
|||
wgtInvalidatePaint(sEditor);
|
||||
}
|
||||
|
||||
updateBreakpointWindow();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Add new breakpoint
|
||||
IdeBreakpointT bp;
|
||||
memset(&bp, 0, sizeof(bp));
|
||||
bp.fileIdx = fileIdx;
|
||||
bp.codeLine = codeLine;
|
||||
bp.procIdx = sCurProcIdx;
|
||||
|
||||
if (sCurProcIdx >= 0 && sCurProcIdx < (int32_t)arrlen(sProcTable)) {
|
||||
snprintf(bp.procName, sizeof(bp.procName), "%s.%s",
|
||||
sProcTable[sCurProcIdx].objName, sProcTable[sCurProcIdx].evtName);
|
||||
} else {
|
||||
snprintf(bp.procName, sizeof(bp.procName), "(General)");
|
||||
}
|
||||
|
||||
arrput(sBreakpoints, bp);
|
||||
sBreakpointCount = (int32_t)arrlen(sBreakpoints);
|
||||
|
||||
dvxLog("[BP] Added: file=%d editorLine=%d codeLine=%d procIdx=%d",
|
||||
fileIdx, editorLine, codeLine, sCurProcIdx);
|
||||
|
||||
if (sEditor) {
|
||||
wgtInvalidatePaint(sEditor);
|
||||
}
|
||||
|
||||
updateBreakpointWindow();
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1182,6 +1199,87 @@ static uint32_t debugLineDecorator(int32_t lineNum, uint32_t *gutterColor, void
|
|||
}
|
||||
|
||||
|
||||
// ============================================================
|
||||
// navigateToCodeLine -- show a specific file/line/proc in the code editor
|
||||
// ============================================================
|
||||
//
|
||||
// fileIdx: project file index (-1 = current)
|
||||
// codeLine: 1-based line within the file's code section
|
||||
// procName: "Obj.Evt" (dot-separated) to match editor proc table, or NULL for General
|
||||
// setDbgLine: if true, update sDbgCurrentLine for the debug decorator
|
||||
|
||||
static void navigateToCodeLine(int32_t fileIdx, int32_t codeLine, const char *procName, bool setDbgLine) {
|
||||
// Track whether the file changed so we can force showProc
|
||||
bool fileChanged = (fileIdx >= 0 && fileIdx != sProject.activeFileIdx);
|
||||
|
||||
// Switch to the correct file if needed
|
||||
if (fileChanged) {
|
||||
activateFile(fileIdx, ViewCodeE);
|
||||
}
|
||||
|
||||
// Ensure code window exists
|
||||
if (!sCodeWin) {
|
||||
showCodeWindow();
|
||||
updateDropdowns();
|
||||
sCurProcIdx = -2;
|
||||
}
|
||||
|
||||
if (sCodeWin && !sCodeWin->visible) {
|
||||
dvxShowWindow(sAc, sCodeWin);
|
||||
}
|
||||
|
||||
if (sCodeWin) {
|
||||
dvxRaiseWindow(sAc, sCodeWin);
|
||||
}
|
||||
|
||||
// Find the target procedure in the editor's proc table
|
||||
int32_t targetProcIdx = -1;
|
||||
int32_t procCount = (int32_t)arrlen(sProcTable);
|
||||
|
||||
if (procName) {
|
||||
for (int32_t i = 0; i < procCount; i++) {
|
||||
char fullName[128];
|
||||
snprintf(fullName, sizeof(fullName), "%s.%s",
|
||||
sProcTable[i].objName, sProcTable[i].evtName);
|
||||
|
||||
if (strcasecmp(fullName, procName) == 0) {
|
||||
targetProcIdx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Switch to the target procedure (always force after a file change)
|
||||
if (targetProcIdx != sCurProcIdx || fileChanged) {
|
||||
showProc(targetProcIdx);
|
||||
}
|
||||
|
||||
// Update dropdowns to match
|
||||
if (targetProcIdx >= 0 && targetProcIdx < procCount) {
|
||||
selectDropdowns(sProcTable[targetProcIdx].objName,
|
||||
sProcTable[targetProcIdx].evtName);
|
||||
} else if (sObjDropdown) {
|
||||
wgtDropdownSetSelected(sObjDropdown, 0);
|
||||
}
|
||||
|
||||
// Compute editor-local line within the current proc
|
||||
int32_t editorLine = codeLine;
|
||||
|
||||
if (sCurProcIdx >= 0 && sCurProcIdx < procCount) {
|
||||
editorLine = codeLine - sProcTable[sCurProcIdx].lineNum + 1;
|
||||
}
|
||||
|
||||
if (setDbgLine) {
|
||||
sDbgCurrentLine = editorLine;
|
||||
}
|
||||
|
||||
if (sEditor) {
|
||||
wgtTextAreaGoToLine(sEditor, editorLine);
|
||||
wgtInvalidatePaint(sEditor);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ============================================================
|
||||
// debugNavigateToLine -- map concatenated source line to file and navigate
|
||||
// ============================================================
|
||||
|
|
@ -1205,59 +1303,29 @@ static void debugNavigateToLine(int32_t concatLine) {
|
|||
}
|
||||
}
|
||||
|
||||
// Switch to the correct file if needed
|
||||
if (fileIdx >= 0 && fileIdx != sProject.activeFileIdx) {
|
||||
activateFile(fileIdx, ViewCodeE);
|
||||
}
|
||||
|
||||
// Ensure the code editor is loaded for this file
|
||||
if (!sEditor && sCodeWin) {
|
||||
// File was activated but editor might not be set up
|
||||
}
|
||||
|
||||
// Show code window (recreate if it was closed).
|
||||
// Don't rebuild proc tables — they were built at session start.
|
||||
// Just recreate the window; showProc below will load the text.
|
||||
if (!sCodeWin) {
|
||||
showCodeWindow();
|
||||
updateDropdowns();
|
||||
sCurProcIdx = -2; // force showProc to reload even if same proc
|
||||
}
|
||||
|
||||
if (sCodeWin && !sCodeWin->visible) {
|
||||
dvxShowWindow(sAc, sCodeWin);
|
||||
}
|
||||
|
||||
if (sCodeWin) {
|
||||
dvxRaiseWindow(sAc, sCodeWin);
|
||||
}
|
||||
|
||||
// Find which procedure we're in using the VM's PC and the compiled
|
||||
// module's proc table. Then match by name to the editor's proc table.
|
||||
int32_t targetProcIdx = -1; // -1 = General section
|
||||
int32_t procCount = (int32_t)arrlen(sProcTable);
|
||||
// module's proc table, then build a dot-separated name for navigateToCodeLine.
|
||||
const char *procName = NULL;
|
||||
char procBuf[128];
|
||||
|
||||
if (sVm && sDbgModule) {
|
||||
// Find the proc whose codeAddr is closest to (but not exceeding) the PC
|
||||
const char *procName = NULL;
|
||||
int32_t bestAddr = -1;
|
||||
const char *compiledName = NULL;
|
||||
int32_t bestAddr = -1;
|
||||
|
||||
for (int32_t i = 0; i < sDbgModule->procCount; i++) {
|
||||
int32_t addr = sDbgModule->procs[i].codeAddr;
|
||||
|
||||
if (addr <= sVm->pc && addr > bestAddr) {
|
||||
bestAddr = addr;
|
||||
procName = sDbgModule->procs[i].name;
|
||||
bestAddr = addr;
|
||||
compiledName = sDbgModule->procs[i].name;
|
||||
}
|
||||
}
|
||||
|
||||
dvxLog("[Navigate] PC=%d bestAddr=%d procName=%s localLine=%d",
|
||||
sVm->pc, bestAddr, procName ? procName : "(null)", localLine);
|
||||
// Convert compiled name (Obj_Evt) to dot-separated (Obj.Evt) for matching
|
||||
if (compiledName) {
|
||||
int32_t procCount = (int32_t)arrlen(sProcTable);
|
||||
|
||||
// Match the compiled proc name to the editor's proc table
|
||||
if (procName) {
|
||||
for (int32_t i = 0; i < procCount; i++) {
|
||||
// Build the full proc name from obj + "_" + evt
|
||||
char fullName[128];
|
||||
|
||||
if (sProcTable[i].objName[0] &&
|
||||
|
|
@ -1268,44 +1336,17 @@ static void debugNavigateToLine(int32_t concatLine) {
|
|||
snprintf(fullName, sizeof(fullName), "%s", sProcTable[i].evtName);
|
||||
}
|
||||
|
||||
dvxLog("[Navigate] match? '%s' vs '%s'", fullName, procName);
|
||||
|
||||
if (strcasecmp(fullName, procName) == 0) {
|
||||
targetProcIdx = i;
|
||||
if (strcasecmp(fullName, compiledName) == 0) {
|
||||
snprintf(procBuf, sizeof(procBuf), "%s.%s",
|
||||
sProcTable[i].objName, sProcTable[i].evtName);
|
||||
procName = procBuf;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Switch to the target procedure
|
||||
if (targetProcIdx != sCurProcIdx) {
|
||||
showProc(targetProcIdx);
|
||||
}
|
||||
|
||||
// Update dropdowns to match
|
||||
if (targetProcIdx >= 0 && targetProcIdx < procCount) {
|
||||
selectDropdowns(sProcTable[targetProcIdx].objName,
|
||||
sProcTable[targetProcIdx].evtName);
|
||||
} else if (sObjDropdown) {
|
||||
wgtDropdownSetSelected(sObjDropdown, 0);
|
||||
}
|
||||
|
||||
// Compute editor-local line within the current proc
|
||||
int32_t editorLine = localLine;
|
||||
|
||||
if (sCurProcIdx >= 0 && sCurProcIdx < procCount) {
|
||||
editorLine = localLine - sProcTable[sCurProcIdx].lineNum + 1;
|
||||
}
|
||||
|
||||
// Store the editor-local line for the decorator
|
||||
sDbgCurrentLine = editorLine;
|
||||
dvxLog("[Navigate] targetProc=%d sCurProc=%d editorLine=%d", targetProcIdx, sCurProcIdx, editorLine);
|
||||
|
||||
if (sEditor) {
|
||||
wgtTextAreaGoToLine(sEditor, editorLine);
|
||||
wgtInvalidatePaint(sEditor);
|
||||
}
|
||||
navigateToCodeLine(fileIdx, localLine, procName, true);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1321,9 +1362,6 @@ static void buildVmBreakpoints(void) {
|
|||
arrfree(sVmBreakpoints);
|
||||
sVmBreakpoints = NULL;
|
||||
|
||||
dvxLog("[Debug] Building VM breakpoints: IDE=%d sourceMap=%d",
|
||||
sBreakpointCount, sProject.sourceMapCount);
|
||||
|
||||
for (int32_t i = 0; i < sBreakpointCount; i++) {
|
||||
int32_t fileIdx = sBreakpoints[i].fileIdx;
|
||||
int32_t codeLine = sBreakpoints[i].codeLine;
|
||||
|
|
@ -1341,16 +1379,11 @@ static void buildVmBreakpoints(void) {
|
|||
|
||||
int32_t vmLine = base + codeLine - 1;
|
||||
arrput(sVmBreakpoints, vmLine);
|
||||
|
||||
dvxLog(" BP %d: file=%d codeLine=%d startLine=%d isForm=%d -> vmLine=%d",
|
||||
i, fileIdx, codeLine, sProject.sourceMap[m].startLine,
|
||||
sProject.files[fileIdx].isForm, vmLine);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dvxLog(" VM breakpoints built: %d", (int32_t)arrlen(sVmBreakpoints));
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1460,10 +1493,7 @@ static void compileAndRun(void) {
|
|||
// If this is the active form in the designer, use form->code.
|
||||
if (sDesigner.form && i == sProject.activeFileIdx) {
|
||||
fileSrc = sDesigner.form->code;
|
||||
dvxLog("[Compile] Form %d: using designer code (code=%s)",
|
||||
i, fileSrc ? "yes" : "NULL");
|
||||
} else if (sProject.files[i].buffer) {
|
||||
dvxLog("[Compile] Form %d: extracting code from buffer", i);
|
||||
// Extract code from the stashed .frm text (after "End\n")
|
||||
const char *buf = sProject.files[i].buffer;
|
||||
const char *endTag = strstr(buf, "\nEnd\n");
|
||||
|
|
@ -1540,23 +1570,9 @@ static void compileAndRun(void) {
|
|||
}
|
||||
|
||||
if (!fileSrc) {
|
||||
dvxLog("[Compile] File %d: no source found, skipping", i);
|
||||
continue;
|
||||
}
|
||||
|
||||
{
|
||||
char preview[81];
|
||||
int32_t pl = (int32_t)strlen(fileSrc);
|
||||
if (pl > 80) { pl = 80; }
|
||||
memcpy(preview, fileSrc, pl);
|
||||
preview[pl] = '\0';
|
||||
// Replace newlines for readability
|
||||
for (int32_t j = 0; j < pl; j++) {
|
||||
if (preview[j] == '\n' || preview[j] == '\r') { preview[j] = '|'; }
|
||||
}
|
||||
dvxLog("[Compile] File %d: startLine=%d src=\"%s...\"", i, line, preview);
|
||||
}
|
||||
|
||||
int32_t startLine = line;
|
||||
|
||||
// Inject BEGINFORM directive for .frm code sections
|
||||
|
|
@ -1788,7 +1804,6 @@ static void runModule(BasModuleT *mod) {
|
|||
// Hide designer windows while the program runs.
|
||||
// Keep the code window visible if debugging (breakpoints or step-into).
|
||||
bool debugging = sDbgEnabled;
|
||||
dvxLog("[Run] debugging=%d sDbgEnabled=%d sCodeWin=%p", debugging, sDbgEnabled, (void *)sCodeWin);
|
||||
bool hadFormWin = sFormWin && sFormWin->visible;
|
||||
bool hadToolbox = sToolboxWin && sToolboxWin->visible;
|
||||
bool hadProps = sPropsWin && sPropsWin->visible;
|
||||
|
|
@ -3048,6 +3063,13 @@ static void onClose(WindowT *win) {
|
|||
sWatchList = NULL;
|
||||
sWatchInput = NULL;
|
||||
|
||||
if (sBreakpointWin && sBreakpointWin != win) {
|
||||
dvxDestroyWindow(sAc, sBreakpointWin);
|
||||
}
|
||||
|
||||
sBreakpointWin = NULL;
|
||||
sBreakpointList = NULL;
|
||||
|
||||
if (sFormWin) {
|
||||
dvxDestroyWindow(sAc, sFormWin);
|
||||
cleanupFormWin();
|
||||
|
|
@ -4068,6 +4090,10 @@ static void handleWindowCmd(int32_t cmd) {
|
|||
showWatchWindow();
|
||||
break;
|
||||
|
||||
case CMD_WIN_BREAKPOINTS:
|
||||
showBreakpointWindow();
|
||||
break;
|
||||
|
||||
case CMD_WIN_TOOLBOX:
|
||||
if (!sToolboxWin) {
|
||||
sToolboxWin = tbxCreate(sAc, &sDesigner);
|
||||
|
|
@ -5902,6 +5928,7 @@ static void showCodeWindow(void) {
|
|||
// (navigateToEventSub, onPrjFileDblClick, etc.) to prevent false dirty marking.
|
||||
|
||||
updateProjectMenuState();
|
||||
updateDirtyIndicators();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -5978,6 +6005,165 @@ static void showImmediateWindow(void) {
|
|||
}
|
||||
|
||||
|
||||
// ============================================================
|
||||
// showBreakpointWindow
|
||||
// ============================================================
|
||||
|
||||
#define MAX_BP_DISPLAY 64
|
||||
|
||||
static char sBpFiles[MAX_BP_DISPLAY][DVX_MAX_PATH];
|
||||
static char sBpProcs[MAX_BP_DISPLAY][64];
|
||||
static char sBpLines[MAX_BP_DISPLAY][12];
|
||||
static const char *sBpCells[MAX_BP_DISPLAY * 3];
|
||||
|
||||
static void onBreakpointWinClose(WindowT *win) {
|
||||
dvxHideWindow(sAc, win);
|
||||
}
|
||||
|
||||
|
||||
static void navigateToBreakpoint(int32_t bpIdx) {
|
||||
if (bpIdx < 0 || bpIdx >= sBreakpointCount) {
|
||||
return;
|
||||
}
|
||||
|
||||
IdeBreakpointT *bp = &sBreakpoints[bpIdx];
|
||||
const char *procName = (bp->procIdx >= 0 && bp->procName[0]) ? bp->procName : NULL;
|
||||
navigateToCodeLine(bp->fileIdx, bp->codeLine, procName, false);
|
||||
}
|
||||
|
||||
|
||||
static void onBreakpointListDblClick(WidgetT *w) {
|
||||
(void)w;
|
||||
|
||||
if (!sBreakpointList) {
|
||||
return;
|
||||
}
|
||||
|
||||
int32_t sel = wgtListViewGetSelected(sBreakpointList);
|
||||
navigateToBreakpoint(sel);
|
||||
}
|
||||
|
||||
|
||||
static void onBreakpointListKeyDown(WidgetT *w, int32_t keyCode, int32_t shift) {
|
||||
(void)w;
|
||||
(void)shift;
|
||||
|
||||
// Delete key
|
||||
if (keyCode != (0x53 | 0x100) && keyCode != 127) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!sBreakpointList || sBreakpointCount == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove selected breakpoints in reverse order to preserve indices
|
||||
for (int32_t i = sBreakpointCount - 1; i >= 0; i--) {
|
||||
if (wgtListViewIsItemSelected(sBreakpointList, i)) {
|
||||
arrdel(sBreakpoints, i);
|
||||
}
|
||||
}
|
||||
|
||||
sBreakpointCount = (int32_t)arrlen(sBreakpoints);
|
||||
updateBreakpointWindow();
|
||||
|
||||
// Repaint editor to remove breakpoint dots
|
||||
if (sEditor) {
|
||||
wgtInvalidatePaint(sEditor);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void showBreakpointWindow(void) {
|
||||
if (sBreakpointWin) {
|
||||
dvxShowWindow(sAc, sBreakpointWin);
|
||||
dvxRaiseWindow(sAc, sBreakpointWin);
|
||||
updateBreakpointWindow();
|
||||
return;
|
||||
}
|
||||
|
||||
int32_t winW = 320;
|
||||
int32_t winH = 180;
|
||||
int32_t winX = sAc->display.width - winW - 10;
|
||||
int32_t winY = sAc->display.height - winH - 10;
|
||||
|
||||
sBreakpointWin = dvxCreateWindow(sAc, "Breakpoints", winX, winY, winW, winH, true);
|
||||
|
||||
if (sBreakpointWin) {
|
||||
sBreakpointWin->onClose = onBreakpointWinClose;
|
||||
sBreakpointWin->onMenu = onMenu;
|
||||
sBreakpointWin->accelTable = sWin ? sWin->accelTable : NULL;
|
||||
sBreakpointWin->resizable = true;
|
||||
|
||||
WidgetT *root = wgtInitWindow(sAc, sBreakpointWin);
|
||||
|
||||
if (root) {
|
||||
sBreakpointList = wgtListView(root);
|
||||
|
||||
if (sBreakpointList) {
|
||||
sBreakpointList->weight = 100;
|
||||
sBreakpointList->onKeyDown = onBreakpointListKeyDown;
|
||||
sBreakpointList->onDblClick = onBreakpointListDblClick;
|
||||
wgtListViewSetMultiSelect(sBreakpointList, true);
|
||||
|
||||
static const ListViewColT cols[] = {
|
||||
{ "File", wgtChars(12), ListViewAlignLeftE },
|
||||
{ "Procedure", wgtChars(16), ListViewAlignLeftE },
|
||||
{ "Line", wgtChars(6), ListViewAlignRightE },
|
||||
};
|
||||
|
||||
wgtListViewSetColumns(sBreakpointList, cols, 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
updateBreakpointWindow();
|
||||
}
|
||||
|
||||
|
||||
// ============================================================
|
||||
// updateBreakpointWindow
|
||||
// ============================================================
|
||||
|
||||
static void updateBreakpointWindow(void) {
|
||||
if (!sBreakpointList || !sBreakpointWin || !sBreakpointWin->visible) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (sBreakpointCount == 0) {
|
||||
wgtListViewSetData(sBreakpointList, NULL, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
int32_t count = sBreakpointCount;
|
||||
|
||||
if (count > MAX_BP_DISPLAY) {
|
||||
count = MAX_BP_DISPLAY;
|
||||
}
|
||||
|
||||
for (int32_t i = 0; i < count; i++) {
|
||||
// File name
|
||||
if (sBreakpoints[i].fileIdx >= 0 && sBreakpoints[i].fileIdx < sProject.fileCount) {
|
||||
snprintf(sBpFiles[i], sizeof(sBpFiles[i]), "%s", sProject.files[sBreakpoints[i].fileIdx].path);
|
||||
} else {
|
||||
snprintf(sBpFiles[i], sizeof(sBpFiles[i]), "?");
|
||||
}
|
||||
|
||||
// Procedure name
|
||||
snprintf(sBpProcs[i], sizeof(sBpProcs[i]), "%s", sBreakpoints[i].procName);
|
||||
|
||||
// Line number
|
||||
snprintf(sBpLines[i], sizeof(sBpLines[i]), "%d", sBreakpoints[i].codeLine);
|
||||
|
||||
sBpCells[i * 3] = sBpFiles[i];
|
||||
sBpCells[i * 3 + 1] = sBpProcs[i];
|
||||
sBpCells[i * 3 + 2] = sBpLines[i];
|
||||
}
|
||||
|
||||
wgtListViewSetData(sBreakpointList, sBpCells, count);
|
||||
}
|
||||
|
||||
|
||||
// ============================================================
|
||||
// showLocalsWindow
|
||||
// ============================================================
|
||||
|
|
|
|||
|
|
@ -3372,18 +3372,6 @@ BasVmResultE basVmStep(BasVmT *vm) {
|
|||
uint16_t lineNum = readUint16(vm);
|
||||
vm->currentLine = lineNum;
|
||||
|
||||
// Debug trace: log first 20 OP_LINE values when breakpoints active
|
||||
if (vm->breakpointCount > 0) {
|
||||
static int32_t sLineLogCount = 0;
|
||||
|
||||
if (sLineLogCount < 20) {
|
||||
extern void dvxLog(const char *fmt, ...);
|
||||
dvxLog(" OP_LINE %d (bp[0]=%d, bpCount=%d)",
|
||||
(int)lineNum, vm->breakpoints[0], vm->breakpointCount);
|
||||
sLineLogCount++;
|
||||
}
|
||||
}
|
||||
|
||||
// Step into: break at any OP_LINE
|
||||
if (vm->debugBreak) {
|
||||
vm->debugBreak = false;
|
||||
|
|
|
|||
|
|
@ -2405,8 +2405,6 @@ static void pollKeyboard(AppContextT *ctx) {
|
|||
|
||||
// Ctrl+Esc -- system-wide hotkey (e.g. task manager)
|
||||
if (scancode == 0x01 && ascii == 0x1B && (shiftFlags & KEY_MOD_CTRL)) {
|
||||
dvxLog("[Key] Ctrl+Esc: onCtrlEsc=%p", (void *)ctx->onCtrlEsc);
|
||||
|
||||
if (ctx->onCtrlEsc) {
|
||||
ctx->onCtrlEsc(ctx->ctrlEscCtx);
|
||||
}
|
||||
|
|
@ -2414,11 +2412,6 @@ static void pollKeyboard(AppContextT *ctx) {
|
|||
continue;
|
||||
}
|
||||
|
||||
// Debug: log ESC presses that didn't match Ctrl+Esc
|
||||
if (scancode == 0x01) {
|
||||
dvxLog("[Key] ESC: scan=%02x ascii=%02x shift=%04x", scancode, ascii, shiftFlags);
|
||||
}
|
||||
|
||||
// F10 -- activate menu bar
|
||||
if (ascii == 0 && scancode == 0x44) {
|
||||
if (ctx->stack.focusedIdx >= 0) {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue