#97, pass input to program using the field dedicated to custom commands

input must be prefixed by '>' to be recognized
This commit is contained in:
Basile Burg 2016-10-29 05:08:35 +02:00
parent f26a83d431
commit db87798694
No known key found for this signature in database
GPG Key ID: 1868039F415CB8CF
2 changed files with 47 additions and 22 deletions

View File

@ -130,7 +130,7 @@ inherited CEGdbWidget: TCEGdbWidget
object Edit1: TComboBox object Edit1: TComboBox
Left = 0 Left = 0
Height = 28 Height = 28
Hint = 'custom GDB command' Hint = 'enter a custom GDB command or the program input with ">"'
Top = 0 Top = 0
Width = 479 Width = 479
Align = alClient Align = alClient

View File

@ -7,7 +7,7 @@ interface
uses uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, RegExpr, ComCtrls, Classes, SysUtils, FileUtil, Forms, Controls, Graphics, RegExpr, ComCtrls,
PropEdits, GraphPropEdits, RTTIGrids, Dialogs, ExtCtrls, Menus, Buttons, PropEdits, GraphPropEdits, RTTIGrids, Dialogs, ExtCtrls, Menus, Buttons,
StdCtrls, ValEdit, process, fpjson, typinfo, StdCtrls, ValEdit, process, fpjson, typinfo, {$IFDEF UNIX}Unix,{$ENDIF}
ce_common, ce_interfaces, ce_widget, ce_processes, ce_observer, ce_synmemo, ce_common, ce_interfaces, ce_widget, ce_processes, ce_observer, ce_synmemo,
ce_sharedres, ce_stringrange, ce_dsgncontrols, ce_dialogs, ce_dbgitf, ce_sharedres, ce_stringrange, ce_dsgncontrols, ce_dialogs, ce_dbgitf,
ce_ddemangle, ce_writableComponent, ce_symstring; ce_ddemangle, ce_writableComponent, ce_symstring;
@ -354,11 +354,11 @@ type
procedure mnuWriteWClick(Sender: TObject); procedure mnuWriteWClick(Sender: TObject);
protected protected
procedure setToolBarFlat(value: boolean); override; procedure setToolBarFlat(value: boolean); override;
procedure updateLoop; override;
private private
fSyms: ICESymStringExpander; fSyms: ICESymStringExpander;
fExe: string; fExe: string;
fOutputName: string; fOutputName: string;
fInputName: string;
fShowFromCustomCommand: boolean; fShowFromCustomCommand: boolean;
fUpdateMenu: boolean; fUpdateMenu: boolean;
fGdbState: TGdbState; fGdbState: TGdbState;
@ -373,6 +373,7 @@ type
fMsg: ICEMessagesDisplay; fMsg: ICEMessagesDisplay;
fGdb: TCEProcess; fGdb: TCEProcess;
fOutput: TFileStream; fOutput: TFileStream;
fInput: TFileStream;
fInspState: TInspectableCPU; fInspState: TInspectableCPU;
fStackItems: TStackItems; fStackItems: TStackItems;
fCatchPause: boolean; fCatchPause: boolean;
@ -877,7 +878,7 @@ begin
end; end;
{$ENDREGION} {$ENDREGION}
{$REGION SteopReasons ----------------------------------------------------------} {$REGION StopReasons -----------------------------------------------------------}
{$IFDEF DEBUG}{$PUSH}{$R-}{$ENDIF} {$IFDEF DEBUG}{$PUSH}{$R-}{$ENDIF}
class function stopReasons.hash(const w: string): Byte; class function stopReasons.hash(const w: string): Byte;
var var
@ -1131,8 +1132,13 @@ begin
if fProj <> project then if fProj <> project then
exit; exit;
fProj := nil; fProj := nil;
if not fDbgRunnable and fOutputName.fileExists then if not fDbgRunnable then
begin
if fOutputName.fileExists then
deleteFile(fOutputName); deleteFile(fOutputName);
if fInputName.fileExists then
deleteFile(fInputName);
end;
end; end;
procedure TCEGdbWidget.projFocused(project: ICECommonProject); procedure TCEGdbWidget.projFocused(project: ICECommonProject);
@ -1168,8 +1174,13 @@ begin
if fDoc <> document then if fDoc <> document then
exit; exit;
fDoc := nil; fDoc := nil;
if fDbgRunnable and fOutputName.fileExists then if fDbgRunnable then
begin
if fOutputName.fileExists then
deleteFile(fOutputName); deleteFile(fOutputName);
if fInputName.fileExists then
deleteFile(fInputName);
end;
end; end;
{$ENDREGION} {$ENDREGION}
@ -1222,7 +1233,6 @@ procedure TCEGdbWidget.addBreakPoint(const fname: string; line: integer; kind: T
begin begin
if fGdb.isNil or not fGdb.Running then if fGdb.isNil or not fGdb.Running then
exit; exit;
//TODO-cGDB: handle trace points
gdbCommand('break ' + fname + ':' + intToStr(line)); gdbCommand('break ' + fname + ':' + intToStr(line));
end; end;
@ -1323,8 +1333,15 @@ begin
fExe := fProj.outputFilename fExe := fProj.outputFilename
else else
fExe := stripFileExt(fDoc.fileName) + exeExt; fExe := stripFileExt(fDoc.fileName) + exeExt;
fOutputName := fExe + '.gdbout'; //
fOutputName := fExe + '.inferiorout';
fInputName := fExe + '.inferiorin';
FreeAndNil(fInput);
if fInputName.fileExists then
deletefile(fInputName);
fInput:= TFileStream.Create(fInputName, fmCreate or fmShareExclusive);
FreeAndNil(fOutput); FreeAndNil(fOutput);
//
if not fExe.fileExists then if not fExe.fileExists then
begin begin
if fDbgRunnable then if fDbgRunnable then
@ -1348,7 +1365,6 @@ begin
//TODO-cGDB: debugee environment //TODO-cGDB: debugee environment
//TODO-cGDB: debugee command line //TODO-cGDB: debugee command line
//TODO-cGDB: pass input to debugee
fgdb.Parameters.Add('--interpreter=mi'); fgdb.Parameters.Add('--interpreter=mi');
fGdb.OnReadData:= @gdboutQuiet; fGdb.OnReadData:= @gdboutQuiet;
@ -1383,7 +1399,7 @@ begin
gdbCommand('-gdb-set mi-async on'); gdbCommand('-gdb-set mi-async on');
fGdb.OnReadData := @gdboutJsonize; fGdb.OnReadData := @gdboutJsonize;
// launch // launch
gdbCommand('run >' + fExe + '.gdbout'); gdbCommand('run >' + fOutputName + '< ' + fInputName);
setState(gsRunning); setState(gsRunning);
end; end;
{$ENDREGION} {$ENDREGION}
@ -1907,12 +1923,6 @@ begin
end; end;
procedure TCEGdbWidget.updateLoop;
begin
if fGdbState <> gsNone then
readOutput;
end;
procedure TCEGdbWidget.readOutput; procedure TCEGdbWidget.readOutput;
var var
str: TMemoryStream; str: TMemoryStream;
@ -2076,13 +2086,28 @@ var
cmd: string; cmd: string;
begin begin
cmd := edit1.Text; cmd := edit1.Text;
if cmd.isBlank or cmd.isEmpty then if cmd.isEmpty then
exit; exit;
if edit1.Items.IndexOf(cmd) = -1 then if edit1.Items.IndexOf(cmd) = -1 then
edit1.Items.Add(cmd); edit1.Items.Add(cmd);
cmd := fSyms.expand(edit1.Text); cmd := fSyms.expand(cmd);
if (cmd.length > 1) and (cmd[1] = '>') and assigned(fInput) then
begin
cmd := cmd[2..cmd.length] + #10;
fInput.Write(cmd[1], cmd.length);
{$IFDEF UNIX}
fpfsync(fInput.Handle);
{$ELSE}
FlushFileBuffers(fInput.Handle);
{$ENDIF}
sleep(100);
readOutput;
end
else
begin
fShowFromCustomCommand := true; fShowFromCustomCommand := true;
gdbCommand(cmd, @gdboutJsonize); gdbCommand(cmd, @gdboutJsonize);
end;
edit1.Text := ''; edit1.Text := '';
end; end;