mirror of https://gitlab.com/basile.b/dexed.git
#97, refactor dbg, use interfaces + the entity connector
This commit is contained in:
parent
1a97a709c3
commit
92008c3a09
Binary file not shown.
After Width: | Height: | Size: 494 B |
Binary file not shown.
After Width: | Height: | Size: 415 B |
Binary file not shown.
After Width: | Height: | Size: 302 B |
|
@ -13,7 +13,7 @@
|
|||
<DpiAware Value="True"/>
|
||||
</XPManifest>
|
||||
<Icon Value="0"/>
|
||||
<Resources Count="94">
|
||||
<Resources Count="97">
|
||||
<Resource_0 FileName="../icons/window/layout_add.png" Type="RCDATA" ResourceName="LAYOUT_ADD"/>
|
||||
<Resource_1 FileName="../icons/window/layout.png" Type="RCDATA" ResourceName="LAYOUT"/>
|
||||
<Resource_2 FileName="../icons/window/application_go.png" Type="RCDATA" ResourceName="APPLICATION_GO"/>
|
||||
|
@ -108,6 +108,9 @@
|
|||
<Resource_91 FileName="../icons/other/pause.png" Type="RCDATA" ResourceName="PAUSE"/>
|
||||
<Resource_92 FileName="../icons/other/play.png" Type="RCDATA" ResourceName="PLAY"/>
|
||||
<Resource_93 FileName="../icons/other/power.png" Type="RCDATA" ResourceName="POWER"/>
|
||||
<Resource_94 FileName="../icons/other/stop.png" Type="RCDATA" ResourceName="STOP"/>
|
||||
<Resource_95 FileName="../icons/other/breaks.png" Type="RCDATA" ResourceName="BREAKS"/>
|
||||
<Resource_96 FileName="../icons/other/step.png" Type="RCDATA" ResourceName="STEP"/>
|
||||
</Resources>
|
||||
</General>
|
||||
<i18n>
|
||||
|
@ -236,7 +239,7 @@
|
|||
<PackageName Value="LCL"/>
|
||||
</Item7>
|
||||
</RequiredPackages>
|
||||
<Units Count="52">
|
||||
<Units Count="53">
|
||||
<Unit0>
|
||||
<Filename Value="coedit.lpr"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
|
@ -506,6 +509,10 @@
|
|||
<Filename Value="..\src\ce_dastworx.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit51>
|
||||
<Unit52>
|
||||
<Filename Value="..\src\ce_dbgitf.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit52>
|
||||
</Units>
|
||||
</ProjectOptions>
|
||||
<CompilerOptions>
|
||||
|
|
|
@ -12,7 +12,7 @@ uses
|
|||
ce_dockoptions, ce_shortcutseditor, ce_mru, ce_processes, ce_dubproject,
|
||||
ce_dialogs, ce_dubprojeditor, ce_controls, ce_dfmt, ce_lcldragdrop,
|
||||
ce_stringrange, ce_dlangmaps, ce_projgroup, ce_projutils, ce_d2synpresets,
|
||||
ce_dastworx;
|
||||
ce_dastworx, ce_dbgitf;
|
||||
|
||||
{$R *.res}
|
||||
|
||||
|
|
|
@ -0,0 +1,90 @@
|
|||
unit ce_dbgitf;
|
||||
|
||||
{$I ce_defines.inc}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils, ce_observer;
|
||||
|
||||
type
|
||||
|
||||
TBreakPointKind = (
|
||||
bpkBreak, // break
|
||||
bpkTrace // a message is output
|
||||
);
|
||||
|
||||
(**
|
||||
* ICEEDebugObserver can call any of the method during debugging
|
||||
*)
|
||||
ICEDebugger = interface
|
||||
procedure addBreakPoint(const fname: string; line: integer; kind: TBreakPointKind);
|
||||
procedure removeBreakPoint(const fname: string; line: integer);
|
||||
end;
|
||||
|
||||
// Enumerates th e reason why debuging breaks.
|
||||
TCEDebugBreakReason = (
|
||||
dbUnknown, // ?
|
||||
dbBreakPoint, // a break point is reached.
|
||||
dbSignal, // an unexpected signal is emitted.
|
||||
dbStep // step to this line
|
||||
);
|
||||
(**
|
||||
* An implementer is informed about a debuging session.
|
||||
*)
|
||||
ICEDebugObserver = interface(IObserverType)
|
||||
['ICEDebugObserver']
|
||||
// a debugging session starts. The ICEDebugger can be stored for the session.
|
||||
procedure debugStart(debugger: ICEDebugger);
|
||||
// a debugging session terminates. Any pointer to a ICEDebugger becomes invalid.
|
||||
procedure debugStop;
|
||||
// the debuger wants to know how many times debugQueryBreakPoints must be called.
|
||||
function debugQueryBpCount: integer;
|
||||
// the debuger wants breakpoints.
|
||||
procedure debugQueryBreakPoint(const index: integer; out fname: string;
|
||||
out line: integer; out kind: TBreakPointKind);
|
||||
// a break happens when code in fname at line is executed.
|
||||
procedure debugBreak(const fname: string; line: integer; reason: TCEDebugBreakReason);
|
||||
end;
|
||||
|
||||
(**
|
||||
* An implementer notifies is observer about a debuginf session.
|
||||
*)
|
||||
TCEDebugObserverSubject = specialize TCECustomSubject<ICEDebugObserver>;
|
||||
|
||||
// TCEDebugObserverSubject primitives
|
||||
procedure subjDebugStart(subj: TCEDebugObserverSubject; dbg: ICEDebugger);
|
||||
procedure subjDebugStop(subj: TCEDebugObserverSubject);
|
||||
procedure subjDebugBreak(subj: TCEDebugObserverSubject; const fname: string;
|
||||
line: integer; reason: TCEDebugBreakReason);
|
||||
|
||||
|
||||
implementation
|
||||
|
||||
procedure subjDebugStart(subj: TCEDebugObserverSubject; dbg: ICEDebugger);
|
||||
var
|
||||
i: integer;
|
||||
begin
|
||||
for i:= 0 to subj.observersCount-1 do
|
||||
(subj.observers[i] as ICEDebugObserver).debugStart(dbg);
|
||||
end;
|
||||
|
||||
procedure subjDebugStop(subj: TCEDebugObserverSubject);
|
||||
var
|
||||
i: integer;
|
||||
begin
|
||||
for i:= 0 to subj.observersCount-1 do
|
||||
(subj.observers[i] as ICEDebugObserver).debugStop;
|
||||
end;
|
||||
|
||||
procedure subjDebugBreak(subj: TCEDebugObserverSubject; const fname: string;
|
||||
line: integer; reason: TCEDebugBreakReason);
|
||||
var
|
||||
i: integer;
|
||||
begin
|
||||
for i:= 0 to subj.observersCount-1 do
|
||||
(subj.observers[i] as ICEDebugObserver).debugBreak(fname, line, reason);
|
||||
end;
|
||||
|
||||
end.
|
||||
|
|
@ -142,7 +142,7 @@ inherited CEGdbWidget: TCEGdbWidget
|
|||
Top = 0
|
||||
Caption = 'btnStop'
|
||||
OnClick = btnStopClick
|
||||
resourceName = 'CANCEL'
|
||||
resourceName = 'STOP'
|
||||
scaledSeparator = False
|
||||
end
|
||||
object btnContinue: TCEToolButton[7]
|
||||
|
|
114
src/ce_gdb.pas
114
src/ce_gdb.pas
|
@ -5,11 +5,11 @@ unit ce_gdb;
|
|||
interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils, FileUtil, ListFilterEdit, Forms, Controls, Graphics,
|
||||
RegExpr, ComCtrls, PropEdits, GraphPropEdits, RTTIGrids, Dialogs, ExtCtrls,
|
||||
Menus, strutils, Buttons, StdCtrls, process, fpjson,
|
||||
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, RegExpr, ComCtrls,
|
||||
PropEdits, GraphPropEdits, RTTIGrids, Dialogs, ExtCtrls, Menus, Buttons,
|
||||
StdCtrls, process, fpjson,
|
||||
ce_common, ce_interfaces, ce_widget, ce_processes, ce_observer, ce_synmemo,
|
||||
ce_sharedres, ce_stringrange, ce_dsgncontrols, ce_dialogs;
|
||||
ce_sharedres, ce_stringrange, ce_dsgncontrols, ce_dialogs, ce_dbgitf;
|
||||
|
||||
type
|
||||
|
||||
|
@ -211,7 +211,7 @@ type
|
|||
end;
|
||||
|
||||
{ TCEGdbWidget }
|
||||
TCEGdbWidget = class(TCEWidget, ICEProjectObserver, ICEDocumentObserver)
|
||||
TCEGdbWidget = class(TCEWidget, ICEProjectObserver, ICEDocumentObserver, ICEDebugger)
|
||||
btnContinue: TCEToolButton;
|
||||
btnPause: TCEToolButton;
|
||||
btnReg: TCEToolButton;
|
||||
|
@ -237,6 +237,7 @@ type
|
|||
protected
|
||||
procedure setToolBarFlat(value: boolean); override;
|
||||
private
|
||||
fSubj: TCEDebugObserverSubject;
|
||||
fDoc: TCESynMemo;
|
||||
fProj: ICECommonProject;
|
||||
fJson: TJsonObject;
|
||||
|
@ -251,8 +252,7 @@ type
|
|||
//
|
||||
procedure startDebugging;
|
||||
procedure killGdb;
|
||||
procedure updateFileLineBrks;
|
||||
procedure editorModBrk(sender: TCESynMemo; line: integer; modification: TBreakPointModification);
|
||||
procedure storeObserversBreakpoints;
|
||||
// GDB output processors
|
||||
procedure gdboutQuiet(sender: TObject);
|
||||
procedure gdboutJsonize(sender: TObject);
|
||||
|
@ -273,6 +273,9 @@ type
|
|||
procedure docFocused(document: TCESynMemo);
|
||||
procedure docChanged(document: TCESynMemo);
|
||||
procedure docClosing(document: TCESynMemo);
|
||||
//
|
||||
procedure addBreakPoint(const fname: string; line: integer; kind: TBreakPointKind);
|
||||
procedure removeBreakPoint(const fname: string; line: integer);
|
||||
public
|
||||
constructor create(aOwner: TComponent); override;
|
||||
destructor destroy; override;
|
||||
|
@ -413,6 +416,7 @@ begin
|
|||
stateViewer.TIObject := fInspState;
|
||||
fJson := TJsonObject.Create;
|
||||
fStackItems := TStackItems.create;
|
||||
fSubj:= TCEDebugObserverSubject.Create;
|
||||
fShowCLI := true;
|
||||
//
|
||||
AssignPng(btnSendCom, 'ACCEPT');
|
||||
|
@ -427,6 +431,7 @@ begin
|
|||
fJson.Free;
|
||||
fStackItems.Free;
|
||||
EntitiesConnector.removeObserver(self);
|
||||
fSubj.free;
|
||||
inherited;
|
||||
end;
|
||||
|
||||
|
@ -473,14 +478,10 @@ end;
|
|||
{$REGION ICEDocumentObserver ---------------------------------------------------}
|
||||
procedure TCEGdbWidget.docNew(document: TCESynMemo);
|
||||
begin
|
||||
if document.isDSource then
|
||||
document.onBreakpointModify := @editorModBrk;
|
||||
end;
|
||||
|
||||
procedure TCEGdbWidget.docFocused(document: TCESynMemo);
|
||||
begin
|
||||
if document.isDSource then
|
||||
document.onBreakpointModify := @editorModBrk;
|
||||
fDoc := document;
|
||||
end;
|
||||
|
||||
|
@ -505,49 +506,41 @@ begin
|
|||
FreeAndNil(fGdb);
|
||||
end;
|
||||
|
||||
procedure TCEGdbWidget.updateFileLineBrks;
|
||||
procedure TCEGdbWidget.storeObserversBreakpoints;
|
||||
var
|
||||
i,j: integer;
|
||||
doc: TCESynMemo;
|
||||
obs: ICEDebugObserver;
|
||||
nme: string;
|
||||
lne: integer;
|
||||
knd: TBreakPointKind;
|
||||
begin
|
||||
fFileLineBrks.Clear;
|
||||
if fDocHandler = nil then exit;
|
||||
//
|
||||
for i:= 0 to fDocHandler.documentCount-1 do
|
||||
for i:= 0 to fSubj.observersCount-1 do
|
||||
begin
|
||||
doc := fDocHandler.document[i];
|
||||
if not doc.isDSource then
|
||||
continue;
|
||||
nme := doc.fileName;
|
||||
if not nme.fileExists then
|
||||
continue;
|
||||
{$PUSH}{$WARNINGS OFF}{$HINTS OFF}
|
||||
for j := 0 to doc.breakPointsCount-1 do
|
||||
fFileLineBrks.AddObject(nme, TObject(pointer(doc.BreakPointLine(j))));
|
||||
{$POP}
|
||||
obs := fSubj.observers[i] as ICEDebugObserver;
|
||||
for j := 0 to obs.debugQueryBpCount-1 do
|
||||
begin
|
||||
obs.debugQueryBreakPoint(j, nme, lne, knd);
|
||||
{$PUSH}{$WARNINGS OFF}{$HINTS OFF}
|
||||
fFileLineBrks.AddObject(nme, TObject(pointer(lne)));
|
||||
{$POP}
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TCEGdbWidget.editorModBrk(sender: TCESynMemo; line: integer; modification: TBreakPointModification);
|
||||
var
|
||||
str: string;
|
||||
nme: string;
|
||||
const
|
||||
cmd: array[TBreakPointModification] of string = ('break ', 'clear ');
|
||||
procedure TCEGdbWidget.addBreakPoint(const fname: string; line: integer; kind: TBreakPointKind);
|
||||
begin
|
||||
// set only breakpoint in live, while debugging
|
||||
// note: only works if execution is paused (breakpoint)
|
||||
// and not inside a loop (for ex. with sleep).
|
||||
if fGdb = nil then exit;
|
||||
if not fGdb.Running then exit;
|
||||
nme := sender.fileName;
|
||||
if not nme.fileExists then exit;
|
||||
//
|
||||
str := cmd[modification] + nme + ':' + intToStr(line);
|
||||
fGdb.Suspend;
|
||||
gdbCommand(str);
|
||||
fGdb.Resume;
|
||||
if fGdb.isNil or not fGdb.Running then
|
||||
exit;
|
||||
//TODO-cGDB: handle trace points
|
||||
gdbCommand('break ' + fname + ':' + intToStr(line));
|
||||
end;
|
||||
|
||||
procedure TCEGdbWidget.removeBreakPoint(const fname: string; line: integer);
|
||||
begin
|
||||
if fGdb.isNil or not fGdb.Running then
|
||||
exit;
|
||||
gdbCommand('clear ' + fname + ':' + intToStr(line));
|
||||
end;
|
||||
|
||||
procedure TCEGdbWidget.startDebugging;
|
||||
|
@ -556,10 +549,15 @@ var
|
|||
i: integer;
|
||||
begin
|
||||
// protect
|
||||
if fProj = nil then exit;
|
||||
if fProj.binaryKind <> executable then exit;
|
||||
if fProj = nil then
|
||||
exit;
|
||||
if fProj.binaryKind <> executable then
|
||||
exit;
|
||||
str := fProj.outputFilename;
|
||||
if not str.fileExists then exit;
|
||||
if not str.fileExists then
|
||||
exit;
|
||||
// TODO-cDBG: detect finish event and notifiy the observers.
|
||||
subjDebugStart(fSubj, self as ICEDebugger);
|
||||
// gdb process
|
||||
killGdb;
|
||||
fGdb := TCEProcess.create(nil);
|
||||
|
@ -571,14 +569,13 @@ begin
|
|||
fGdb.OnTerminate:= @gdboutQuiet;
|
||||
fgdb.execute;
|
||||
// file:line breakpoints
|
||||
updateFileLineBrks;
|
||||
storeObserversBreakpoints;
|
||||
for i:= 0 to fFileLineBrks.Count-1 do
|
||||
begin
|
||||
str := 'break ' + fFileLineBrks.Strings[i] + ':' + intToStr(PtrUInt(fFileLineBrks.Objects[i])) + #10;
|
||||
fGdb.Input.Write(str[1], str.length);
|
||||
end;
|
||||
// break on druntime exceptions + any throw'
|
||||
fGdb.OnReadData := @gdboutQuiet;
|
||||
gdbCommand('break onAssertError');
|
||||
gdbCommand('break onAssertErrorMsg');
|
||||
gdbCommand('break onUnittestErrorMsg');
|
||||
|
@ -804,11 +801,7 @@ begin
|
|||
if val.isNotNil then
|
||||
line := strToInt(val.AsString);
|
||||
if (line <> -1) and fullname.fileExists then
|
||||
begin
|
||||
getMultiDocHandler.openDocument(fullname);
|
||||
fDoc.setFocus;
|
||||
fDoc.CaretY:= line;
|
||||
end;
|
||||
subjDebugBreak(fSubj, fullname, line, dbBreakPoint);
|
||||
end;
|
||||
end
|
||||
|
||||
|
@ -837,15 +830,8 @@ begin
|
|||
+ LineEnding + 'Do you wish to pause execution ?', [signame, sigmean, line, fullname]),
|
||||
'Unexpected signal received') = mrNo then
|
||||
gdbCommand('continue', @gdboutJsonize)
|
||||
else
|
||||
begin
|
||||
if (line <> -1) and fullname.fileExists then
|
||||
begin
|
||||
getMultiDocHandler.openDocument(fullname);
|
||||
fDoc.setFocus;
|
||||
fDoc.CaretY:= line;
|
||||
end;
|
||||
end;
|
||||
else if (line <> -1) and fullname.fileExists then
|
||||
subjDebugBreak(fSubj, fullname, line, dbSignal);
|
||||
end;
|
||||
|
||||
end;
|
||||
|
@ -992,7 +978,7 @@ end;
|
|||
|
||||
procedure TCEGdbWidget.btnStopClick(Sender: TObject);
|
||||
begin
|
||||
gdbCommand('kill', @gdboutQuiet);
|
||||
gdbCommand('kill', @gdboutJsonize);
|
||||
killGdb;
|
||||
end;
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ type
|
|||
* Each project format has its own dedicated editors.
|
||||
* A few common properties allow some generic operations whatever is the format.
|
||||
*)
|
||||
ICECommonProject = interface(ISubjectType)
|
||||
ICECommonProject = interface
|
||||
['ICECommonProject']
|
||||
|
||||
// general properties ------------------------------------------------------
|
||||
|
@ -98,7 +98,7 @@ type
|
|||
(**
|
||||
* An implementer declares some actions on demand.
|
||||
*)
|
||||
ICEContextualActions = interface(ISubjectType)
|
||||
ICEContextualActions = interface(IObserverType)
|
||||
['ICEContextualActions']
|
||||
// declares a context name for the actions
|
||||
function contextName: string;
|
||||
|
@ -113,7 +113,7 @@ type
|
|||
(**
|
||||
* An implementer is informed about the current file(s).
|
||||
*)
|
||||
ICEDocumentObserver = interface(ISubjectType)
|
||||
ICEDocumentObserver = interface(IObserverType)
|
||||
['ICEDocumentObserver']
|
||||
// document has been created (empty, runnable, project source, ...).
|
||||
procedure docNew(document: TCESynMemo);
|
||||
|
@ -139,7 +139,7 @@ type
|
|||
* - the current project, the one that's active) which can be either the FSP
|
||||
* or one of the project in the group.
|
||||
*)
|
||||
ICEProjectObserver = interface(ISubjectType)
|
||||
ICEProjectObserver = interface(IObserverType)
|
||||
['ICEProjectObserver']
|
||||
// a project has been created/opened
|
||||
procedure projNew(project: ICECommonProject);
|
||||
|
@ -164,7 +164,7 @@ type
|
|||
(**
|
||||
* An implementer can add a main menu entry.
|
||||
*)
|
||||
ICEMainMenuProvider = interface(ISubjectType)
|
||||
ICEMainMenuProvider = interface(IObserverType)
|
||||
['ICEMainMenuProvider']
|
||||
// item is a new mainMenu entry. item must be filled with the sub-items to be added.
|
||||
procedure menuDeclare(item: TMenuItem);
|
||||
|
@ -182,7 +182,7 @@ type
|
|||
* An implementer declares some actions which have their own main menu entry and
|
||||
* whose shortcuts are automatically handled
|
||||
*)
|
||||
ICEActionProvider = interface(ISubjectType)
|
||||
ICEActionProvider = interface(IObserverType)
|
||||
['ICEActionProvider']
|
||||
// the action handler will clear the references to the actions collected previously and start collecting if result.
|
||||
function actHandlerWantRecollect: boolean;
|
||||
|
@ -203,7 +203,7 @@ type
|
|||
(**
|
||||
* An implementer can expose customizable shortcuts to be edited in a dedicated widget.
|
||||
*)
|
||||
ICEEditableShortCut = interface(ISubjectType)
|
||||
ICEEditableShortCut = interface(IObserverType)
|
||||
['ICEEditableShortCut']
|
||||
// a TCEEditableShortCutSubject will start to collect shortcuts if result.
|
||||
function scedWantFirst: boolean;
|
||||
|
@ -237,7 +237,7 @@ type
|
|||
(**
|
||||
* An implementer can expose options to be edited in a dedicated widget.
|
||||
*)
|
||||
ICEEditableOptions = interface(ISubjectType)
|
||||
ICEEditableOptions = interface(IObserverType)
|
||||
['ICEEditableOptions']
|
||||
// the widget wants the category.
|
||||
function optionedWantCategory(): string;
|
||||
|
|
|
@ -57,8 +57,6 @@ type
|
|||
property isUpdating: boolean read getIsUpdating;
|
||||
end;
|
||||
|
||||
|
||||
|
||||
(**
|
||||
* Interface for a Coedit subject. Basically designed to hold a list of observer
|
||||
*)
|
||||
|
@ -70,15 +68,18 @@ type
|
|||
// optionally implemented to trigger all the methods of the observer interface.
|
||||
end;
|
||||
|
||||
// Base type for an interface that contains the methods of a subject.
|
||||
ISubjectType = interface
|
||||
(**
|
||||
* Base type used as constraint for an interface that contains
|
||||
* the methods called by a ICESubject.
|
||||
*)
|
||||
IObserverType = interface
|
||||
end;
|
||||
|
||||
(**
|
||||
* Standard implementation of an ICESubject.
|
||||
* Any descendant adds itself to the global EntitiesConnector.
|
||||
* Any descendant automatically adds itself to the EntitiesConnector.
|
||||
*)
|
||||
generic TCECustomSubject<T:ISubjectType> = class(ICESubject)
|
||||
generic TCECustomSubject<T:IObserverType> = class(ICESubject)
|
||||
protected
|
||||
fObservers: TObjectList;
|
||||
// test for a specific interface when adding an observer.
|
||||
|
|
|
@ -11,7 +11,7 @@ uses
|
|||
SynEditMarks, SynEditTypes, SynHighlighterJScript, SynBeautifier, dialogs,
|
||||
fpjson, jsonparser, LazUTF8, LazUTF8Classes, Buttons, StdCtrls,
|
||||
ce_common, ce_writableComponent, ce_d2syn, ce_txtsyn, ce_dialogs,
|
||||
ce_sharedres, ce_dlang, ce_stringrange;
|
||||
ce_sharedres, ce_dlang, ce_stringrange, ce_dbgitf, ce_observer;
|
||||
|
||||
type
|
||||
|
||||
|
@ -49,12 +49,6 @@ type
|
|||
|
||||
TIdentifierMatchOptions = set of TIdentifierMatchOption;
|
||||
|
||||
TBreakPointModification = (bpAdded, bpRemoved);
|
||||
|
||||
// breakpoint added or removed
|
||||
TBreakPointModifyEvent = procedure(sender: TCESynMemo; line: integer;
|
||||
modification: TBreakPointModification) of object;
|
||||
|
||||
// Simple THintWindow descendant allowing the font size to be in sync with the editor.
|
||||
TCEEditorHintWindow = class(THintWindow)
|
||||
public
|
||||
|
@ -122,7 +116,7 @@ type
|
|||
|
||||
TSortDialog = class;
|
||||
|
||||
TCESynMemo = class(TSynEdit)
|
||||
TCESynMemo = class(TSynEdit, ICEDebugObserver)
|
||||
private
|
||||
fFilename: string;
|
||||
fDastWorxExename: string;
|
||||
|
@ -153,7 +147,6 @@ type
|
|||
fTxtHighlighter: TSynTxtSyn;
|
||||
fImages: TImageList;
|
||||
fBreakPoints: TFPList;
|
||||
fBreakpointEvent: TBreakPointModifyEvent;
|
||||
fMatchSelectionOpts: TSynSearchOptions;
|
||||
fMatchIdentOpts: TSynSearchOptions;
|
||||
fMatchOpts: TIdentifierMatchOptions;
|
||||
|
@ -171,6 +164,7 @@ type
|
|||
fModuleTokFound: boolean;
|
||||
fHasModuleDeclaration: boolean;
|
||||
fLastCompletion: string;
|
||||
fDebugger: ICEDebugger;
|
||||
procedure decCallTipsLvl;
|
||||
procedure setMatchOpts(value: TIdentifierMatchOptions);
|
||||
function getMouseBytePosition: Integer;
|
||||
|
@ -195,6 +189,7 @@ type
|
|||
procedure gutterClick(Sender: TObject; X, Y, Line: integer; mark: TSynEditMark);
|
||||
procedure addBreakPoint(line: integer);
|
||||
procedure removeBreakPoint(line: integer);
|
||||
procedure removeDebugTimeMarks;
|
||||
function findBreakPoint(line: integer): boolean;
|
||||
procedure showCallTips(const tips: string);
|
||||
function lexCanCloseBrace: boolean;
|
||||
|
@ -204,6 +199,14 @@ type
|
|||
procedure setSelectionOrWordCase(upper: boolean);
|
||||
procedure sortSelectedLines(descending, caseSensitive: boolean);
|
||||
procedure tokFoundForCaption(const token: PLexToken; out stop: boolean);
|
||||
//
|
||||
procedure debugStart(debugger: ICEDebugger);
|
||||
procedure debugStop;
|
||||
function debugQueryBpCount: integer;
|
||||
procedure debugQueryBreakPoint(const index: integer; out fname: string; out line: integer; out kind: TBreakPointKind);
|
||||
procedure debugBreak(const fname: string; line: integer; reason: TCEDebugBreakReason);
|
||||
function breakPointsCount: integer;
|
||||
function breakPointLine(index: integer): integer;
|
||||
protected
|
||||
procedure DoEnter; override;
|
||||
procedure DoExit; override;
|
||||
|
@ -223,6 +226,7 @@ type
|
|||
constructor Create(aOwner: TComponent); override;
|
||||
destructor destroy; override;
|
||||
procedure setFocus; override;
|
||||
procedure showPage;
|
||||
//
|
||||
function pageCaption(checkModule: boolean): string;
|
||||
procedure checkFileDate;
|
||||
|
@ -243,12 +247,8 @@ type
|
|||
procedure ShowPhobosDoc;
|
||||
procedure nextChangedArea;
|
||||
procedure previousChangedArea;
|
||||
function implementMain: THasMain;
|
||||
procedure sortLines;
|
||||
//
|
||||
function breakPointsCount: integer;
|
||||
function breakPointLine(index: integer): integer;
|
||||
property onBreakpointModify: TBreakPointModifyEvent read fBreakpointEvent write fBreakpointEvent;
|
||||
function implementMain: THasMain;
|
||||
//
|
||||
property IdentifierMatchOptions: TIdentifierMatchOptions read fMatchOpts write setMatchOpts;
|
||||
property Identifier: string read fIdentifier;
|
||||
|
@ -723,6 +723,9 @@ begin
|
|||
fImages := TImageList.Create(self);
|
||||
fImages.AddResourceName(HINSTANCE, 'BULLET_RED');
|
||||
fImages.AddResourceName(HINSTANCE, 'BULLET_GREEN');
|
||||
fImages.AddResourceName(HINSTANCE, 'BULLET_BLACK');
|
||||
fImages.AddResourceName(HINSTANCE, 'BREAKS');
|
||||
fImages.AddResourceName(HINSTANCE, 'STEP');
|
||||
fBreakPoints := TFPList.Create;
|
||||
//
|
||||
fPositions := TCESynMemoPositions.create(self);
|
||||
|
@ -742,12 +745,14 @@ begin
|
|||
fDastWorxExename:= exeFullName('dastworx' + exeExt);
|
||||
//
|
||||
subjDocNew(TCEMultiDocSubject(fMultiDocSubject), self);
|
||||
EntitiesConnector.addObserver(self);
|
||||
end;
|
||||
|
||||
destructor TCESynMemo.destroy;
|
||||
begin
|
||||
saveCache;
|
||||
//
|
||||
EntitiesConnector.removeObserver(self);
|
||||
subjDocClosing(TCEMultiDocSubject(fMultiDocSubject), self);
|
||||
fMultiDocSubject.Free;
|
||||
fPositions.Free;
|
||||
|
@ -783,6 +788,11 @@ begin
|
|||
subjDocFocused(TCEMultiDocSubject(fMultiDocSubject), self);
|
||||
end;
|
||||
|
||||
procedure TCESynMemo.showPage;
|
||||
begin
|
||||
getMultiDocHandler.openDocument(fileName);
|
||||
end;
|
||||
|
||||
procedure TCESynMemo.DoEnter;
|
||||
begin
|
||||
inherited;
|
||||
|
@ -2404,7 +2414,7 @@ begin
|
|||
end;
|
||||
{$ENDREGION --------------------------------------------------------------------}
|
||||
|
||||
{$REGION breakpoints -----------------------------------------------------------}
|
||||
{$REGION debugging/breakpoints -----------------------------------------------------------}
|
||||
function TCESynMemo.breakPointsCount: integer;
|
||||
begin
|
||||
exit(fBreakPoints.Count);
|
||||
|
@ -2434,8 +2444,8 @@ begin
|
|||
{$PUSH}{$WARNINGS OFF}{$HINTS OFF}
|
||||
fBreakPoints.Add(pointer(line));
|
||||
{$POP}
|
||||
if assigned(fBreakpointEvent) then
|
||||
fBreakpointEvent(self, line, bpAdded);
|
||||
if assigned(fDebugger) then
|
||||
fDebugger.addBreakPoint(fFilename, line, bpkBreak);
|
||||
end;
|
||||
|
||||
procedure TCESynMemo.removeBreakPoint(line: integer);
|
||||
|
@ -2447,8 +2457,13 @@ begin
|
|||
{$PUSH}{$WARNINGS OFF}{$HINTS OFF}
|
||||
fBreakPoints.Remove(pointer(line));
|
||||
{$POP}
|
||||
if assigned(fBreakpointEvent) then
|
||||
fBreakpointEvent(self, line, bpRemoved);
|
||||
if assigned(fDebugger) then
|
||||
fDebugger.removeBreakPoint(fFilename, line);
|
||||
end;
|
||||
|
||||
procedure TCESynMemo.removeDebugTimeMarks;
|
||||
begin
|
||||
//TODO-cGDB: clean gutter marks generated during the session
|
||||
end;
|
||||
|
||||
function TCESynMemo.findBreakPoint(line: integer): boolean;
|
||||
|
@ -2465,6 +2480,44 @@ begin
|
|||
else
|
||||
addBreakPoint(line);
|
||||
end;
|
||||
|
||||
procedure TCESynMemo.debugStart(debugger: ICEDebugger);
|
||||
begin
|
||||
fDebugger := debugger;
|
||||
end;
|
||||
|
||||
procedure TCESynMemo.debugStop;
|
||||
begin
|
||||
fDebugger := nil;
|
||||
removeDebugTimeMarks;
|
||||
end;
|
||||
|
||||
function TCESynMemo.debugQueryBpCount: integer;
|
||||
begin
|
||||
exit(fBreakPoints.Count);
|
||||
end;
|
||||
|
||||
procedure TCESynMemo.debugQueryBreakPoint(const index: integer; out fname: string;
|
||||
out line: integer; out kind: TBreakPointKind);
|
||||
begin
|
||||
fname:= fFilename;
|
||||
line := breakPointLine(index);
|
||||
kind := bpkBreak;
|
||||
end;
|
||||
|
||||
procedure TCESynMemo.debugBreak(const fname: string; line: integer;
|
||||
reason: TCEDebugBreakReason);
|
||||
begin
|
||||
if fname <> fFilename then
|
||||
exit;
|
||||
showPage;
|
||||
caretY := line;
|
||||
// TODO-cDBG: add markup according to break reason
|
||||
case reason of
|
||||
dbBreakPoint:;
|
||||
dbSignal:;
|
||||
end;
|
||||
end;
|
||||
{$ENDREGION --------------------------------------------------------------------}
|
||||
|
||||
{$ENDREGION --------------------------------------------------------------------}
|
||||
|
|
Loading…
Reference in New Issue