mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-16 18:10:39 +02:00
MG: splitted main.pp: debugger management in TDebugManager
git-svn-id: trunk@1552 -
This commit is contained in:
parent
1ac990f79a
commit
1e999a3d60
2
.gitattributes
vendored
2
.gitattributes
vendored
@ -117,6 +117,7 @@ examples/testallform.pp svneol=native#text/pascal
|
||||
examples/testtools.inc svneol=native#text/pascal
|
||||
examples/toolbar.pp svneol=native#text/pascal
|
||||
examples/trackbar.pp svneol=native#text/pascal
|
||||
ide/basedebugmanager.pas svneol=native#text/pascal
|
||||
ide/buildlazdialog.pas svneol=native#text/pascal
|
||||
ide/codetemplatedialog.pp svneol=native#text/pascal
|
||||
ide/codetoolsdefines.lrs svneol=native#text/pascal
|
||||
@ -127,6 +128,7 @@ ide/compiler.pp svneol=native#text/pascal
|
||||
ide/compileroptions.pp svneol=native#text/pascal
|
||||
ide/compreg.pp svneol=native#text/pascal
|
||||
ide/customformeditor.pp svneol=native#text/pascal
|
||||
ide/debugmanager.pas svneol=native#text/pascal
|
||||
ide/editdefinetree.pas svneol=native#text/pascal
|
||||
ide/editoroptions.lrs svneol=native#text/pascal
|
||||
ide/editoroptions.pp svneol=native#text/pascal
|
||||
|
@ -1078,13 +1078,11 @@ writeln('TCodeCompletionCodeTool.CreateMissingProcBodies Gather existing method
|
||||
AnAVLNode:=ClassProcs.FindLowest;
|
||||
while AnAVLNode<>nil do begin
|
||||
NextAVLNode:=ClassProcs.FindSuccessor(AnAVLNode);
|
||||
if NextAVLNode<>nil then begin
|
||||
ANodeExt:=TCodeTreeNodeExtension(AnAVLNode.Data);
|
||||
ANode:=ANodeExt.Node;
|
||||
if (ANode<>nil) and (ANode.Desc=ctnProcedure)
|
||||
and ProcNodeHasSpecifier(ANode,psABSTRACT) then begin
|
||||
ClassProcs.Delete(AnAVLNode);
|
||||
end;
|
||||
ANodeExt:=TCodeTreeNodeExtension(AnAVLNode.Data);
|
||||
ANode:=ANodeExt.Node;
|
||||
if (ANode<>nil) and (ANode.Desc=ctnProcedure)
|
||||
and ProcNodeHasSpecifier(ANode,psABSTRACT) then begin
|
||||
ClassProcs.Delete(AnAVLNode);
|
||||
end;
|
||||
AnAVLNode:=NextAVLNode;
|
||||
end;
|
||||
|
58
ide/basedebugmanager.pas
Normal file
58
ide/basedebugmanager.pas
Normal file
@ -0,0 +1,58 @@
|
||||
{ $Id$ }
|
||||
{
|
||||
/***************************************************************************
|
||||
basedebugmanager.pp
|
||||
-------------------
|
||||
TBaseDebugManager is the base class for TDebugManager, which controls all
|
||||
debugging related stuff in the IDE. The base class is mostly abstract.
|
||||
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
}
|
||||
unit BaseDebugManager;
|
||||
|
||||
{$mode objfpc}{$H+}
|
||||
|
||||
interface
|
||||
|
||||
{$I ide.inc}
|
||||
|
||||
uses
|
||||
{$IFDEF IDE_MEM_CHECK}
|
||||
MemCheck,
|
||||
{$ENDIF}
|
||||
Classes, SysUtils, Forms;
|
||||
|
||||
type
|
||||
TBaseDebugManager = class(TComponent)
|
||||
public
|
||||
procedure ConnectMainBarEvents; virtual; abstract;
|
||||
procedure ConnectSourceNotebookEvents; virtual; abstract;
|
||||
procedure SetupMainBarShortCuts; virtual; abstract;
|
||||
|
||||
function DoInitDebugger: TModalResult; virtual; abstract;
|
||||
function DoPauseProject: TModalResult; virtual; abstract;
|
||||
function DoStepIntoProject: TModalResult; virtual; abstract;
|
||||
function DoStepOverProject: TModalResult; virtual; abstract;
|
||||
function DoRunToCursor: TModalResult; virtual; abstract;
|
||||
function DoStopProject: TModalResult; virtual; abstract;
|
||||
|
||||
procedure RunDebugger; virtual; abstract;
|
||||
procedure EndDebugging; virtual; abstract;
|
||||
end;
|
||||
|
||||
var DebugBoss: TBaseDebugManager;
|
||||
|
||||
implementation
|
||||
|
||||
end.
|
||||
|
524
ide/debugmanager.pas
Normal file
524
ide/debugmanager.pas
Normal file
@ -0,0 +1,524 @@
|
||||
{ $Id$ }
|
||||
{
|
||||
/***************************************************************************
|
||||
debugmanager.pp
|
||||
---------------
|
||||
TDebugManager controls all debugging related stuff in the IDE.
|
||||
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
}
|
||||
unit DebugManager;
|
||||
|
||||
{$mode objfpc}{$H+}
|
||||
|
||||
interface
|
||||
|
||||
{$I ide.inc}
|
||||
|
||||
uses
|
||||
{$IFDEF IDE_MEM_CHECK}
|
||||
MemCheck,
|
||||
{$ENDIF}
|
||||
Classes, SysUtils, Forms, Controls, Dialogs, CompilerOptions, EditorOptions,
|
||||
EnvironmentOpts, KeyMapping, UnitEditor, Project, IDEProcs,
|
||||
Debugger, DBGOutputForm, GDBMIDebugger, RunParamsOpts, ExtToolDialog,
|
||||
ProjectDefs, Watchesdlg, BreakPointsdlg, LocalsDlg, DebuggerDlg,
|
||||
BaseDebugManager, MainBar;
|
||||
|
||||
type
|
||||
TDebugManager = class(TBaseDebugManager)
|
||||
// Menu events
|
||||
procedure mnuViewWatchesClick(Sender: TObject);
|
||||
procedure mnuViewBreakPointsClick(Sender: TObject);
|
||||
procedure mnuViewDebugOutputClick(Sender: TObject);
|
||||
procedure mnuViewLocalsClick(Sender: TObject);
|
||||
|
||||
// SrcNotebook events
|
||||
procedure OnSrcNotebookAddWatchesAtCursor(Sender: TObject);
|
||||
procedure OnSrcNotebookCreateBreakPoint(Sender: TObject; Line: Integer);
|
||||
procedure OnSrcNotebookDeleteBreakPoint(Sender: TObject; Line: Integer);
|
||||
|
||||
// Debugger events
|
||||
procedure OnDebuggerChangeState(Sender: TObject);
|
||||
procedure OnDebuggerCurrentLine(Sender: TObject; const ALocation: TDBGLocationRec);
|
||||
procedure OnDebuggerOutput(Sender: TObject; const AText: String);
|
||||
procedure OnDebuggerException(Sender: TObject; const AExceptionID: Integer; const AExceptionText: String);
|
||||
private
|
||||
FBreakPoints: TDBGBreakPoints; // Points to debugger breakpoints if available
|
||||
// Else to own objet
|
||||
FDebugOutputDlg: TDBGOutputForm;
|
||||
FBreakPointsDlg: TBreakPointsDlg;
|
||||
FLocalsDlg: TLocalsDlg;
|
||||
|
||||
FDebugger: TDebugger;
|
||||
|
||||
procedure DebugConstructor;
|
||||
|
||||
procedure DebugDialogDestroy(Sender: TObject);
|
||||
procedure ViewDebugDialog(const ADialogClass: TDebuggerDlgClass; var ADialog: TDebuggerDlg);
|
||||
public
|
||||
constructor Create(TheOwner: TComponent); override;
|
||||
destructor Destroy; override;
|
||||
procedure ConnectMainBarEvents; override;
|
||||
procedure ConnectSourceNotebookEvents; override;
|
||||
procedure SetupMainBarShortCuts; override;
|
||||
|
||||
function DoInitDebugger: TModalResult; override;
|
||||
function DoPauseProject: TModalResult; override;
|
||||
function DoStepIntoProject: TModalResult; override;
|
||||
function DoStepOverProject: TModalResult; override;
|
||||
function DoRunToCursor: TModalResult; override;
|
||||
function DoStopProject: TModalResult; override;
|
||||
|
||||
procedure RunDebugger; override;
|
||||
procedure EndDebugging; override;
|
||||
end;
|
||||
|
||||
|
||||
|
||||
implementation
|
||||
|
||||
procedure TDebugManager.DebugConstructor;
|
||||
begin
|
||||
// TWatchesDlg
|
||||
Watches_Dlg := TWatchesDlg.Create(Self);
|
||||
|
||||
FBreakPointsDlg := nil;
|
||||
FLocalsDlg := nil;
|
||||
FDebugger := nil;
|
||||
FBreakPoints := TDBGBreakPoints.Create(nil, TDBGBreakPoint);
|
||||
end;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Menu events
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
procedure TDebugManager.mnuViewWatchesClick(Sender : TObject);
|
||||
begin
|
||||
Watches_dlg.Show;
|
||||
end;
|
||||
|
||||
procedure TDebugManager.mnuViewBreakPointsClick(Sender : TObject);
|
||||
begin
|
||||
ViewDebugDialog(TBreakPointsDlg, FBreakPointsDlg);
|
||||
end;
|
||||
|
||||
procedure TDebugManager.mnuViewDebugOutputClick(Sender : TObject);
|
||||
begin
|
||||
ViewDebugDialog(TDBGOutputForm, FDebugOutputDlg);
|
||||
end;
|
||||
|
||||
procedure TDebugManager.mnuViewLocalsClick(Sender : TObject);
|
||||
begin
|
||||
ViewDebugDialog(TLocalsDlg, FLocalsDlg);
|
||||
end;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ScrNoteBook events
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
procedure TDebugManager.OnSrcNotebookAddWatchesAtCursor(Sender : TObject);
|
||||
var
|
||||
SE : TSourceEditor;
|
||||
WatchVar: String;
|
||||
NewWatch: TdbgWatch;
|
||||
begin
|
||||
if FDebugger = nil then Exit;
|
||||
|
||||
//get the sourceEditor.
|
||||
SE := TSourceNotebook(sender).GetActiveSE;
|
||||
if not Assigned(SE) then Exit;
|
||||
WatchVar := SE.GetWordAtCurrentCaret;
|
||||
if WatchVar = '' then Exit;
|
||||
|
||||
NewWatch := TdbgWatch(FDebugger.Watches.Add);
|
||||
NewWatch.Expression := WatchVar;
|
||||
NewWatch.Enabled := True;
|
||||
end;
|
||||
|
||||
procedure TDebugManager.OnSrcNotebookCreateBreakPoint(Sender: TObject; Line: Integer);
|
||||
var
|
||||
NewBreak: TDBGBreakPoint;
|
||||
begin
|
||||
if SourceNotebook.Notebook = nil then Exit;
|
||||
|
||||
NewBreak := FBreakPoints.Add(ExtractFilename(TSourceNotebook(sender).GetActiveSe.FileName), Line);
|
||||
NewBreak.Enabled := True;
|
||||
end;
|
||||
|
||||
procedure TDebugManager.OnSrcNotebookDeleteBreakPoint(Sender: TObject; Line: Integer);
|
||||
begin
|
||||
if SourceNotebook.Notebook = nil then Exit;
|
||||
|
||||
FBreakPoints.Find(ExtractFilename(TSourceNotebook(sender).GetActiveSe.FileName), Line).Free;
|
||||
end;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Debugger events
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
procedure TDebugManager.OnDebuggerException(Sender: TObject; const AExceptionID: Integer; const AExceptionText: String);
|
||||
begin
|
||||
MessageDlg('Error',
|
||||
Format('Project %s raised exception class %d with message ''%s''.', [Project1.Title, AExceptionID, AExceptionText]),
|
||||
mtError,[mbOk],0);
|
||||
end;
|
||||
|
||||
procedure TDebugManager.OnDebuggerOutput(Sender: TObject; const AText: String);
|
||||
begin
|
||||
if FDebugOutputDlg <> nil
|
||||
then FDebugOutputDlg.AddText(AText);
|
||||
end;
|
||||
|
||||
procedure TDebugManager.OnDebuggerChangeState(Sender: TObject);
|
||||
const
|
||||
// dsNone, dsIdle, dsStop, dsPause, dsRun, dsError
|
||||
TOOLSTATEMAP: array[TDBGState] of TIDEToolStatus = (
|
||||
// dsNone, dsIdle, dsStop, dsPause, dsRun, dsError
|
||||
itNone, itNone, itNone, itDebugger, itDebugger, itDebugger
|
||||
);
|
||||
STATENAME: array[TDBGState] of string = (
|
||||
'dsNone', 'dsIdle', 'dsStop', 'dsPause', 'dsRun', 'dsError'
|
||||
);
|
||||
begin
|
||||
// Is the next line needed ???
|
||||
if (Sender<>FDebugger) or (Sender=nil) then exit;
|
||||
|
||||
WriteLN('[TDebugManager.OnDebuggerChangeState] state: ', STATENAME[FDebugger.State]);
|
||||
|
||||
// All conmmands
|
||||
// -------------------
|
||||
// dcRun, dcPause, dcStop, dcStepOver, dcStepInto, dcRunTo, dcJumpto, dcBreak, dcWatch
|
||||
// -------------------
|
||||
|
||||
with MainIDE do begin
|
||||
// For run end step bypass idle, so we can set the filename later
|
||||
RunSpeedButton.Enabled := (dcRun in FDebugger.Commands) or (FDebugger.State = dsIdle);
|
||||
itmProjectRun.Enabled := RunSpeedButton.Enabled;
|
||||
PauseSpeedButton.Enabled := dcPause in FDebugger.Commands;
|
||||
itmProjectPause.Enabled := PauseSpeedButton.Enabled;
|
||||
StepIntoSpeedButton.Enabled := (dcStepInto in FDebugger.Commands) or (FDebugger.State = dsIdle);
|
||||
itmProjectStepInto.Enabled := StepIntoSpeedButton.Enabled;
|
||||
StepOverSpeedButton.Enabled := (dcStepOver in FDebugger.Commands) or (FDebugger.State = dsIdle);
|
||||
itmProjectStepOver.Enabled := StepOverSpeedButton.Enabled;
|
||||
|
||||
itmProjectRunToCursor.Enabled := dcRunTo in FDebugger.Commands;
|
||||
itmProjectStop.Enabled := dcStop in FDebugger.Commands;;
|
||||
|
||||
// TODO: add other debugger menuitems
|
||||
// TODO: implement by actions
|
||||
|
||||
ToolStatus := TOOLSTATEMAP[FDebugger.State];
|
||||
end;
|
||||
|
||||
if FDebugger.State = dsError
|
||||
then begin
|
||||
WriteLN('Ooops, the debugger entered the error state');
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TDebugManager.OnDebuggerCurrentLine(Sender: TObject;
|
||||
const ALocation: TDBGLocationRec);
|
||||
// debugger paused program due to pause or error
|
||||
// -> show the current execution line in editor
|
||||
// if SrcLine = -1 then no source is available
|
||||
var
|
||||
ActiveSrcEdit: TSourceEditor;
|
||||
UnitFile: String;
|
||||
begin
|
||||
if (Sender<>FDebugger) or (Sender=nil) then exit;
|
||||
|
||||
//TODO: Show assembler window if no source can be found.
|
||||
if ALocation.SrcLine = -1 then Exit;
|
||||
|
||||
UnitFile := MainIDE.FindUnitFile(ALocation.SrcFile);
|
||||
if UnitFile = ''
|
||||
then UnitFile := ALocation.SrcFile;
|
||||
if MainIDE.DoOpenEditorFile(UnitFile, [ofOnlyIfExists]) <> mrOk then exit;
|
||||
|
||||
ActiveSrcEdit := SourceNoteBook.GetActiveSE;
|
||||
if ActiveSrcEdit=nil then exit;
|
||||
|
||||
with ActiveSrcEdit.EditorComponent do
|
||||
begin
|
||||
CaretXY:=Point(1, ALocation.SrcLine);
|
||||
BlockBegin:=CaretXY;
|
||||
BlockEnd:=CaretXY;
|
||||
TopLine:=ALocation.SrcLine-(LinesInWindow div 2);
|
||||
end;
|
||||
ActiveSrcEdit.ErrorLine:=ALocation.SrcLine;
|
||||
end;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Debugger dialog routines
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// Common handler
|
||||
// The tag of the destroyed form contains the form variable pointing to it
|
||||
procedure TDebugManager.DebugDialogDestroy(Sender: TObject);
|
||||
begin
|
||||
if TForm(Sender).Tag <> 0
|
||||
then PPointer(TForm(Sender).Tag)^ := nil;
|
||||
end;
|
||||
|
||||
procedure TDebugManager.ViewDebugDialog(const ADialogClass: TDebuggerDlgClass; var ADialog: TDebuggerDlg);
|
||||
begin
|
||||
if ADialog = nil
|
||||
then begin
|
||||
try
|
||||
ADialog := ADialogClass.Create(Self);
|
||||
except
|
||||
on E: Exception do begin
|
||||
WriteLN('[ERROR] IDE: Probably FPC bug #1888 caused an exception while creating class ''', ADialogClass.ClassName, '''');
|
||||
WriteLN('[ERROR] IDE: Exception message: ', E.Message);
|
||||
Exit;
|
||||
end;
|
||||
end;
|
||||
ADialog.Tag := Integer(@ADialog);
|
||||
ADialog.OnDestroy := @DebugDialogDestroy;
|
||||
DoInitDebugger;
|
||||
ADialog.Debugger := FDebugger;
|
||||
end;
|
||||
ADialog.Show;
|
||||
ADialog.BringToFront;
|
||||
end;
|
||||
|
||||
constructor TDebugManager.Create(TheOwner: TComponent);
|
||||
begin
|
||||
inherited Create(TheOwner);
|
||||
DebugConstructor;
|
||||
end;
|
||||
|
||||
destructor TDebugManager.Destroy;
|
||||
begin
|
||||
FreeThenNil(FDebugger);
|
||||
FreeThenNil(FBreakPoints);
|
||||
FreeThenNil(Watches_Dlg);
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
procedure TDebugManager.ConnectMainBarEvents;
|
||||
begin
|
||||
with MainIDE do begin
|
||||
itmViewWatches.OnClick := @mnuViewWatchesClick;
|
||||
itmViewBreakPoints.OnClick := @mnuViewBreakPointsClick;
|
||||
itmViewLocals.OnClick := @mnuViewLocalsClick;
|
||||
itmViewDebugOutput.OnClick := @mnuViewDebugOutputClick;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TDebugManager.ConnectSourceNotebookEvents;
|
||||
begin
|
||||
SourceNotebook.OnAddWatchAtCursor := @OnSrcNotebookAddWatchesAtCursor;
|
||||
SourceNotebook.OnCreateBreakPoint := @OnSrcNotebookCreateBreakPoint;
|
||||
SourceNotebook.OnDeleteBreakPoint := @OnSrcNotebookDeleteBreakPoint;
|
||||
end;
|
||||
|
||||
procedure TDebugManager.SetupMainBarShortCuts;
|
||||
begin
|
||||
with MainIDE, EditorOpts.KeyMap do
|
||||
begin
|
||||
itmViewWatches.ShortCut := CommandToShortCut(ecToggleWatches);
|
||||
itmViewBreakpoints.ShortCut := CommandToShortCut(ecToggleBreakPoints);
|
||||
itmViewDebugOutput.ShortCut := CommandToShortCut(ecToggleDebuggerOut);
|
||||
itmViewLocals.ShortCut := CommandToShortCut(ecToggleLocals);
|
||||
end;
|
||||
end;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Debugger routines
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
function TDebugManager.DoInitDebugger: TModalResult;
|
||||
procedure ResetDialogs;
|
||||
begin
|
||||
if FDebugOutputDlg <> nil
|
||||
then FDebugOutputDlg.Debugger := FDebugger;
|
||||
if FBreakPointsDlg <> nil
|
||||
then FBreakPointsDlg.Debugger := FDebugger;
|
||||
if FLocalsDlg <> nil
|
||||
then FLocalsDlg.Debugger := FDebugger;
|
||||
end;
|
||||
var
|
||||
OldBreakpoints: TDBGBreakpoints;
|
||||
LaunchingCmdLine, LaunchingApplication, LaunchingParams: String;
|
||||
begin
|
||||
WriteLN('[TDebugManager.DoInitDebugger] A');
|
||||
|
||||
Result:=mrCancel;
|
||||
if Project1.MainUnit < 0 then Exit;
|
||||
|
||||
LaunchingCmdLine:=MainIDE.GetRunCommandLine;
|
||||
SplitCmdLine(LaunchingCmdLine,LaunchingApplication,LaunchingParams);
|
||||
|
||||
OldBreakpoints := nil;
|
||||
|
||||
case EnvironmentOptions.DebuggerType of
|
||||
dtGnuDebugger: begin
|
||||
if (FDebugger <> nil)
|
||||
and ( not(FDebugger is TGDBMIDebugger)
|
||||
or (FDebugger.ExternalDebugger <> EnvironmentOptions.DebuggerFilename)
|
||||
)
|
||||
then begin
|
||||
OldBreakpoints := TDBGBreakpoints.Create(nil, TDBGBreakpoint);
|
||||
OldBreakpoints.Assign(FBreakPoints);
|
||||
FBreakPoints := nil;
|
||||
|
||||
FDebugger.Free;
|
||||
FDebugger := nil;
|
||||
ResetDialogs;
|
||||
end;
|
||||
if FDebugger = nil
|
||||
then begin
|
||||
if FBreakPoints <> nil
|
||||
then begin
|
||||
OldBreakpoints := TDBGBreakpoints.Create(nil, TDBGBreakpoint);
|
||||
OldBreakpoints.Assign(FBreakPoints);
|
||||
end;
|
||||
FDebugger := TGDBMIDebugger.Create(EnvironmentOptions.DebuggerFilename);
|
||||
FBreakPoints := FDebugger.BreakPoints;
|
||||
ResetDialogs;
|
||||
end;
|
||||
if OldBreakpoints <> nil
|
||||
then FBreakPoints.Assign(OldBreakpoints);
|
||||
end;
|
||||
else
|
||||
OldBreakpoints := FBreakPoints;
|
||||
FBreakPoints := TDBGBreakpoints.Create(nil, TDBGBreakpoint);
|
||||
FBreakPoints.Assign(OldBreakpoints);
|
||||
|
||||
FDebugger.Free;
|
||||
FDebugger := nil;
|
||||
ResetDialogs;
|
||||
Exit;
|
||||
end;
|
||||
FDebugger.OnState:=@OnDebuggerChangeState;
|
||||
FDebugger.OnCurrent:=@OnDebuggerCurrentLine;
|
||||
FDebugger.OnDbgOutput := @OnDebuggerOutput;
|
||||
FDebugger.OnException := @OnDebuggerException;
|
||||
if FDebugger.State = dsNone
|
||||
then FDebugger.Init;
|
||||
|
||||
FDebugger.FileName := LaunchingApplication;
|
||||
FDebugger.Arguments := LaunchingParams;
|
||||
|
||||
if FDebugOutputDlg <> nil
|
||||
then FDebugOutputDlg.Clear;
|
||||
|
||||
//TODO: Show/hide debug menuitems based on FDebugger.SupportedCommands
|
||||
|
||||
// property BreakPointGroups: TDBGBreakPointGroups read FBreakPointGroups; // list of all breakpoints
|
||||
// property Watches: TDBGWatches read FWatches; // list of all watches localvars etc
|
||||
|
||||
Result := mrOk;
|
||||
WriteLN('[TDebugManager.DoInitDebugger] END');
|
||||
end;
|
||||
|
||||
// still part of main, should go here when dummydebugger is finished
|
||||
//
|
||||
//function TDebugManager.DoRunProject: TModalResult;
|
||||
|
||||
function TDebugManager.DoPauseProject: TModalResult;
|
||||
begin
|
||||
Result := mrCancel;
|
||||
if (MainIDE.ToolStatus <> itDebugger)
|
||||
or (FDebugger = nil)
|
||||
then Exit;
|
||||
FDebugger.Pause;
|
||||
Result := mrOk;
|
||||
end;
|
||||
|
||||
function TDebugManager.DoStepIntoProject: TModalResult;
|
||||
begin
|
||||
if (MainIDE.DoInitProjectRun <> mrOK)
|
||||
or (MainIDE.ToolStatus <> itDebugger)
|
||||
or (FDebugger = nil)
|
||||
then begin
|
||||
Result := mrAbort;
|
||||
Exit;
|
||||
end;
|
||||
|
||||
FDebugger.StepInto;
|
||||
Result := mrOk;
|
||||
end;
|
||||
|
||||
function TDebugManager.DoStepOverProject: TModalResult;
|
||||
begin
|
||||
if (MainIDE.DoInitProjectRun <> mrOK)
|
||||
or (MainIDE.ToolStatus <> itDebugger)
|
||||
or (FDebugger = nil)
|
||||
then begin
|
||||
Result := mrAbort;
|
||||
Exit;
|
||||
end;
|
||||
|
||||
FDebugger.StepOver;
|
||||
Result := mrOk;
|
||||
end;
|
||||
|
||||
function TDebugManager.DoStopProject: TModalResult;
|
||||
begin
|
||||
Result := mrCancel;
|
||||
if (MainIDE.ToolStatus <> itDebugger)
|
||||
or (FDebugger=nil)
|
||||
then Exit;
|
||||
|
||||
FDebugger.Stop;
|
||||
Result := mrOk;
|
||||
end;
|
||||
|
||||
procedure TDebugManager.RunDebugger;
|
||||
begin
|
||||
if FDebugger <> nil then FDebugger.Run;
|
||||
end;
|
||||
|
||||
procedure TDebugManager.EndDebugging;
|
||||
begin
|
||||
if FDebugger <> nil then FDebugger.Done;
|
||||
end;
|
||||
|
||||
function TDebugManager.DoRunToCursor: TModalResult;
|
||||
var
|
||||
ActiveSrcEdit: TSourceEditor;
|
||||
ActiveUnitInfo: TUnitInfo;
|
||||
UnitFilename: string;
|
||||
begin
|
||||
if (MainIDE.DoInitProjectRun <> mrOK)
|
||||
or (MainIDE.ToolStatus <> itDebugger)
|
||||
or (FDebugger = nil)
|
||||
then begin
|
||||
Result := mrAbort;
|
||||
Exit;
|
||||
end;
|
||||
|
||||
Result := mrCancel;
|
||||
|
||||
MainIDE.GetCurrentUnit(ActiveSrcEdit, ActiveUnitInfo);
|
||||
if (ActiveSrcEdit=nil) or (ActiveUnitInfo=nil)
|
||||
then begin
|
||||
MessageDlg('Run to failed','Please open a unit before run.',mtError,
|
||||
[mbCancel],0);
|
||||
Exit;
|
||||
end;
|
||||
|
||||
if not ActiveUnitInfo.Source.IsVirtual
|
||||
then UnitFilename:=ActiveUnitInfo.Filename
|
||||
else UnitFilename:=MainIDE.GetTestUnitFilename(ActiveUnitInfo);
|
||||
|
||||
FDebugger.RunTo(ExtractFilename(UnitFilename), ActiveSrcEdit.EditorComponent.CaretY);
|
||||
|
||||
Result := mrOK;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
@ -5,52 +5,12 @@
|
||||
{------------------------------------------------------------------------------}
|
||||
|
||||
{$IFDEF IDE_HEAD}
|
||||
itmViewwatches: TMenuItem;
|
||||
itmViewBreakpoints: TMenuItem;
|
||||
itmViewLocals: TMenuItem;
|
||||
itmViewDebugOutput: TMenuItem;
|
||||
|
||||
// Menu events
|
||||
procedure mnuViewWatchesClick(Sender: TObject);
|
||||
procedure mnuViewBreakPointsClick(Sender: TObject);
|
||||
procedure mnuViewDebugOutputClick(Sender: TObject);
|
||||
procedure mnuViewLocalsClick(Sender: TObject);
|
||||
|
||||
// SrcNotebook events
|
||||
procedure OnSrcNotebookAddWatchesAtCursor(Sender: TObject);
|
||||
procedure OnSrcNotebookCreateBreakPoint(Sender: TObject; Line: Integer);
|
||||
procedure OnSrcNotebookDeleteBreakPoint(Sender: TObject; Line: Integer);
|
||||
|
||||
// Debugger events
|
||||
procedure OnDebuggerChangeState(Sender: TObject);
|
||||
procedure OnDebuggerCurrentLine(Sender: TObject; const ALocation: TDBGLocationRec);
|
||||
procedure OnDebuggerOutput(Sender: TObject; const AText: String);
|
||||
procedure OnDebuggerException(Sender: TObject; const AExceptionID: Integer; const AExceptionText: String);
|
||||
|
||||
|
||||
{$ELSE} {$IFDEF IDE_PRIVATE}
|
||||
FBreakPoints: TDBGBreakPoints; // Points to debugger breakpoints if available
|
||||
// Else to own objet
|
||||
FDebugOutputDlg: TDBGOutputForm;
|
||||
FBreakPointsDlg: TBreakPointsDlg;
|
||||
FLocalsDlg: TLocalsDlg;
|
||||
|
||||
FDebugger: TDebugger;
|
||||
|
||||
procedure DebugConstructor;
|
||||
procedure DebugCreateShortCuts;
|
||||
procedure DebugLoadMenus;
|
||||
|
||||
procedure DebugDialogDestroy(Sender: TObject);
|
||||
procedure ViewDebugDialog(const ADialogClass: TDebuggerDlgClass; var ADialog: TDebuggerDlg);
|
||||
|
||||
{$ELSE} {$IFDEF IDE_PUBLIC}
|
||||
function DoInitDebugger: TModalResult;
|
||||
function DoPauseProject: TModalResult;
|
||||
function DoStepIntoProject: TModalResult;
|
||||
function DoStepOverProject: TModalResult;
|
||||
function DoRunToCursor: TModalResult;
|
||||
function DoStopProject: TModalResult;
|
||||
|
||||
{$ELSE} {$IFDEF IDE_IMPLEMENTATION}
|
||||
//=============================================================================
|
||||
@ -61,412 +21,6 @@
|
||||
// IDE initialization
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
procedure TMainIDE.DebugConstructor;
|
||||
begin
|
||||
// TWatchesDlg
|
||||
Watches_Dlg := TWatchesDlg.Create(Self);
|
||||
|
||||
|
||||
FBreakPointsDlg := nil;
|
||||
FLocalsDlg := nil;
|
||||
FDebugger := nil;
|
||||
FBreakPoints := TDBGBreakPoints.Create(nil, TDBGBreakPoint);
|
||||
end;
|
||||
|
||||
procedure TMainIDE.DebugCreateShortCuts;
|
||||
begin
|
||||
with EditorOpts.KeyMap do
|
||||
begin
|
||||
itmViewWatches.ShortCut := CommandToShortCut(ecToggleWatches);
|
||||
itmViewBreakpoints.ShortCut := CommandToShortCut(ecToggleBreakPoints);
|
||||
itmViewDebugOutput.ShortCut := CommandToShortCut(ecToggleDebuggerOut);
|
||||
itmViewLocals.ShortCut := CommandToShortCut(ecToggleLocals);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TMainIDE.DebugLoadMenus;
|
||||
begin
|
||||
itmViewWatches := TMenuItem.Create(Self);
|
||||
itmViewWatches.Name:='itmViewWatches';
|
||||
itmViewWatches.Caption := 'Watches';
|
||||
itmViewWatches.OnClick := @mnuViewWatchesClick;
|
||||
itmViewDebugWindows.Add(itmViewWatches);
|
||||
|
||||
itmViewBreakPoints := TMenuItem.Create(Self);
|
||||
itmViewBreakPoints.Name:='itmViewBreakPoints';
|
||||
itmViewBreakPoints.Caption := 'BreakPoints';
|
||||
itmViewBreakPoints.OnClick := @mnuViewBreakPointsClick;
|
||||
itmViewDebugWindows.Add(itmViewBreakPoints);
|
||||
|
||||
itmViewLocals := TMenuItem.Create(Self);
|
||||
itmViewLocals.Name:='itmViewLocals';
|
||||
itmViewLocals.Caption := 'Local Variables';
|
||||
itmViewLocals.OnClick := @mnuViewLocalsClick;
|
||||
itmViewDebugWindows.Add(itmViewLocals);
|
||||
|
||||
itmViewDebugOutput := TMenuItem.Create(Self);
|
||||
itmViewDebugOutput.Name:='itmViewDebugOutput';
|
||||
itmViewDebugOutput.Caption := 'Debug output';
|
||||
itmViewDebugOutput.OnClick := @mnuViewDebugOutputClick;
|
||||
itmViewDebugWindows.Add(itmViewDebugOutput);
|
||||
end;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Menu events
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
procedure TMainIDE.mnuViewWatchesClick(Sender : TObject);
|
||||
begin
|
||||
Watches_dlg.Show;
|
||||
end;
|
||||
|
||||
procedure TMainIDE.mnuViewBreakPointsClick(Sender : TObject);
|
||||
begin
|
||||
ViewDebugDialog(TBreakPointsDlg, FBreakPointsDlg);
|
||||
end;
|
||||
|
||||
procedure TMainIDE.mnuViewDebugOutputClick(Sender : TObject);
|
||||
begin
|
||||
ViewDebugDialog(TDBGOutputForm, FDebugOutputDlg);
|
||||
end;
|
||||
|
||||
procedure TMainIDE.mnuViewLocalsClick(Sender : TObject);
|
||||
begin
|
||||
ViewDebugDialog(TLocalsDlg, FLocalsDlg);
|
||||
end;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ScrNoteBook events
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
procedure TMainIDE.OnSrcNotebookAddWatchesAtCursor(Sender : TObject);
|
||||
var
|
||||
SE : TSourceEditor;
|
||||
WatchVar: String;
|
||||
NewWatch: TdbgWatch;
|
||||
begin
|
||||
if FDebugger = nil then Exit;
|
||||
|
||||
//get the sourceEditor.
|
||||
SE := TSourceNotebook(sender).GetActiveSE;
|
||||
if not Assigned(SE) then Exit;
|
||||
WatchVar := SE.GetWordAtCurrentCaret;
|
||||
if WatchVar = '' then Exit;
|
||||
|
||||
NewWatch := TdbgWatch(FDebugger.Watches.Add);
|
||||
NewWatch.Expression := WatchVar;
|
||||
NewWatch.Enabled := True;
|
||||
end;
|
||||
|
||||
procedure TMainIDE.OnSrcNotebookCreateBreakPoint(Sender: TObject; Line: Integer);
|
||||
var
|
||||
NewBreak: TDBGBreakPoint;
|
||||
begin
|
||||
if SourceNotebook.Notebook = nil then Exit;
|
||||
|
||||
NewBreak := FBreakPoints.Add(ExtractFilename(TSourceNotebook(sender).GetActiveSe.FileName), Line);
|
||||
NewBreak.Enabled := True;
|
||||
end;
|
||||
|
||||
procedure TMainIDE.OnSrcNotebookDeleteBreakPoint(Sender: TObject; Line: Integer);
|
||||
begin
|
||||
if SourceNotebook.Notebook = nil then Exit;
|
||||
|
||||
FBreakPoints.Find(ExtractFilename(TSourceNotebook(sender).GetActiveSe.FileName), Line).Free;
|
||||
end;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Debugger events
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
procedure TMainIDE.OnDebuggerException(Sender: TObject; const AExceptionID: Integer; const AExceptionText: String);
|
||||
begin
|
||||
MessageDlg('Error',
|
||||
Format('Project %s raised exception class %d with message ''%s''.', [Project1.Title, AExceptionID, AExceptionText]),
|
||||
mtError,[mbOk],0);
|
||||
end;
|
||||
|
||||
procedure TMainIDE.OnDebuggerOutput(Sender: TObject; const AText: String);
|
||||
begin
|
||||
if FDebugOutputDlg <> nil
|
||||
then FDebugOutputDlg.AddText(AText);
|
||||
end;
|
||||
|
||||
procedure TMainIDE.OnDebuggerChangeState(Sender: TObject);
|
||||
const
|
||||
// dsNone, dsIdle, dsStop, dsPause, dsRun, dsError
|
||||
TOOLSTATEMAP: array[TDBGState] of TIDEToolStatus = (
|
||||
// dsNone, dsIdle, dsStop, dsPause, dsRun, dsError
|
||||
itNone, itNone, itNone, itDebugger, itDebugger, itDebugger
|
||||
);
|
||||
STATENAME: array[TDBGState] of string = (
|
||||
'dsNone', 'dsIdle', 'dsStop', 'dsPause', 'dsRun', 'dsError'
|
||||
);
|
||||
begin
|
||||
// Is the next line needed ???
|
||||
if (Sender<>FDebugger) or (Sender=nil) then exit;
|
||||
|
||||
WriteLN('[TMainIDE.OnDebuggerChangeState] state: ', STATENAME[FDebugger.State]);
|
||||
|
||||
// All conmmands
|
||||
// -------------------
|
||||
// dcRun, dcPause, dcStop, dcStepOver, dcStepInto, dcRunTo, dcJumpto, dcBreak, dcWatch
|
||||
// -------------------
|
||||
|
||||
// For run end step bypass idle, so we can set the filename later
|
||||
RunSpeedButton.Enabled := (dcRun in FDebugger.Commands) or (FDebugger.State = dsIdle);
|
||||
itmProjectRun.Enabled := RunSpeedButton.Enabled;
|
||||
PauseSpeedButton.Enabled := dcPause in FDebugger.Commands;
|
||||
itmProjectPause.Enabled := PauseSpeedButton.Enabled;
|
||||
StepIntoSpeedButton.Enabled := (dcStepInto in FDebugger.Commands) or (FDebugger.State = dsIdle);
|
||||
itmProjectStepInto.Enabled := StepIntoSpeedButton.Enabled;
|
||||
StepOverSpeedButton.Enabled := (dcStepOver in FDebugger.Commands) or (FDebugger.State = dsIdle);
|
||||
itmProjectStepOver.Enabled := StepOverSpeedButton.Enabled;
|
||||
|
||||
itmProjectRunToCursor.Enabled := dcRunTo in FDebugger.Commands;
|
||||
itmProjectStop.Enabled := dcStop in FDebugger.Commands;;
|
||||
|
||||
// TODO: add other debugger menuitems
|
||||
// TODO: implement by actions
|
||||
|
||||
ToolStatus := TOOLSTATEMAP[FDebugger.State];
|
||||
|
||||
if FDebugger.State = dsError
|
||||
then begin
|
||||
WriteLN('Ooops, the debugger entered the error state');
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TMainIDE.OnDebuggerCurrentLine(Sender: TObject;
|
||||
const ALocation: TDBGLocationRec);
|
||||
// debugger paused program due to pause or error
|
||||
// -> show the current execution line in editor
|
||||
// if SrcLine = -1 then no source is available
|
||||
var
|
||||
ActiveSrcEdit: TSourceEditor;
|
||||
UnitFile: String;
|
||||
begin
|
||||
if (Sender<>FDebugger) or (Sender=nil) then exit;
|
||||
|
||||
//TODO: Show assembler window if no source can be found.
|
||||
if ALocation.SrcLine = -1 then Exit;
|
||||
|
||||
UnitFile := FindUnitFile(ALocation.SrcFile);
|
||||
if UnitFile = ''
|
||||
then UnitFile := ALocation.SrcFile;
|
||||
if DoOpenEditorFile(UnitFile, [ofOnlyIfExists]) <> mrOk then exit;
|
||||
|
||||
ActiveSrcEdit := SourceNoteBook.GetActiveSE;
|
||||
if ActiveSrcEdit=nil then exit;
|
||||
|
||||
with ActiveSrcEdit.EditorComponent do
|
||||
begin
|
||||
CaretXY:=Point(1, ALocation.SrcLine);
|
||||
BlockBegin:=CaretXY;
|
||||
BlockEnd:=CaretXY;
|
||||
TopLine:=ALocation.SrcLine-(LinesInWindow div 2);
|
||||
end;
|
||||
ActiveSrcEdit.ErrorLine:=ALocation.SrcLine;
|
||||
end;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Debugger dialog routines
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// Common handler
|
||||
// The tag of the destroyed form contains the form variable pointing to it
|
||||
procedure TMainIDE.DebugDialogDestroy(Sender: TObject);
|
||||
begin
|
||||
if TForm(Sender).Tag <> 0
|
||||
then PPointer(TForm(Sender).Tag)^ := nil;
|
||||
end;
|
||||
|
||||
procedure TMainIDE.ViewDebugDialog(const ADialogClass: TDebuggerDlgClass; var ADialog: TDebuggerDlg);
|
||||
begin
|
||||
if ADialog = nil
|
||||
then begin
|
||||
try
|
||||
ADialog := ADialogClass.Create(Self);
|
||||
except
|
||||
on E: Exception do begin
|
||||
WriteLN('[ERROR] IDE: Probably FPC bug #1888 caused an exception while creating class ''', ADialogClass.ClassName, '''');
|
||||
WriteLN('[ERROR] IDE: Exception message: ', E.Message);
|
||||
Exit;
|
||||
end;
|
||||
end;
|
||||
ADialog.Tag := Integer(@ADialog);
|
||||
ADialog.OnDestroy := @DebugDialogDestroy;
|
||||
DoInitDebugger;
|
||||
ADialog.Debugger := FDebugger;
|
||||
end;
|
||||
ADialog.Show;
|
||||
ADialog.BringToFront;
|
||||
end;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Debugger routines
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
function TMainIDE.DoInitDebugger: TModalResult;
|
||||
procedure ResetDialogs;
|
||||
begin
|
||||
if FDebugOutputDlg <> nil
|
||||
then FDebugOutputDlg.Debugger := FDebugger;
|
||||
if FBreakPointsDlg <> nil
|
||||
then FBreakPointsDlg.Debugger := FDebugger;
|
||||
if FLocalsDlg <> nil
|
||||
then FLocalsDlg.Debugger := FDebugger;
|
||||
end;
|
||||
var
|
||||
OldBreakpoints: TDBGBreakpoints;
|
||||
begin
|
||||
WriteLN('[TMainIDE.DoInitDebugger] A');
|
||||
|
||||
Result:=mrCancel;
|
||||
if Project1.MainUnit < 0 then Exit;
|
||||
|
||||
OldBreakpoints := nil;
|
||||
|
||||
case EnvironmentOptions.DebuggerType of
|
||||
dtGnuDebugger: begin
|
||||
if (FDebugger <> nil)
|
||||
and ( not(FDebugger is TGDBMIDebugger)
|
||||
or (FDebugger.ExternalDebugger <> EnvironmentOptions.DebuggerFilename)
|
||||
)
|
||||
then begin
|
||||
OldBreakpoints := TDBGBreakpoints.Create(nil, TDBGBreakpoint);
|
||||
OldBreakpoints.Assign(FBreakPoints);
|
||||
FBreakPoints := nil;
|
||||
|
||||
FDebugger.Free;
|
||||
FDebugger := nil;
|
||||
ResetDialogs;
|
||||
end;
|
||||
if FDebugger = nil
|
||||
then begin
|
||||
if FBreakPoints <> nil
|
||||
then begin
|
||||
OldBreakpoints := TDBGBreakpoints.Create(nil, TDBGBreakpoint);
|
||||
OldBreakpoints.Assign(FBreakPoints);
|
||||
end;
|
||||
FDebugger := TGDBMIDebugger.Create(EnvironmentOptions.DebuggerFilename);
|
||||
FBreakPoints := FDebugger.BreakPoints;
|
||||
ResetDialogs;
|
||||
end;
|
||||
if OldBreakpoints <> nil
|
||||
then FBreakPoints.Assign(OldBreakpoints);
|
||||
end;
|
||||
else
|
||||
OldBreakpoints := FBreakPoints;
|
||||
FBreakPoints := TDBGBreakpoints.Create(nil, TDBGBreakpoint);
|
||||
FBreakPoints.Assign(OldBreakpoints);
|
||||
|
||||
FDebugger.Free;
|
||||
FDebugger := nil;
|
||||
ResetDialogs;
|
||||
Exit;
|
||||
end;
|
||||
FDebugger.OnState:=@OnDebuggerChangeState;
|
||||
FDebugger.OnCurrent:=@OnDebuggerCurrentLine;
|
||||
FDebugger.OnDbgOutput := @OnDebuggerOutput;
|
||||
FDebugger.OnException := @OnDebuggerException;
|
||||
if FDebugger.State = dsNone
|
||||
then FDebugger.Init;
|
||||
|
||||
//TODO: Show/hide debug menuitems based on FDebugger.SupportedCommands
|
||||
|
||||
// property BreakPointGroups: TDBGBreakPointGroups read FBreakPointGroups; // list of all breakpoints
|
||||
// property Watches: TDBGWatches read FWatches; // list of all watches localvars etc
|
||||
|
||||
Result := mrOk;
|
||||
WriteLN('[TMainIDE.DoInitDebugger] END');
|
||||
end;
|
||||
|
||||
// still part of main, should go here when dummydebugger is finished
|
||||
//
|
||||
//function TMainIDE.DoRunProject: TModalResult;
|
||||
|
||||
function TMainIDE.DoPauseProject: TModalResult;
|
||||
begin
|
||||
Result := mrCancel;
|
||||
if (ToolStatus <> itDebugger)
|
||||
or (FDebugger = nil)
|
||||
then Exit;
|
||||
FDebugger.Pause;
|
||||
Result := mrOk;
|
||||
end;
|
||||
|
||||
function TMainIDE.DoStepIntoProject: TModalResult;
|
||||
begin
|
||||
if (DoInitProjectRun <> mrOK)
|
||||
or (ToolStatus <> itDebugger)
|
||||
or (FDebugger = nil)
|
||||
then begin
|
||||
Result := mrAbort;
|
||||
Exit;
|
||||
end;
|
||||
|
||||
FDebugger.StepInto;
|
||||
Result := mrOk;
|
||||
end;
|
||||
|
||||
function TMainIDE.DoStepOverProject: TModalResult;
|
||||
begin
|
||||
if (DoInitProjectRun <> mrOK)
|
||||
or (ToolStatus <> itDebugger)
|
||||
or (FDebugger = nil)
|
||||
then begin
|
||||
Result := mrAbort;
|
||||
Exit;
|
||||
end;
|
||||
|
||||
FDebugger.StepOver;
|
||||
Result := mrOk;
|
||||
end;
|
||||
|
||||
function TMainIDE.DoStopProject: TModalResult;
|
||||
begin
|
||||
Result := mrCancel;
|
||||
if (ToolStatus <> itDebugger)
|
||||
or (FDebugger=nil)
|
||||
then Exit;
|
||||
|
||||
FDebugger.Stop;
|
||||
Result := mrOk;
|
||||
end;
|
||||
|
||||
function TMainIDE.DoRunToCursor: TModalResult;
|
||||
var
|
||||
ActiveSrcEdit: TSourceEditor;
|
||||
ActiveUnitInfo: TUnitInfo;
|
||||
UnitFilename: string;
|
||||
begin
|
||||
if (DoInitProjectRun <> mrOK)
|
||||
or (ToolStatus <> itDebugger)
|
||||
or (FDebugger = nil)
|
||||
then begin
|
||||
Result := mrAbort;
|
||||
Exit;
|
||||
end;
|
||||
|
||||
Result := mrCancel;
|
||||
|
||||
GetCurrentUnit(ActiveSrcEdit, ActiveUnitInfo);
|
||||
if (ActiveSrcEdit=nil) or (ActiveUnitInfo=nil)
|
||||
then begin
|
||||
MessageDlg('Run to failed','Please open a unit before run.',mtError,
|
||||
[mbCancel],0);
|
||||
Exit;
|
||||
end;
|
||||
|
||||
if not ActiveUnitInfo.Source.IsVirtual
|
||||
then UnitFilename:=ActiveUnitInfo.Filename
|
||||
else UnitFilename:=GetTestUnitFilename(ActiveUnitInfo);
|
||||
|
||||
FDebugger.RunTo(ExtractFilename(UnitFilename), ActiveSrcEdit.EditorComponent.CaretY);
|
||||
|
||||
Result := mrOK;
|
||||
end;
|
||||
|
||||
|
||||
|
||||
|
148
ide/main.pp
148
ide/main.pp
@ -42,14 +42,10 @@ uses
|
||||
Debugger, DBGOutputForm, GDBMIDebugger, RunParamsOpts, ExtToolDialog,
|
||||
MacroPromptDlg, LMessages, ProjectDefs, Watchesdlg, BreakPointsdlg, ColumnDlg,
|
||||
OutputFilter, BuildLazDialog, MiscOptions, EditDefineTree, CodeToolsOptions,
|
||||
TypInfo, IDEOptionDefs, CodeToolsDefines, LocalsDlg, DebuggerDlg, MainBar;
|
||||
TypInfo, IDEOptionDefs, CodeToolsDefines, LocalsDlg, DebuggerDlg,
|
||||
BaseDebugManager, DebugManager, MainBar;
|
||||
|
||||
type
|
||||
|
||||
{$DEFINE IDE_TYPE}
|
||||
{$I ide_debugger.inc}
|
||||
{$UNDEF IDE_TYPE}
|
||||
|
||||
TMainIDE = class(TMainIDEBar)
|
||||
// event handlers
|
||||
//procedure FormShow(Sender : TObject);
|
||||
@ -201,10 +197,6 @@ type
|
||||
var Abort: boolean);
|
||||
procedure OnExtToolFreeOutputFilter(OutputFilter: TOutputFilter;
|
||||
ErrorOccurred: boolean);
|
||||
|
||||
{$DEFINE IDE_HEAD}
|
||||
{$I ide_debugger.inc}
|
||||
{$UNDEF IDE_HEAD}
|
||||
private
|
||||
FHintSender : TObject;
|
||||
FCodeLastActivated : Boolean; // used for toggling between code and forms
|
||||
@ -221,9 +213,6 @@ type
|
||||
function CreateSeperator : TMenuItem;
|
||||
procedure SetDefaultsForForm(aForm : TCustomForm);
|
||||
|
||||
{$DEFINE IDE_PRIVATE}
|
||||
{$I ide_debugger.inc}
|
||||
{$UNDEF IDE_PRIVATE}
|
||||
protected
|
||||
procedure ToolButtonClick(Sender : TObject);
|
||||
procedure OnApplyWindowLayout(ALayout: TIDEWindowLayout);
|
||||
@ -243,7 +232,7 @@ type
|
||||
procedure SetupToolsMenu;
|
||||
procedure SetupEnvironmentMenu;
|
||||
procedure SetupHelpMenu;
|
||||
procedure ConnectFormEvents;
|
||||
procedure ConnectMainBarEvents;
|
||||
procedure LoadMenuShortCuts;
|
||||
procedure SetupSpeedButtons;
|
||||
procedure SetupComponentNoteBook;
|
||||
@ -293,9 +282,7 @@ type
|
||||
function DoCompleteLoadingProjectInfo: TModalResult;
|
||||
|
||||
public
|
||||
ToolStatus: TIDEToolStatus;
|
||||
|
||||
constructor Create(AOwner: TComponent); override;
|
||||
constructor Create(TheOwner: TComponent); override;
|
||||
destructor Destroy; override;
|
||||
|
||||
// files/units
|
||||
@ -306,7 +293,7 @@ type
|
||||
function DoCloseEditorUnit(PageIndex:integer;
|
||||
SaveFirst: boolean):TModalResult;
|
||||
function DoOpenEditorFile(const AFileName:string;
|
||||
Flags: TOpenFlags): TModalResult;
|
||||
Flags: TOpenFlags): TModalResult; override;
|
||||
function DoOpenFileAtCursor(Sender: TObject):TModalResult;
|
||||
function DoSaveAll: TModalResult;
|
||||
function DoOpenMainUnit(ProjectLoading: boolean): TModalResult;
|
||||
@ -320,7 +307,7 @@ type
|
||||
function DoAddActiveUnitToProject: TModalResult;
|
||||
function DoRemoveFromProjectDialog: TModalResult;
|
||||
function DoBuildProject(BuildAll: boolean): TModalResult;
|
||||
function DoInitProjectRun: TModalResult;
|
||||
function DoInitProjectRun: TModalResult; override;
|
||||
function DoRunProject: TModalResult;
|
||||
function SomethingOfProjectIsModified: boolean;
|
||||
function DoCreateProjectForProgram(ProgramBuf: TCodeBuffer): TModalResult;
|
||||
@ -335,13 +322,13 @@ type
|
||||
|
||||
// useful methods
|
||||
procedure GetCurrentUnit(var ActiveSourceEditor:TSourceEditor;
|
||||
var ActiveUnitInfo:TUnitInfo);
|
||||
var ActiveUnitInfo:TUnitInfo); override;
|
||||
procedure DoSwitchToFormSrc(var ActiveSourceEditor:TSourceEditor;
|
||||
var ActiveUnitInfo:TUnitInfo);
|
||||
procedure GetUnitWithPageIndex(PageIndex:integer;
|
||||
var ActiveSourceEditor:TSourceEditor; var ActiveUnitInfo:TUnitInfo);
|
||||
function GetSourceEditorForUnitInfo(AnUnitInfo: TUnitInfo): TSourceEditor;
|
||||
function FindUnitFile(const AFilename: string): string;
|
||||
function FindUnitFile(const AFilename: string): string; override;
|
||||
function DoSaveStreamToFile(AStream:TStream; const Filename:string;
|
||||
IsPartOfProject:boolean): TModalResult;
|
||||
function DoLoadMemoryStreamFromFile(MemStream: TMemoryStream;
|
||||
@ -382,8 +369,8 @@ type
|
||||
procedure DoArrangeSourceEditorAndMessageView;
|
||||
function GetProjectTargetFilename: string;
|
||||
function GetTestProjectFilename: string;
|
||||
function GetTestUnitFilename(AnUnitInfo: TUnitInfo): string;
|
||||
function GetRunCommandLine: string;
|
||||
function GetTestUnitFilename(AnUnitInfo: TUnitInfo): string; override;
|
||||
function GetRunCommandLine: string; override;
|
||||
procedure OnMacroSubstitution(TheMacro: TTransferMacro; var s:string;
|
||||
var Handled, Abort: boolean);
|
||||
function OnMacroPromptFunction(const s:string; var Abort: boolean):string;
|
||||
@ -412,10 +399,6 @@ type
|
||||
procedure SaveEnvironment;
|
||||
procedure LoadDesktopSettings(TheEnvironmentOptions: TEnvironmentOptions);
|
||||
procedure SaveDesktopSettings(TheEnvironmentOptions: TEnvironmentOptions);
|
||||
|
||||
{$DEFINE IDE_PUBLIC}
|
||||
{$I ide_debugger.inc}
|
||||
{$UNDEF IDE_PUBLIC}
|
||||
end;
|
||||
|
||||
|
||||
@ -574,9 +557,10 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
constructor TMainIDE.Create(AOwner: TComponent);
|
||||
constructor TMainIDE.Create(TheOwner: TComponent);
|
||||
begin
|
||||
inherited Create(AOwner);
|
||||
MainIDE:=Self;
|
||||
inherited Create(TheOwner);
|
||||
|
||||
// load options
|
||||
ParseCmdLineOptions;
|
||||
@ -597,10 +581,14 @@ begin
|
||||
SetupMainMenu;
|
||||
SetupSpeedButtons;
|
||||
SetupComponentNoteBook;
|
||||
ConnectFormEvents;
|
||||
ConnectMainBarEvents;
|
||||
SetupHints;
|
||||
end;
|
||||
|
||||
DebugBoss:=TDebugManager.Create(Self);
|
||||
DebugBoss.ConnectMainBarEvents;
|
||||
|
||||
LoadMenuShortCuts;
|
||||
SetupComponentTabs;
|
||||
SetupOutputFilter;
|
||||
SetupCompilerInterface;
|
||||
@ -608,9 +596,8 @@ begin
|
||||
SetupFormEditor;
|
||||
SetupSourceNotebook;
|
||||
SetupTransferMacros;
|
||||
DebugConstructor;
|
||||
SetupControlSelection;
|
||||
|
||||
|
||||
SetupStartProject;
|
||||
end;
|
||||
|
||||
@ -618,10 +605,9 @@ destructor TMainIDE.Destroy;
|
||||
begin
|
||||
writeln('[TMainIDE.Destroy] A');
|
||||
{$IFDEF IDE_MEM_CHECK}CheckHeap(IntToStr(GetMem_Cnt));{$ENDIF}
|
||||
if FDebugger <> nil then FDebugger.Done;
|
||||
DebugBoss.EndDebugging;
|
||||
|
||||
FreeThenNil(Project1);
|
||||
FreeThenNil(FBreakPoints);
|
||||
if TheControlSelection<>nil then begin
|
||||
TheControlSelection.OnChange:=nil;
|
||||
FreeThenNil(TheControlSelection);
|
||||
@ -637,8 +623,6 @@ writeln('[TMainIDE.Destroy] A');
|
||||
FreeThenNil(EnvironmentOptions);
|
||||
FreeThenNil(HintTimer1);
|
||||
FreeThenNil(HintWindow1);
|
||||
FreeThenNil(Watches_Dlg);
|
||||
FreeThenNil(FDebugger);
|
||||
|
||||
writeln('[TMainIDE.Destroy] B -> inherited Destroy...');
|
||||
{$IFDEF IDE_MEM_CHECK}CheckHeap(IntToStr(GetMem_Cnt));{$ENDIF}
|
||||
@ -959,9 +943,7 @@ begin
|
||||
SourceNotebook.OnShowUnitInfo := @OnSrcNoteBookShowUnitInfo;
|
||||
SourceNotebook.OnToggleFormUnitClicked := @OnSrcNotebookToggleFormUnit;
|
||||
SourceNotebook.OnViewJumpHistory := @OnSrcNotebookViewJumpHistory;
|
||||
SourceNotebook.OnAddWatchAtCursor := @OnSrcNotebookAddWatchesAtCursor;
|
||||
SourceNotebook.OnCreateBreakPoint := @OnSrcNotebookCreateBreakPoint;
|
||||
SourceNotebook.OnDeleteBreakPoint := @OnSrcNotebookDeleteBreakPoint;
|
||||
DebugBoss.ConnectSourceNotebookEvents;
|
||||
|
||||
// connect search menu to sourcenotebook
|
||||
itmSearchFind.OnClick := @SourceNotebook.FindClicked;
|
||||
@ -1118,9 +1100,6 @@ begin
|
||||
SetupToolsMenu;
|
||||
SetupEnvironmentMenu;
|
||||
SetupHelpMenu;
|
||||
DebugLoadMenus;
|
||||
|
||||
LoadMenuShortCuts;
|
||||
end;
|
||||
|
||||
procedure TMainIDE.AddRecentSubMenu(ParentMenuItem: TMenuItem;
|
||||
@ -1395,6 +1374,26 @@ begin
|
||||
itmViewDebugWindows.Name := 'itmViewDebugWindows';
|
||||
itmViewDebugWindows.Caption := 'Debug windows';
|
||||
mnuView.Add(itmViewDebugWindows);
|
||||
|
||||
itmViewWatches := TMenuItem.Create(Self);
|
||||
itmViewWatches.Name:='itmViewWatches';
|
||||
itmViewWatches.Caption := 'Watches';
|
||||
itmViewDebugWindows.Add(itmViewWatches);
|
||||
|
||||
itmViewBreakPoints := TMenuItem.Create(Self);
|
||||
itmViewBreakPoints.Name:='itmViewBreakPoints';
|
||||
itmViewBreakPoints.Caption := 'BreakPoints';
|
||||
itmViewDebugWindows.Add(itmViewBreakPoints);
|
||||
|
||||
itmViewLocals := TMenuItem.Create(Self);
|
||||
itmViewLocals.Name:='itmViewLocals';
|
||||
itmViewLocals.Caption := 'Local Variables';
|
||||
itmViewDebugWindows.Add(itmViewLocals);
|
||||
|
||||
itmViewDebugOutput := TMenuItem.Create(Self);
|
||||
itmViewDebugOutput.Name:='itmViewDebugOutput';
|
||||
itmViewDebugOutput.Caption := 'Debug output';
|
||||
itmViewDebugWindows.Add(itmViewDebugOutput);
|
||||
end;
|
||||
|
||||
procedure TMainIDE.SetupProjectMenu;
|
||||
@ -1599,7 +1598,7 @@ begin
|
||||
mnuHelp.Add(itmHelpAboutLazarus);
|
||||
end;
|
||||
|
||||
procedure TMainIDE.ConnectFormEvents;
|
||||
procedure TMainIDE.ConnectMainBarEvents;
|
||||
begin
|
||||
//OnShow := @FormShow;
|
||||
OnClose := @FormClose;
|
||||
@ -1807,11 +1806,11 @@ begin
|
||||
ecBuildAll: DoBuildProject(Command=ecBuildAll);
|
||||
|
||||
ecRun: DoRunProject;
|
||||
ecPause: DoPauseProject;
|
||||
ecStepInto: DoStepIntoProject;
|
||||
ecStepOver: DoStepOverProject;
|
||||
ecRunToCursor: DoRunToCursor;
|
||||
ecStopProgram: DoStopProject;
|
||||
ecPause: DebugBoss.DoPauseProject;
|
||||
ecStepInto: DebugBoss.DoStepIntoProject;
|
||||
ecStepOver: DebugBoss.DoStepOverProject;
|
||||
ecRunToCursor: DebugBoss.DoRunToCursor;
|
||||
ecStopProgram: DebugBoss.DoStopProject;
|
||||
|
||||
ecFindProcedureDefinition,ecFindProcedureMethod:
|
||||
DoJumpToProcedureSection;
|
||||
@ -2033,27 +2032,27 @@ end;
|
||||
|
||||
Procedure TMainIDE.mnuPauseProjectClicked(Sender : TObject);
|
||||
begin
|
||||
DoPauseProject;
|
||||
DebugBoss.DoPauseProject;
|
||||
end;
|
||||
|
||||
Procedure TMainIDE.mnuStepIntoProjectClicked(Sender : TObject);
|
||||
begin
|
||||
DoStepIntoProject;
|
||||
DebugBoss.DoStepIntoProject;
|
||||
end;
|
||||
|
||||
Procedure TMainIDE.mnuStepOverProjectClicked(Sender : TObject);
|
||||
begin
|
||||
DoStepOverProject;
|
||||
DebugBoss.DoStepOverProject;
|
||||
end;
|
||||
|
||||
Procedure TMainIDE.mnuRunToCursorProjectClicked(Sender : TObject);
|
||||
begin
|
||||
DoRunToCursor;
|
||||
DebugBoss.DoRunToCursor;
|
||||
end;
|
||||
|
||||
Procedure TMainIDE.mnuStopProjectClicked(Sender : TObject);
|
||||
begin
|
||||
DoStopProject;
|
||||
DebugBoss.DoStopProject;
|
||||
end;
|
||||
|
||||
procedure TMainIDE.mnuProjectCompilerSettingsClicked(Sender : TObject);
|
||||
@ -2402,7 +2401,8 @@ function TMainIDE.DoShowSaveFileAsDialog(AnUnitInfo: TUnitInfo;
|
||||
var
|
||||
SaveDialog: TSaveDialog;
|
||||
SaveAsFilename, SaveAsFileExt, NewFilename, NewUnitName, NewFilePath,
|
||||
NewResFilename, NewResFilePath, OldFilePath, NewPageName: string;
|
||||
NewResFilename, NewResFilePath, OldFilePath, NewPageName,
|
||||
NewLFMFilename: string;
|
||||
ACaption, AText: string;
|
||||
SrcEdit: TSourceEditor;
|
||||
NewSource: TCodeBuffer;
|
||||
@ -2502,9 +2502,10 @@ begin
|
||||
if AnUnitInfo.FormName='' then begin
|
||||
// unit has no form
|
||||
// -> remove lfm file, so that it will not be auto loaded on next open
|
||||
NewResFilename:=ChangeFileExt(NewFilename,'.lfm');
|
||||
if (not DeleteFile(NewResFilename))
|
||||
and (MessageDlg('Delete failed','Deleting of file "'+NewResFilename+'"'
|
||||
NewLFMFilename:=ChangeFileExt(NewFilename,'.lfm');
|
||||
if (FileExists(NewLFMFilename))
|
||||
and (not DeleteFile(NewLFMFilename))
|
||||
and (MessageDlg('Delete failed','Deleting of file "'+NewLFMFilename+'"'
|
||||
+' failed.',mtError,[mbIgnore,mbCancel],0)=mrCancel) then
|
||||
begin
|
||||
Result:=mrCancel;
|
||||
@ -4351,10 +4352,9 @@ end;
|
||||
|
||||
function TMainIDE.DoInitProjectRun: TModalResult;
|
||||
var
|
||||
ProgramFilename, LaunchingCmdLine, LaunchingApplication,
|
||||
LaunchingParams: String;
|
||||
ProgramFilename: String;
|
||||
begin
|
||||
if ToolStatus = itDebugger
|
||||
if ToolStatus <> itNone
|
||||
then begin
|
||||
// already running so no initialization needed
|
||||
Result := mrOk;
|
||||
@ -4382,17 +4382,12 @@ begin
|
||||
[mbCancel], 0);
|
||||
Exit;
|
||||
end;
|
||||
LaunchingCmdLine:=GetRunCommandLine;
|
||||
|
||||
// Setup debugger
|
||||
case EnvironmentOptions.DebuggerType of
|
||||
dtGnuDebugger: begin
|
||||
if (FDebugger = nil)
|
||||
and (DoInitDebugger <> mrOk)
|
||||
if (DebugBoss.DoInitDebugger <> mrOk)
|
||||
then Exit;
|
||||
SplitCmdLine(LaunchingCmdLine,LaunchingApplication,LaunchingParams);
|
||||
FDebugger.FileName := LaunchingApplication;
|
||||
FDebugger.Arguments := LaunchingParams;
|
||||
// ToDo: set working directory
|
||||
end;
|
||||
else
|
||||
@ -4400,7 +4395,7 @@ begin
|
||||
try
|
||||
CheckIfFileIsExecutable(ProgramFilename);
|
||||
FRunProcess := TProcess.Create(nil);
|
||||
FRunProcess.CommandLine := LaunchingCmdLine;
|
||||
FRunProcess.CommandLine := GetRunCommandLine;
|
||||
FRunProcess.CurrentDirectory:=
|
||||
Project1.RunParameterOptions.WorkingDirectory;
|
||||
FRunProcess.Options:= [poNoConsole];
|
||||
@ -4413,9 +4408,6 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
if FDebugOutputDlg <> nil
|
||||
then FDebugOutputDlg.Clear;
|
||||
|
||||
Result := mrOK;
|
||||
ToolStatus := itDebugger;
|
||||
end;
|
||||
@ -4433,13 +4425,10 @@ begin
|
||||
|
||||
Result := mrCancel;
|
||||
|
||||
case EnvironmentOptions.DebuggerType of
|
||||
dtGnuDebugger: begin
|
||||
if FDebugger = nil then Exit;
|
||||
FDebugger.Run;
|
||||
Result := mrOK;
|
||||
end;
|
||||
else
|
||||
if EnvironmentOptions.DebuggerType <> dtNone then begin
|
||||
DebugBoss.RunDebugger;
|
||||
Result := mrOK;
|
||||
end else begin
|
||||
if FRunProcess = nil then Exit;
|
||||
try
|
||||
Writeln(' EXECUTING "',FRunProcess.CommandLine,'"');
|
||||
@ -6148,7 +6137,7 @@ begin
|
||||
|
||||
itmHelpAboutLazarus.ShortCut:=CommandToShortCut(ecAboutLazarus);
|
||||
end;
|
||||
DebugCreateShortCuts;
|
||||
DebugBoss.SetupMainBarShortCuts;
|
||||
end;
|
||||
|
||||
procedure TMainIDE.mnuSearchFindBlockOtherEnd(Sender: TObject);
|
||||
@ -6185,6 +6174,9 @@ end.
|
||||
|
||||
{ =============================================================================
|
||||
$Log$
|
||||
Revision 1.259 2002/03/27 10:39:42 lazarus
|
||||
MG: splitted main.pp: debugger management in TDebugManager
|
||||
|
||||
Revision 1.258 2002/03/27 09:25:31 lazarus
|
||||
MG: renamed main Project to Project1
|
||||
|
||||
|
@ -138,6 +138,10 @@ type
|
||||
itmViewForms : TMenuItem;
|
||||
itmViewMessage : TMenuItem;
|
||||
itmViewDebugWindows: TMenuItem;
|
||||
itmViewwatches: TMenuItem;
|
||||
itmViewBreakpoints: TMenuItem;
|
||||
itmViewLocals: TMenuItem;
|
||||
itmViewDebugOutput: TMenuItem;
|
||||
|
||||
itmProjectNew: TMenuItem;
|
||||
itmProjectOpen: TMenuItem;
|
||||
@ -178,7 +182,18 @@ type
|
||||
HintTimer1 : TTimer;
|
||||
HintWindow1 : THintWindow;
|
||||
public
|
||||
|
||||
ToolStatus: TIDEToolStatus;
|
||||
function FindUnitFile(const AFilename: string): string; virtual; abstract;
|
||||
procedure GetCurrentUnit(var ActiveSourceEditor:TSourceEditor;
|
||||
var ActiveUnitInfo:TUnitInfo); virtual; abstract;
|
||||
|
||||
function GetTestUnitFilename(AnUnitInfo: TUnitInfo): string; virtual; abstract;
|
||||
function GetRunCommandLine: string; virtual; abstract;
|
||||
|
||||
function DoOpenEditorFile(const AFileName:string;
|
||||
Flags: TOpenFlags): TModalResult; virtual; abstract;
|
||||
function DoInitProjectRun: TModalResult; virtual; abstract;
|
||||
|
||||
end;
|
||||
|
||||
var
|
||||
|
Loading…
Reference in New Issue
Block a user