#define strlen _strlen
#include <stdarg.h>
#include <unistd.h>
+#include <ctype.h>
#ifdef __APPLE__
#define __unix__
enum DebuggerState { none, prompt, loaded, running, stopped, terminated, error };
enum DebuggerEvent
{
- none, hit, breakEvent, signal, stepEnd, functionEnd, exit, valgrindStartPause;
+ none, hit, breakEvent, signal, stepEnd, functionEnd, exit, valgrindStartPause, locationReached;
- property bool canBeMonitored { get { return (this == hit || this == breakEvent || this == signal || this == stepEnd || this == functionEnd); } };
+ property bool canBeMonitored { get { return (this == hit || this == breakEvent || this == signal || this == stepEnd || this == functionEnd || this == locationReached); } };
};
-enum DebuggerAction { none, internal, restart, stop, selectFrame }; //, bpValidation
+enum DebuggerAction { none, internal, restart, stop, selectFrame, advance }; //, bpValidation
enum DebuggerReason
{
- unknown, endSteppingRange, functionFinished, signalReceived, breakpointHit
- //watchpointTrigger, readWatchpointTrigger, accessWatchpointTrigger, watchpointScope, locationReached,
+ unknown, endSteppingRange, functionFinished, signalReceived, breakpointHit, locationReached
+ //watchpointTrigger, readWatchpointTrigger, accessWatchpointTrigger, watchpointScope,
//exited, exitedNormally, exitedSignalled;
};
enum BreakpointType
{
- none, internalMain, internalWinMain, internalModulesLoaded, user, runToCursor, internalModuleLoad;
+ none, internalMain, internalWinMain, internalModulesLoaded, user, runToCursor, internalModuleLoad, internalEntry;
- property bool isInternal { get { return (this == internalMain || this == internalWinMain || this == internalModulesLoaded || this == internalModuleLoad); } };
+ property bool isInternal { get { return (this == internalMain || this == internalWinMain || this == internalModulesLoaded || this == internalModuleLoad || this == internalEntry); } };
property bool isUser { get { return (this == user || this == runToCursor); } };
};
enum DebuggerEvaluationError { none, symbolNotFound, memoryCantBeRead, unknown };
-enum DebuggerUserAction { none, start, resume, _break, stop, restart, selectThread, selectFrame, stepInto, stepOver, stepOut, runToCursor };
+enum DebuggerUserAction { none, start, resume, _break, stop, restart, selectThread, selectFrame, stepInto, stepOver, stepUntil, stepOut, runToCursor };
+enum GdbExecution
+{
+ none, run, _continue, next, until, advance, step, finish;
+ property bool suspendInternalBreakpoints { get { return (this == until || this == advance || this == step || this == finish); } };
+};
FileDialog debuggerFileDialog { type = selectDir };
char * targetDir;
char * targetFile;
+ GdbExecution gdbExecution;
DebuggerUserAction userAction;
DebuggerState state;
DebuggerEvent event;
DebuggerAction breakType;
+ char * breakString;
//DebuggerCommand lastCommand; // THE COMPILER COMPILES STUFF THAT DOES NOT EXIST???
GdbDataStop stopItem;
ValgrindLogThread vgLogThread { debugger = this };
ValgrindTargetThread vgTargetThread { debugger = this };
GdbThread gdbThread { debugger = this };
+
+ bool entryPoint;
+
Timer gdbTimer
{
delay = 0.0, userData = this;
case breakEvent:
case stepEnd:
case functionEnd:
+ case locationReached:
monitor = true;
ignoreBreakpoints = false;
break;
WatchesCodeEditorLinkInit();
EvaluateWatches();
+ ide.AdjustDebugMenus();
}
if(curEvent == signal)
{
if(BreakpointHit(stopItem, bpInternal, bpUser))
{
+ ide.AdjustDebugMenus();
if(bpUser && bpUser.type == runToCursor)
{
ignoreBreakpoints = false;
}
}
else
- GdbExecContinue(false);
+ {
+ if(breakType == advance && bpInternal && (bpInternal.type == internalMain || bpInternal.type == internalEntry))
+ {
+ breakType = none;
+ GdbExecAdvance(breakString, 0);
+ delete breakString;
+ }
+ else
+ GdbExecContinue(false);
+ }
}
if(stopItem)
__dpl2(file, line, _dpct, dplchan::debuggerState, 0, state, same ? " *** == *** " : " -> ", value);
#endif
state = value;
- if(!same && ide) ide.AdjustDebugMenus();
+ if(!same) ide.AdjustDebugMenus();
}
void CleanUp()
prjConfig = null;
codeEditor = null;
+ entryPoint = false;
+
/*GdbThread gdbThread
Timer gdbTimer*/
}
_dpl2(_dpct, dplchan::debuggerCall, 0, "Debugger::constructor");
ideProcessId = Process_GetCurrentProcessId();
+ sysBPs.Add(Breakpoint { type = internalEntry, enabled = false, level = -1 });
sysBPs.Add(Breakpoint { type = internalMain, function = "main", enabled = true, level = -1 });
#if defined(__WIN32__)
sysBPs.Add(Breakpoint { type = internalWinMain, function = "WinMain", enabled = true, level = -1 });
}
this.ignoreBreakpoints = ignoreBreakpoints;
this.userBreakOnInternalBreakpoint = userBreakOnInternalBreakpoint;
- if(result == loaded || result == stopped)
- GdbBreakpointsDelete(false, (userAction == stepOver || userAction == stepOut), ignoreBreakpoints);
}
return result;
}
}
}
+ void StepUntil(CompilerConfig compiler, ProjectConfig config, int bitDepth, bool useValgrind, bool ignoreBreakpoints)
+ {
+ _dpl2(_dpct, dplchan::debuggerCall, 0, "Debugger::StepUntil()");
+ _ChangeUserAction(stepUntil);
+ switch(StartSession(compiler, config, bitDepth, useValgrind, false, true, ignoreBreakpoints/*, false*/))
+ {
+ case loaded: GdbExecRun(); break;
+ case stopped: GdbExecUntil(null, 0); break;
+ }
+ }
+
void StepOut(bool ignoreBreakpoints)
{
_dpl2(_dpct, dplchan::debuggerCall, 0, "Debugger::StepOut()");
if(state == stopped)
{
this.ignoreBreakpoints = ignoreBreakpoints;
- GdbBreakpointsDelete(true, true, ignoreBreakpoints);
if(frameCount > 1)
GdbExecFinish();
else
}
}
- void RunToCursor(CompilerConfig compiler, ProjectConfig config, int bitDepth, bool useValgrind, char * absoluteFilePath, int lineNumber, bool ignoreBreakpoints, bool atSameLevel)
+ void RunToCursor(CompilerConfig compiler, ProjectConfig config, int bitDepth, bool useValgrind, char * absoluteFilePath, int lineNumber, bool ignoreBreakpoints, bool atSameLevel, bool oldImplementation)
{
char relativeFilePath[MAX_LOCATION];
- DebuggerState st = state;
_dpl2(_dpct, dplchan::debuggerCall, 0, "Debugger::RunToCursor()");
_ChangeUserAction(runToCursor);
- //if(st == loaded)
- //{
- // ide.outputView.ShowClearSelectTab(debug);
- // ide.outputView.debugBox.Logf($"Starting debug mode\n");
- //}
if(!ide.projectView.project.GetRelativePath(absoluteFilePath, relativeFilePath))
strcpy(relativeFilePath, absoluteFilePath);
delete bpRunToCursor;
}
- bpRunToCursor = Breakpoint { };
- bpRunToCursor.absoluteFilePath = absoluteFilePath;
- bpRunToCursor.relativeFilePath = relativeFilePath;
- bpRunToCursor.line = lineNumber;
- bpRunToCursor.type = runToCursor;
- bpRunToCursor.enabled = true;
- bpRunToCursor.level = atSameLevel ? frameCount - activeFrameLevel -1 : -1;
+ StartSession(compiler, config, bitDepth, useValgrind, false, false, ignoreBreakpoints/*, true*/);
- switch(StartSession(compiler, config, bitDepth, useValgrind, false, false, ignoreBreakpoints/*, true*/))
+#if 0
+ if(oldImplementation)
{
- case loaded:
- GdbExecRun();
- break;
- case stopped:
+ bpRunToCursor = Breakpoint { };
+ bpRunToCursor.absoluteFilePath = absoluteFilePath;
+ bpRunToCursor.relativeFilePath = relativeFilePath;
+ bpRunToCursor.line = lineNumber;
+ bpRunToCursor.type = runToCursor;
+ bpRunToCursor.enabled = true;
+ bpRunToCursor.level = atSameLevel ? frameCount - activeFrameLevel -1 : -1;
+ }
+#endif
+ if(state == loaded)
+ {
+ breakType = advance;
+ breakString = PrintString(relativeFilePath, ":", lineNumber);
+ GdbExecRun();
+ }
+ else if(state == stopped)
+ {
+ if(oldImplementation)
GdbExecContinue(true);
- break;
+ else
+ {
+ if(atSameLevel)
+ GdbExecUntil(absoluteFilePath, lineNumber);
+ else
+ GdbExecAdvance(absoluteFilePath, lineNumber);
+ }
}
}
return true;
}
- void GdbBreakpointsInsert()
+ void BreakpointsMaintenance()
{
- //_dpl2(_dpct, dplchan::debuggerBreakpoints, 0, "Debugger::GdbBreakpointsInsert()");
+ //_dpl2(_dpct, dplchan::debuggerBreakpoints, 0, "Debugger::BreakpointsMaintenance()");
if(symbols)
{
- if(userAction != stepOut && (userAction != stepOver || state == loaded))
+ if(gdbExecution.suspendInternalBreakpoints)
+ {
+ for(bp : sysBPs; bp.inserted)
+ UnsetBreakpoint(bp);
+ }
+ else
{
DirExpression objDir = ide.project.GetObjDir(currentCompiler, prjConfig, bitDepth);
for(bp : sysBPs; !bp.inserted)
delete objDir;
}
+ if(userAction != runToCursor && bpRunToCursor && bpRunToCursor.inserted)
+ UnsetBreakpoint(bpRunToCursor);
if(bpRunToCursor && !bpRunToCursor.inserted)
SetBreakpoint(bpRunToCursor, false);
- if(!ignoreBreakpoints)
+ if(ignoreBreakpoints)
+ {
+ for(bp : ide.workspace.breakpoints; bp.inserted)
+ UnsetBreakpoint(bp);
+ }
+ else
{
for(bp : ide.workspace.breakpoints; !bp.inserted && bp.type == user)
{
{
char * s; _dpl2(_dpct, dplchan::debuggerBreakpoints, 0, "Debugger::SetBreakpoint(", s=bp.CopyLocationString(false), ", ", removePath ? "**** removePath(true) ****" : "", ") -- ", bp.type); delete s;
breakpointError = false;
- if(symbols)
+ if(symbols && bp.enabled)
{
char * location = bp.CopyLocationString(removePath);
sentBreakInsert = true;
return !breakpointError;
}
- void GdbBreakpointsDelete(bool deleteRunToCursor, bool deleteInternalBreakpoints, bool deleteUserBreakpoints)
- {
- _dpl2(_dpct, dplchan::debuggerBreakpoints, 0, "Debugger::GdbBreakpointsDelete(deleteRunToCursor(", deleteRunToCursor, "))");
- if(symbols)
- {
- if(deleteInternalBreakpoints)
- {
- for(bp : sysBPs; bp.inserted)
- UnsetBreakpoint(bp);
- }
- if(deleteUserBreakpoints)
- {
- for(bp : ide.workspace.breakpoints; bp.inserted)
- UnsetBreakpoint(bp);
- }
- if(deleteRunToCursor && bpRunToCursor && bpRunToCursor.inserted)
- UnsetBreakpoint(bpRunToCursor);
- }
- }
-
void GdbGetStack()
{
_dpl2(_dpct, dplchan::debuggerCall, 0, "Debugger::GdbGetStack()");
{
char escaped[MAX_LOCATION];
strescpy(escaped, targetFile);
- GdbCommand(false, "file \"%s\"", escaped); //GDB/MI Missing Implementation -symbol-file, -target-attach
+ GdbCommand(false, "file \"%s\"", escaped); //GDB/MI Missing Implementation in 5.1.1 but we now have -file-exec-and-symbols / -file-exec-file / -file-symbol-file
if(!symbols)
return true;
printf("target remote | %s --pid=%d\n", vgdbCommand, targetProcessId);
GdbCommand(false, "target remote | %s --pid=%d", vgdbCommand, targetProcessId); // TODO: vgdb command config option
}
+ else
+ GdbCommand(false, "info target"); //GDB/MI Missing Implementation -file-list-symbol-files and -file-list-exec-sections
/*for(prj : ide.workspace.projects; prj != ide.workspace.projects.firstIterator.data)
GdbCommand(false, "-environment-directory \"%s\"", prj.topNode.path);*/
{
if(targeted)
{
- GdbBreakpointsDelete(true, true, true);
+ BreakpointsDeleteAll();
GdbCommand(false, "file"); //GDB/MI Missing Implementation -target-detach
targeted = false;
symbols = true;
{
_dpl2(_dpct, dplchan::debuggerCall, 0, "Debugger::GdbExecRun()");
GdbTargetSet();
+ if(!usingValgrind)
+ gdbExecution = run;
GdbExecCommon();
ShowDebuggerViews();
if(usingValgrind)
- GdbCommand(true, "-exec-continue");
+ GdbExecContinue(true);
else
GdbCommand(true, "-exec-run");
}
void GdbExecContinue(bool focus)
{
_dpl2(_dpct, dplchan::debuggerCall, 0, "Debugger::GdbExecContinue()");
+ gdbExecution = run;
GdbExecCommon();
GdbCommand(focus, "-exec-continue");
}
void GdbExecNext()
{
_dpl2(_dpct, dplchan::debuggerCall, 0, "Debugger::GdbExecNext()");
+ gdbExecution = next;
GdbExecCommon();
GdbCommand(true, "-exec-next");
}
+ void GdbExecUntil(char * absoluteFilePath, int lineNumber)
+ {
+ char relativeFilePath[MAX_LOCATION];
+ _dpl2(_dpct, dplchan::debuggerCall, 0, "Debugger::GdbExecUntil()");
+ gdbExecution = until;
+ GdbExecCommon();
+ if(absoluteFilePath)
+ {
+ if(!ide.projectView.project.GetRelativePath(absoluteFilePath, relativeFilePath))
+ strcpy(relativeFilePath, absoluteFilePath);
+ GdbCommand(true, "-exec-until %s:%d", relativeFilePath, lineNumber);
+ }
+ else
+ GdbCommand(true, "-exec-until");
+ }
+
+ void GdbExecAdvance(char * absoluteFilePathOrLocation, int lineNumber)
+ {
+ char relativeFilePath[MAX_LOCATION];
+ _dpl2(_dpct, dplchan::debuggerCall, 0, "Debugger::GdbExecAdvance()");
+ gdbExecution = advance;
+ GdbExecCommon();
+ if(lineNumber)
+ {
+ if(!ide.projectView.project.GetRelativePath(absoluteFilePathOrLocation, relativeFilePath))
+ strcpy(relativeFilePath, absoluteFilePathOrLocation);
+ GdbCommand(true, "advance %s:%d", relativeFilePath, lineNumber); // should use -exec-advance -- GDB/MI implementation missing
+ }
+ else
+ GdbCommand(true, "advance %s", absoluteFilePathOrLocation); // should use -exec-advance -- GDB/MI implementation missing
+ }
+
void GdbExecStep()
{
_dpl2(_dpct, dplchan::debuggerCall, 0, "Debugger::GdbExecStep()");
+ gdbExecution = step;
GdbExecCommon();
GdbCommand(true, "-exec-step");
}
void GdbExecFinish()
{
_dpl2(_dpct, dplchan::debuggerCall, 0, "Debugger::GdbExecFinish()");
+ gdbExecution = finish;
GdbExecCommon();
GdbCommand(true, "-exec-finish");
}
void GdbExecCommon()
{
//_dpl2(_dpct, dplchan::debuggerCall, 0, "Debugger::GdbExecCommon()");
- GdbBreakpointsInsert();
+ BreakpointsMaintenance();
}
#ifdef GDB_DEBUG_GUI
void GdbThreadMain(char * output)
{
int i;
+ char * t;
Array<char *> outTokens { minAllocSize = 50 };
Array<char *> subTokens { minAllocSize = 50 };
DebugListItem item { };
ide.outputView.debugBox.Logf($"Target doesn't contain debug information!\n");
ide.Update(null);
}
+ if(!entryPoint && (t = strstr(output, "Entry point:")))
+ {
+ char * addr = t + strlen("Entry point:");
+ t = addr;
+ if(*t++ == ' ' && *t++ == '0' && *t == 'x')
+ {
+ *addr = '*';
+ while(isxdigit(*++t));
+ *t = '\0';
+ for(bp : sysBPs; bp.type == internalEntry)
+ {
+ bp.function = addr;
+ bp.enabled = entryPoint = true;
+ break;
+ }
+ }
+ }
break;
case '^':
gdbReady = false;
HandleExit(reason, exitCode);
needReset = true;
}
- else if(!strcmp(reason, "breakpoint-hit"))
- {
- #ifdef _DEBUG
- if(stopItem)
- _dpl(0, "problem");
- #endif
- stopItem = GdbDataStop { };
- stopItem.reason = breakpointHit;
-
- for(i = tk+1; i < outTokens.count; i++)
- {
- TokenizeListItem(outTokens[i], item);
- StripQuotes(item.value, item.value);
- if(!strcmp(item.name, "bkptno"))
- stopItem.bkptno = atoi(item.value);
- else if(!strcmp(item.name, "thread-id"))
- stopItem.threadid = atoi(item.value);
- else if(!strcmp(item.name, "frame"))
- {
- item.value = StripCurlies(item.value);
- ParseFrame(stopItem.frame, item.value);
- }
- else if(!strcmp(item.name, "disp") || !strcmp(item.name, "stopped-threads") || !strcmp(item.name, "core"))
- _dpl2(_dpct, dplchan::gdbProtoIgnored, 0, "(", item.name, "=", item.value, ")");
- else
- _dpl2(_dpct, dplchan::gdbProtoUnknown, 0, "Unknown breakpoint hit item name (", item.name, "=", item.value, ")");
- }
-
- event = hit;
- }
- else if(!strcmp(reason, "end-stepping-range"))
+ else if(!strcmp(reason, "breakpoint-hit") ||
+ !strcmp(reason, "function-finished") ||
+ !strcmp(reason, "end-stepping-range") ||
+ !strcmp(reason, "location-reached") ||
+ !strcmp(reason, "signal-received"))
{
- #ifdef _DEBUG
- if(stopItem)
- _dpl(0, "problem");
- #endif
- stopItem = GdbDataStop { };
- stopItem.reason = endSteppingRange;
-
- for(i = tk+1; i < outTokens.count; i++)
- {
- TokenizeListItem(outTokens[i], item);
- StripQuotes(item.value, item.value);
- if(!strcmp(item.name, "thread-id"))
- stopItem.threadid = atoi(item.value);
- else if(!strcmp(item.name, "frame"))
- {
- item.value = StripCurlies(item.value);
- ParseFrame(stopItem.frame, item.value);
- }
- else if(!strcmp(item.name, "reason") || !strcmp(item.name, "bkptno"))
- _dpl2(_dpct, dplchan::gdbProtoIgnored, 0, "(", item.name, "=", item.value, ")");
- else
- _dpl2(_dpct, dplchan::gdbProtoUnknown, 0, "Unknown end of stepping range item name (", item.name, "=", item.value, ")");
- }
-
- event = stepEnd;
- ide.Update(null);
- }
- else if(!strcmp(reason, "function-finished"))
- {
- #ifdef _DEBUG
- if(stopItem)
- _dpl(0, "problem");
- #endif
+ char r = reason[0];
+#ifdef _DEBUG
+ if(stopItem) _dpl(0, "problem");
+#endif
stopItem = GdbDataStop { };
- stopItem.reason = functionFinished;
+ stopItem.reason = r == 'b' ? breakpointHit : r == 'f' ? functionFinished : r == 'e' ? endSteppingRange : r == 'l' ? locationReached : signalReceived;
for(i = tk+1; i < outTokens.count; i++)
{
item.value = StripCurlies(item.value);
ParseFrame(stopItem.frame, item.value);
}
- else if(!strcmp(item.name, "gdb-result-var"))
+ else if(stopItem.reason == breakpointHit && !strcmp(item.name, "bkptno"))
+ stopItem.bkptno = atoi(item.value);
+ else if(stopItem.reason == functionFinished && !strcmp(item.name, "gdb-result-var"))
stopItem.gdbResultVar = CopyString(item.value);
- else if(!strcmp(item.name, "return-value"))
+ else if(stopItem.reason == functionFinished && !strcmp(item.name, "return-value"))
stopItem.returnValue = CopyString(item.value);
+ else if(stopItem.reason == signalReceived && !strcmp(item.name, "signal-name"))
+ stopItem.name = CopyString(item.value);
+ else if(stopItem.reason == signalReceived && !strcmp(item.name, "signal-meaning"))
+ stopItem.meaning = CopyString(item.value);
else if(!strcmp(item.name, "stopped-threads"))
- _dpl2(_dpct, dplchan::gdbProtoIgnored, 0, "Advanced thread debugging not handled");
+ _dpl2(_dpct, dplchan::gdbProtoIgnored, 0, reason, ": Advanced thread debugging not handled");
else if(!strcmp(item.name, "core"))
- _dpl2(_dpct, dplchan::gdbProtoIgnored, 0, "Information (core) not used");
+ _dpl2(_dpct, dplchan::gdbProtoIgnored, 0, reason, ": Information (core) not used");
+ else if(!strcmp(item.name, "disp"))
+ _dpl2(_dpct, dplchan::gdbProtoIgnored, 0, reason, ": (", item.name, "=", item.value, ")");
else
- _dpl2(_dpct, dplchan::gdbProtoUnknown, 0, "Unknown function finished item name (", item.name, "=", item.value, ")");
+ _dpl2(_dpct, dplchan::gdbProtoUnknown, 0, "Unknown ", reason, " item name (", item.name, "=", item.value, ")");
}
- event = functionEnd;
- ide.Update(null);
- }
- else if(!strcmp(reason, "signal-received"))
- {
- #ifdef _DEBUG
- if(stopItem)
- _dpl(0, "problem");
- #endif
- stopItem = GdbDataStop { };
- stopItem.reason = signalReceived;
-
- for(i = tk+1; i < outTokens.count; i++)
- {
- TokenizeListItem(outTokens[i], item);
- StripQuotes(item.value, item.value);
- if(!strcmp(item.name, "signal-name"))
- stopItem.name = CopyString(item.value);
- else if(!strcmp(item.name, "signal-meaning"))
- stopItem.meaning = CopyString(item.value);
- else if(!strcmp(item.name, "thread-id"))
- stopItem.threadid = atoi(item.value);
- else if(!strcmp(item.name, "frame"))
- {
- item.value = StripCurlies(item.value);
- ParseFrame(stopItem.frame, item.value);
- }
- else
- _dpl2(_dpct, dplchan::gdbProtoUnknown, 0, "Unknown signal reveived item name (", item.name, "=", item.value, ")");
- }
- if(!strcmp(stopItem.name, "SIGTRAP"))
+ if(stopItem.reason == signalReceived && !strcmp(stopItem.name, "SIGTRAP"))
{
switch(breakType)
{
}
else
{
- event = signal;
+ event = r == 'b' ? hit : r == 'f' ? functionEnd : r == 'e' ? stepEnd : r == 'l' ? locationReached : signal;
+ ide.Update(null);
}
}
else if(!strcmp(reason, "watchpoint-trigger"))
_dpl2(_dpct, dplchan::gdbProtoIgnored, 0, "Reason access watchpoint trigger not handled");
else if(!strcmp(reason, "watchpoint-scope"))
_dpl2(_dpct, dplchan::gdbProtoIgnored, 0, "Reason watchpoint scope not handled");
- else if(!strcmp(reason, "location-reached"))
- _dpl2(_dpct, dplchan::gdbProtoIgnored, 0, "Reason location reached not handled");
else
_dpl2(_dpct, dplchan::gdbProtoUnknown, 0, "Unknown reason: ", reason);
}
extern int __ecereVMethodID_class_OnSaveEdit;
extern int __ecereVMethodID___ecereNameSpace__ecere__com__Module_OnLoad;
+class RTCMenuBits
+{
+public:
+ bool ignoreBreakpoints:1;
+ bool atSameLevel:1;
+ bool oldImplementation:1;
+};
+
class EditFileDialog : FileDialog
{
bool OnCreate()
}
};
- Menu fileMenu { menu, $"File", f }; // MenuPlacement?
+ Menu fileMenu { menu, $"File", f };
MenuItem { fileMenu, $"Save", s, Key { s, ctrl = true }, NotifySelect = MenuFileSave };
MenuItem { fileMenu, $"Save As...", a, NotifySelect = MenuFileSaveAs };
- Menu debugMenu { menu, $"Debug", d }; // MenuPlacement?
- MenuItem debugRunToCursor
- {
- debugMenu, $"Run To Cursor", c, Key { f10, ctrl = true };
- bool NotifySelect(MenuItem selection, Modifiers mods)
- {
- ProjectView projectView = ide.projectView;
- if(!projectView.buildInProgress)
- {
- int line = editBox.lineNumber + 1;
- if(projectView)
- {
- CompilerConfig compiler = ideSettings.GetCompilerConfig(ide.workspace.compiler);
- ProjectConfig config = projectView.project.config;
- int bitDepth = ide.workspace.bitDepth;
- bool useValgrind = ide.workspace.useValgrind;
- ide.debugger.RunToCursor(compiler, config, bitDepth, useValgrind, fileName, line, false, false);
- delete compiler;
- }
- }
- return true;
- }
- };
- MenuItem debugSkipRunToCursor
- {
- debugMenu, $"Run To Cursor Skipping Breakpoints", u, Key { f10, ctrl = true, shift = true };
- bool NotifySelect(MenuItem selection, Modifiers mods)
- {
- ProjectView projectView = ide.projectView;
- int line = editBox.lineNumber + 1;
- if(projectView)
- {
- CompilerConfig compiler = ideSettings.GetCompilerConfig(ide.workspace.compiler);
- ProjectConfig config = projectView.project.config;
- int bitDepth = ide.workspace.bitDepth;
- bool useValgrind = ide.workspace.useValgrind;
- ide.debugger.RunToCursor(compiler, config, bitDepth, useValgrind, fileName, line, true, false);
- delete compiler;
- }
- return true;
- }
- };
- MenuItem debugSkipRunToCursorAtSameLevel
+ Menu debugMenu { menu, $"Debug", d };
+ MenuItem debugRunToCursor { debugMenu, $"Run To Cursor", c, ctrlF10, id = RTCMenuBits { false, false, false }, NotifySelect = RTCMenu_NotifySelect; };
+ MenuItem debugSkipRunToCursor { debugMenu, $"Run To Cursor Skipping Breakpoints", u, Key { f10, ctrl = true, shift = true }, id = RTCMenuBits { true, false, false }, NotifySelect = RTCMenu_NotifySelect; };
+ MenuItem debugRunToCursorAtSameLevel { debugMenu, $"Run To Cursor At Same Level", l, altF10, id = RTCMenuBits { false, true, false }, NotifySelect = RTCMenu_NotifySelect; };
+ MenuItem debugSkipRunToCursorAtSameLevel { debugMenu, $"Run To Cursor At Same Level Skipping Breakpoints", g, Key { f10, shift = true, alt = true }, id = RTCMenuBits { true, true, false }, NotifySelect = RTCMenu_NotifySelect; };
+#if 0
+ MenuItem debugBpRunToCursor { debugMenu, $"BP Run To Cursor"/*, c, ctrlF10*/, id = RTCMenuBits { false, false, true }, NotifySelect = RTCMenu_NotifySelect; };
+ MenuItem debugBpSkipRunToCursor { debugMenu, $"BP Run To Cursor Skipping Breakpoints"/*, u, Key { f10, ctrl = true, shift = true }*/, id = RTCMenuBits { true, false, true }, NotifySelect = RTCMenu_NotifySelect; };
+ MenuItem debugBpRunToCursorAtSameLevel { debugMenu, $"BP Run To Cursor At Same Level"/*, l, altF10*/, id = RTCMenuBits { false, true, true }, NotifySelect = RTCMenu_NotifySelect; };
+ MenuItem debugBpSkipRunToCursorAtSameLevel { debugMenu, $"BP Run To Cursor At Same Level Skipping Breakpoints"/*, g, Key { f10, shift = true, alt = true }*/, id = RTCMenuBits { true, true, true }, NotifySelect = RTCMenu_NotifySelect; };
+#endif
+ bool RTCMenu_NotifySelect(MenuItem selection, Modifiers mods)
{
- debugMenu, $"Run To Cursor At Same Level Skipping Breakpoints", l, altF10;
- bool NotifySelect(MenuItem selection, Modifiers mods)
+ ProjectView projectView = ide.projectView;
+ if(!projectView.buildInProgress)
{
- ProjectView projectView = ide.projectView;
+ RTCMenuBits bits = (RTCMenuBits)selection.id;
int line = editBox.lineNumber + 1;
if(projectView)
{
ProjectConfig config = projectView.project.config;
int bitDepth = ide.workspace.bitDepth;
bool useValgrind = ide.workspace.useValgrind;
- ide.debugger.RunToCursor(compiler, config, bitDepth, useValgrind, fileName, line, true, true);
+ ide.debugger.RunToCursor(compiler, config, bitDepth, useValgrind, fileName, line, bits.ignoreBreakpoints, bits.atSameLevel, bits.oldImplementation);
delete compiler;
}
- return true;
}
- };
+ return true;
+ }
MenuDivider { debugMenu };
MenuItem debugToggleBreakpoint
{
*/
if(active && directActivation)
{
- AdjustDebugMenus(ide.areDebugMenusUnavailable, ide.isBreakpointTogglingUnavailable, ide.isDebuggerExecuting);
+ AdjustDebugMenus(ide.areDebugMenusUnavailable, ide.isBreakpointTogglingUnavailable, ide.isDebuggerExecuting, ide.isDebuggerStopped);
if(openedFileInfo)
openedFileInfo.Activate();
if(designer)
return false;
}
- void AdjustDebugMenus(bool unavailable, bool bpNoToggle, bool executing)
+ void AdjustDebugMenus(bool unavailable, bool bpNoToggle, bool executing, bool stopped)
{
debugRunToCursor.disabled = unavailable || executing;
debugSkipRunToCursor.disabled = unavailable || executing;
- debugSkipRunToCursorAtSameLevel.disabled = unavailable || executing;
+ debugRunToCursorAtSameLevel.disabled = unavailable || !stopped;
+ debugSkipRunToCursorAtSameLevel.disabled = unavailable || !stopped;
+#if 0
+ debugBpRunToCursor.disabled = unavailable || executing;
+ debugBpSkipRunToCursor.disabled = unavailable || executing;
+ debugBpRunToCursorAtSameLevel.disabled = unavailable || !stopped;
+ debugBpSkipRunToCursorAtSameLevel.disabled = unavailable || !stopped;
+#endif
debugToggleBreakpoint.disabled = bpNoToggle;
}
designer.fileName = title;
}
- AdjustDebugMenus(ide.areDebugMenusUnavailable, ide.isBreakpointTogglingUnavailable, ide.isDebuggerExecuting);
+ AdjustDebugMenus(ide.areDebugMenusUnavailable, ide.isBreakpointTogglingUnavailable, ide.isDebuggerExecuting, ide.isDebuggerStopped);
for(c = 0; c < CodeObjectType::enumSize; c++)
icons[c] = BitmapResource { iconNames[c], window = this };
bitmap = { ":actions/stepInto.png" };
bool NotifySelect(MenuItem selection, Modifiers mods)
{
- if(projectView)
- projectView.DebugStepInto();
+ if(projectView) projectView.DebugStepInto();
return true;
}
}
bitmap = { ":actions/stepOver.png" };
bool NotifySelect(MenuItem selection, Modifiers mods)
{
- if(projectView)
- projectView.DebugStepOver(false);
+ if(projectView) projectView.DebugStepOver(false);
+ return true;
+ }
+ }
+ MenuItem debugSkipStepOverItem
+ {
+ debugMenu, $"Step Over Skipping Breakpoints", e, shiftF10, disabled = true;
+ bool NotifySelect(MenuItem selection, Modifiers mods)
+ {
+ if(projectView) projectView.DebugStepOver(true);
return true;
}
}
bitmap = { ":actions/stepOut.png" };
bool NotifySelect(MenuItem selection, Modifiers mods)
{
- if(projectView)
- projectView.DebugStepOut(false);
+ if(projectView) projectView.DebugStepOut(false);
return true;
}
}
- MenuPlacement debugRunToCursorItem { debugMenu, $"Run To Cursor", c };
- MenuItem debugSkipStepOverItem
+ MenuItem debugSkipStepOutItem
{
- debugMenu, $"Step Over Skipping Breakpoints", e, shiftF10, disabled = true;
+ debugMenu, $"Step Out Skipping Breakpoints", n, Key { f11, ctrl = true, shift = true }, disabled = true;
+ bitmap = { ":actions/skipBreaks.png" };
bool NotifySelect(MenuItem selection, Modifiers mods)
{
- if(projectView)
- projectView.DebugStepOver(true);
+ if(projectView) projectView.DebugStepOut(true);
return true;
}
}
- MenuItem debugSkipStepOutItem
+#if 0
+ MenuItem debugStepUntilItem
{
- debugMenu, $"Step Out Skipping Breakpoints", t, Key { f11, ctrl = true, shift = true }, disabled = true;
- bitmap = { ":actions/skipBreaks.png" };
+ debugMenu, $"Step Over Until Next Line", x, disabled = true;
bool NotifySelect(MenuItem selection, Modifiers mods)
{
- if(projectView)
- projectView.DebugStepOut(true);
+ if(projectView) projectView.DebugStepUntil(false);
+ return true;
+ }
+ }
+ MenuItem debugSkipStepUntilItem
+ {
+ debugMenu, $"Step Over Until Next Line Skipping Breakpoints", e, Key { f10, shift = true, alt = true }, disabled = true;
+ bool NotifySelect(MenuItem selection, Modifiers mods)
+ {
+ if(projectView) projectView.DebugStepUntil(true);
return true;
}
}
+#endif
+ MenuPlacement debugRunToCursorItem { debugMenu, $"Run To Cursor", c };
MenuPlacement debugSkipRunToCursorItem { debugMenu, $"Run To Cursor Skipping Breakpoints", u };
- MenuPlacement debugSkipRunToCursorAtSameLevelItem { debugMenu, $"Run To Cursor At Same Level Skipping Breakpoints", l };
+ MenuPlacement debugRunToCursorAtSameLevelItem { debugMenu, $"Run To Cursor At Same Level", l };
+ MenuPlacement debugSkipRunToCursorAtSameLevelItem { debugMenu, $"Run To Cursor At Same Level Skipping Breakpoints", g };
+#if 0
+ MenuPlacement debugBpRunToCursorItem { debugMenu, $"BP Run To Cursor" };
+ MenuPlacement debugBpSkipRunToCursorItem { debugMenu, $"BP Run To Cursor Skipping Breakpoints" };
+ MenuPlacement debugBpRunToCursorAtSameLevelItem { debugMenu, $"BP Run To Cursor At Same Level" };
+ MenuPlacement debugBpSkipRunToCursorAtSameLevelItem { debugMenu, $"BP Run To Cursor At Same Level Skipping Breakpoints" };
+#endif
//MenuDivider { debugMenu };
//MenuPlacement debugToggleBreakpoint { debugMenu, "Toggle Breakpoint", t };
MenuPlacement imageMenu { menu, $"Image", i };
MenuDivider { viewMenu };
MenuItem viewColorPicker
{
- viewMenu, $"Color Picker...", c, Key { c, ctrl = true , shift = true };
+ viewMenu, $"Color Picker...", l, Key { c, ctrl = true , shift = true };
bool NotifySelect(MenuItem selection, Modifiers mods)
{
ColorPicker colorPicker { master = this };
projectView.buildInProgress == buildingMainProject;
} }
- property bool isBreakpointTogglingUnavailable { get {
- return !project;
- } }
-
- property bool isDebuggerExecuting { get {
- if(!ide.debugger)
- return false;
- else
- return ide.debugger.state == running;
- } }
+ property bool isBreakpointTogglingUnavailable { get { return !project; } }
+ property bool isDebuggerExecuting { get { if(ide.debugger) return ide.debugger.state == running; return false; } }
+ property bool isDebuggerStopped { get { if(ide.debugger) return ide.debugger.state == stopped; return false; } }
void AdjustDebugMenus()
{
debugStepIntoItem.disabled = unavailable || executing;
debugStepOverItem.disabled = unavailable || executing;
- debugStepOutItem.disabled = unavailable || executing || !active;
debugSkipStepOverItem.disabled = unavailable || executing;
+ debugStepOutItem.disabled = unavailable || executing || !active;
debugSkipStepOutItem.disabled = unavailable || executing || !active;
if(toolBar)
{
toolBar.buttonDebugStepInto.disabled = unavailable || executing;
toolBar.buttonDebugStepOver.disabled = unavailable || executing;
- toolBar.buttonDebugStepOut.disabled = unavailable || executing || !active;
toolBar.buttonDebugSkipStepOver.disabled = unavailable || executing;
- // toolBar.buttonDebugSkipStepOutItem.disabled = unavailable || executing;
+ toolBar.buttonDebugStepOut.disabled = unavailable || executing || !active;
+ //toolBar.buttonDebugSkipStepOutItem.disabled = unavailable || executing;
}
if((Designer)GetActiveDesigner())
{
CodeEditor codeEditor = ((Designer)GetActiveDesigner()).codeEditor;
if(codeEditor)
- codeEditor.AdjustDebugMenus(unavailable, bpNoToggle, executing);
+ codeEditor.AdjustDebugMenus(unavailable, bpNoToggle, executing, isDebuggerStopped);
}
}