Jump to content
JohnF

Stdin and debugging in the IDE

Recommended Posts

Hi,

 

I've been writing an app that takes a data feed from Stdin, and while I have it working using the code below, which works fine if you are running it on the commandline

 

ie  sendstuff | MyApp

 

However I was trying to get the App to run inside the IDE by first piping the output to a file

 

sendstuff > xxx

 

and then in the run params having "< xxx", but it doesnt see the input as Stdin and you get a stream size of -1.

 

Anyone got any ideas how to be ablue to simulate the stdin properly so I can step through the code in the IDE, debugging via writeln really sucks.

 

Its a windows app atm, will eventually want to expand it so its windows/linux. Im using Delphi 12.2

 

John.

 

var
  StdInHandle: THandle;
  StdInStream: TStream;
  Buffer: TBytes;
  BytesRead: Integer;
begin
  StdInHandle := GetStdHandle(STD_INPUT_HANDLE);

// Ensure the handle is valid
  if StdInHandle = INVALID_HANDLE_VALUE then
    begin
      WriteErr('Invalid standard input handle.');
      Exit;
    end;
  try
    // Wrap the handle in a THandleStream for easier reading
    StdInStream := THandleStream.Create(StdInHandle);

    while StdInStream.Position < StdInStream.Size do
      begin
		SetLength(Buffer, StdInStream.Size);
        BytesRead := StdInStream.Read(Buffer, StdInStream.Size);
        // do stuff
                                                
      end;                                           

                                                 

 

Share this post


Link to post

At program startup, detect the presence of the debugger (dynamically, or via a command-line parameter) and then use SetStdHandle() to replace STDIN with your own handle to a named pipe or anonymous pipe, and then write your desired debug data to that pipe.

 

Or better, simply move your logic into a function that takes an input TStream as a parameter, and then decide whether you want to use a THandleStream for STDIN or a TStringStream or TMemoryStream for your debug data.

 

On a side note - using a 'while (Position < Size)' loop is not a good idea.  You should simply call Read() with a fixed-sized buffer, and let it tell you when it reaches the end of the stream, eg.

SetLength(Buffer, SomeSize);
repeat
  BytesRead := StdInStream.Read(Buffer, SomeSize);
  if BytesRead < 1 then Break;
  // do stuff
until False;
Edited by Remy Lebeau

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×