Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / lazarus / 2018-05

Cloning standard output to text file

10 messages · 6 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Carlos E. R.

Hi,

I know I did this decades ago with Turbo Pascal, but I can't remember how, and my google foo fails me.

I want to do a series of "writeln(...)" and have the output go simultaneously to the console and to a text file of my choice. I have the vague idea that this was done writing a text file handler :-?

I can of course do two writeln calls for each current call, but it is a nuisance.

I can not use a mywriteln wrapper that would do the two calls, because I do not know how to create a procedure that takes a variant number of parameters, as "writeln()" does...

Ideas?

If you know of a google search string to locate these ideas, just tell me ;-)

Cheers / Saludos, Carlos E. R. (from 42.3 x86_64 "Malachite" at Telcontar) -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 181 bytes Desc: OpenPGP digital signature URL: <http://lists.lazarus-ide.org/pipermail/lazarus/attachments/20180504/69a3306e/attachment.sig>

Reply by email

Mattias Gaertner
to Carlos E. R.
Show quoted text 7 lines
[...] I want to do a series of "writeln(...)" and have the output go simultaneously to the console and to a text file of my choice. I have the vague idea that this was done writing a text file handler :-? [...] If you know of a google search string to locate these ideas, just tell me ;-)

fpc redirect stdout

Mattias

Reply by email

Bart
to Carlos E. R.: I know I did this decades ago with Turbo Pascal, but I can't remember how, and my google…
Carlos E. R. wrote
I want to do a series of "writeln(...)" and have the output go simultaneously to the console and to a text file of my choice. I have the vague idea that this was done writing a text file handler :-?

I once wrote a simple utility (myutil) that read from stdin, echoed to stdout and echoed to a logfile.
I then used a pipe from the commandline to achieve what I wanted. E.g.:

myprog | mytuil path/to/log

Or something similar to that.

Bart

Reply by email

Carlos E. R.
to Mattias Gaertner: On Fri, 4 May 2018 12:51:38 +0200 fpc redirect stdout Mattias
Mattias Gaertner wrote 12 lines
On Fri, 4 May 2018 12:51:38 +0200 "Carlos E. R. via Lazarus" wrote: > [...] > I want to do a series of "writeln(...)" and have the output go > simultaneously to the console and to a text file of my choice. I have > the vague idea that this was done writing a text file handler :-? > [...] > If you know of a google search string to locate these ideas, just tell > me ;-) fpc redirect stdout

Thank you! :-)

Found it. At least for redirection, the output is sent to a file.

<http://lists.freepascal.org/fpc-pascal/2010-July/026163.html>

Now I have to figure out how to write both to file and screen :-)

More ideas to investigate here:

<http://fpc-devel.freepascal.narkive.com/KZnUZaMJ/stdout-capture-for-fpc-rtl>

Cheers / Saludos, Carlos E. R. (from 42.3 x86_64 "Malachite" at Telcontar) -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 181 bytes Desc: OpenPGP digital signature URL: <http://lists.lazarus-ide.org/pipermail/lazarus/attachments/20180504/680ad87b/attachment.sig>

Reply by email

Carlos E. R.
to Bart: On Fri, May 4, 2018 at 12:51 PM, Carlos E. R. via Lazarus I once wrote a simple utility…
Bart wrote 15 lines
On Fri, May 4, 2018 at 12:51 PM, Carlos E. R. via Lazarus wrote: > I want to do a series of "writeln(...)" and have the output go > simultaneously to the console and to a text file of my choice. I have > the vague idea that this was done writing a text file handler :-? I once wrote a simple utility (myutil) that read from stdin, echoed to stdout and echoed to a logfile. I then used a pipe from the commandline to achieve what I wanted. E.g.: myprog | mytuil path/to/log Or something similar to that.

Yes, of course, that's what I'm doing now, but I wanted to do it internally, control the file name, perhaps rotate it, etc :-)

Actually:

myprog | tee mytuil path/to/log

It has the effect that text to screen is written in chunks, may stop at the middle of a line. So at the end each cycle, I issue a "flush(output);"

Cheers / Saludos, Carlos E. R. (from 42.3 x86_64 "Malachite" at Telcontar) -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 181 bytes Desc: OpenPGP digital signature URL: <http://lists.lazarus-ide.org/pipermail/lazarus/attachments/20180504/287cd1f7/attachment.sig>

Reply by email

Carlos E. R.
to Reimar Grabowski: On Fri, 4 May 2018 13:34:54 +0200 Perhaps you should use a logger. There are surely some…
Reimar Grabowski wrote 8 lines
On Fri, 4 May 2018 13:34:54 +0200 "Carlos E. R. via Lazarus" wrote: > Yes, of course, that's what I'm doing now, but I wanted to do it > internally, control the file name, perhaps rotate it, etc :-) Perhaps you should use a logger. There are surely some FPC ones out there that can do all this for you. A fast google search brings up http://wiki.freepascal.org/Log4Delphi which is based on Log4J (which does all that).

Well, I send to syslog the important things :-)

In this phase I use many writeln as debug help, and using a pipe and a tee does the job fine.

The idea here:
<http://lists.freepascal.org/fpc-pascal/2010-July/026163.html> redirects all stdout to a file, but I'm thinking that it is basically the same as replacing all writeln found with writeln(F, ...), achieving the same thing perhaps simpler. Well, except that commenting out a the call to "redirect" disables it.

The basic trick it does is:

var
  f : TextFile;
  s: TDebugStream;

and a procedure to redirect the output:

procedure redirect;
begin
 s := TDebugStream.Create();
 AssignStream(f, s);
 Rewrite(f);
 output := f;
end;

wich replaces stdout (output) with f. The role of tTDebugStream I don't get. It is created thus:

Type
  TDebugStream = class(TStream)
    function Write(const Buffer; Count : Longint) : Longint; override;
  end;
implementation
function TDebugStream.Write(const Buffer; Count : Longint) : Longint;
var
  msg : ansistring;
begin
  result := count;
  SetLength(msg, count);
  move(buffer, PChar(msg)[0], count);
  OutputDebugString(PChar(TrimRight(msg)));
end;

I also miss where the file name is assigned.

But anyway, what I wanted is to write both to the screen and to a file, so this is not sufficient.

Further in the thread they say that this would do - this is the classic method I had forgotten:

var
   oldoutput, f: TextFile;
begin
   AssignFile(f, 'somefile');
   Rewrite(f);
   oldoutput := Output;
   Output := f;
   Writeln('Hello World'); // this is send to Output
   Output := oldoutput;
   CloseFile(f);
end.

At the start of the thread there is a suggestion to "implementing your own textfile driver", but the link is dead.

Cheers / Saludos, Carlos E. R. (from 42.3 x86_64 "Malachite" at Telcontar) -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 181 bytes Desc: OpenPGP digital signature URL: <http://lists.lazarus-ide.org/pipermail/lazarus/attachments/20180504/088c00f0/attachment.sig>

Reply by email

Carlos E. R.
to Marco van de Voort: fpc streamio
Marco van de Voort wrote 5 lines
On Fri, May 04, 2018 at 01:31:50PM +0200, Carlos E. R. via Lazarus wrote: > Now I have to figure out how to write both to file and screen :-) fpc streamio

Results in church related links, LOL.

Better "freepascal streamio".

<https://www.freepascal.org/docs-html/fcl/streamio/index.html>

«The StreamIO unit implements a call to reroute the input or output of a text file to a descendents of TStream.»

Sorry, I fail to see how I can use this with writeln to write to *both* output and file at the same time. Maybe I miss something :-?

Cheers / Saludos, Carlos E. R. (from 42.3 x86_64 "Malachite" at Telcontar) -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 181 bytes Desc: OpenPGP digital signature URL: <http://lists.lazarus-ide.org/pipermail/lazarus/attachments/20180504/4745d262/attachment.sig>

Reply by email

leledumbo
to Carlos E. R.
Sorry, I fail to see how I can use this with writeln to write to *both* output and file at the same time. Maybe I miss something :-?
{$mode objfpc}{$H+}
uses
  Classes,SysUtils,StreamIO;
type
  TDoubleStream = class(TFileStream)
  private
    FStdOut: TextFile;
  public
    constructor Create(const AFileName: string; Mode: Word);
    destructor Destroy; override;
    function Write(const Buffer; Count: longint): longint; override;
  end;
constructor TDoubleStream.Create(const AFileName: string; Mode: Word);
begin
  inherited Create(AFileName,Mode);
  AssignFile(FStdOut,''); // empty string = stdout
  Rewrite(FStdOut);
end;
destructor TDoubleStream.Destroy;
begin
  CloseFile(FStdOut);
  inherited Destroy;
end;
function TDoubleStream.Write(const Buffer; Count: longint): longint;
var
  p: PChar;
begin
  Result := inherited Write(Buffer, Count);
  p := PChar(@Buffer); // safe assumption for standard output, I guess?
  while Count > 0 do begin
    System.Write(FStdOut,p^);
    Inc(p);
    Dec(Count);
  end;
end;
var
  ds: TStream;
begin
  ds := TDoubleStream.Create('log.txt', fmCreate or fmOpenWrite);
  try
    AssignStream(Output,ds);
    Rewrite(Output);
    WriteLn('Hello!');
  finally
    ds.Free;
  end;
end.

Reply by email