dexed/src/ce_cdbcmd.pas

210 lines
4.7 KiB
Plaintext

unit ce_cdbcmd;
{$I ce_defines.inc}
interface
uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ExtCtrls,
process, Menus, StdCtrls, ce_widget, ce_project, ce_interfaces, ce_observer,
asyncprocess, ComCtrls, Buttons, ce_common;
type
{ TCECdbWidget }
TCECdbWidget = class(TCEWidget, ICEProjectObserver)
btnGo: TSpeedButton;
btnStep: TSpeedButton;
btnDisasm: TSpeedButton;
btnStop: TSpeedButton;
btnStart: TSpeedButton;
txtCdbCmd: TEdit;
lstCdbOut: TListView;
Panel1: TPanel;
procedure btnDisasmClick(Sender: TObject);
procedure btnGoClick(Sender: TObject);
procedure btnStartClick(Sender: TObject);
procedure btnStepClick(Sender: TObject);
procedure btnStopClick(Sender: TObject);
procedure txtCdbCmdKeyPress(Sender: TObject; var Key: char);
private
fCdbProc: TAsyncProcess;
fProject: TCEProject;
procedure cdbOutput(sender: TObject);
procedure cdbTerminate(sender: TObject);
procedure cdbOutputToGui;
public
constructor create(aOwner: TComponent); override;
destructor destroy; override;
//
procedure projNew(aProject: TCEProject);
procedure projClosing(aProject: TCEProject);
procedure projFocused(aProject: TCEProject);
procedure projChanged(aProject: TCEProject);
end;
implementation
{$R *.lfm}
uses
ce_symstring;
{$REGION Standard Comp/Obj------------------------------------------------------}
constructor TCECdbWidget.create(aOwner: TComponent);
begin
inherited;
Enabled := exeInSysPath('cdb');
if Enabled then
begin
EntitiesConnector.addObserver(self);
EntitiesConnector.endUpdate;
end;
end;
destructor TCECdbWidget.destroy;
begin
if Enabled then begin
killProcess(fCdbProc);
EntitiesConnector.removeObserver(self);
end;
inherited;
end;
{$ENDREGION --------------------------------------------------------------------}
{$REGION ICEProjectMonitor -----------------------------------------------------}
procedure TCECdbWidget.projNew(aProject: TCEProject);
begin
fProject := aProject;
end;
procedure TCECdbWidget.projClosing(aProject: TCEProject);
begin
if fProject <> aProject then
exit;
fProject := nil;
end;
procedure TCECdbWidget.projFocused(aProject: TCEProject);
begin
fProject := aProject;
end;
procedure TCECdbWidget.projChanged(aProject: TCEProject);
begin
end;
{$ENDREGION --------------------------------------------------------------------}
procedure TCECdbWidget.btnStartClick(Sender: TObject);
var
outname: string;
begin
lstCdbOut.Clear;
if fProject = nil then
exit;
outname := fProject.outputFilename;
if not fileExists(outname) then
exit;
//
killProcess(fCdbProc);
fCdbProc := TAsyncProcess.create(nil);
fCdbProc.Executable := 'cdb';
fCdbProc.Parameters.Add('-c');
fCdbProc.Parameters.Add('"l+*;.lines"');
fCdbProc.Parameters.Add(outname);
fCdbProc.CurrentDirectory := extractFilePath(outname);
fCdbProc.Options := [poNoConsole, poStderrToOutPut, poUsePipes];
fCdbProc.OnReadData := @cdbOutput;
fCdbProc.OnTerminate := @cdbTerminate;
//
fCdbProc.Execute;
end;
procedure TCECdbWidget.btnStepClick(Sender: TObject);
const
cmd = 'p'#13#10;
begin
if fCdbProc = nil then
exit;
fCdbProc.Input.Write(cmd[1], length(cmd));
end;
procedure TCECdbWidget.btnGoClick(Sender: TObject);
const
cmd = 'g'#13#10;
begin
if fCdbProc = nil then
exit;
fCdbProc.Input.Write(cmd[1], length(cmd));
end;
procedure TCECdbWidget.btnDisasmClick(Sender: TObject);
const
cmd = 'u'#13#10;
begin
if fCdbProc = nil then
exit;
fCdbProc.Input.Write(cmd[1], length(cmd));
end;
procedure TCECdbWidget.btnStopClick(Sender: TObject);
const
cmd = 'q'#13#10;
begin
if fCdbProc <> nil
then
fCdbProc.Input.Write(cmd[1], length(cmd));
killProcess(fCdbProc);
end;
procedure TCECdbWidget.txtCdbCmdKeyPress(Sender: TObject; var Key: char);
var
inp: string;
cmd: string;
begin
if (fCdbProc = nil) or (key <> #13) then
exit;
//
cmd := symbolExpander.get(txtCdbCmd.Text);
inp := cmd + LineEnding;
fCdbProc.Input.Write(inp[1], length(inp));
//
inp := lstCdbOut.Items.Item[lstCdbOut.Items.Count-1].Caption;
inp += cmd;
lstCdbOut.Items.Item[lstCdbOut.Items.Count-1].Caption := inp;
//
txtCdbCmd.Text := '';
end;
procedure TCECdbWidget.cdbOutputToGui;
var
lst: TStringList;
str: string;
begin
if fCdbProc = nil then
exit;
//
lst := TStringList.Create;
try
processOutputToStrings(fCdbProc, lst);
for str in lst do
lstCdbOut.AddItem(str, nil);
lstCdbOut.Items[lstCdbOut.Items.Count-1].MakeVisible(true);
finally
lst.Free;
end;
end;
procedure TCECdbWidget.cdbOutput(sender: TObject);
begin
cdbOutputToGui;
end;
procedure TCECdbWidget.cdbTerminate(sender: TObject);
begin
cdbOutputToGui;
killProcess(fCdbProc);
end;
end.