Re: [fpc-pascal] Procedures that work like WRITELN()
On Wed, Dec 27, 2023 at 3:42 PM Wayne Sherman wrote: > Example using a TFileStream descendant and StreamIO AssignStream: > ...(line 42 follows) > FileWrite(TextRec(Output).Handle, Buffer, Count); Although that worked (I don't know why) I intended line 42 to be: FileWrite(TextRec(FOriginalStdOut).Handle, Buffer, Count); ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Procedures that work like WRITELN()
Example using a TFileStream descendant and StreamIO AssignStream: program TeeStdOut; {$mode objfpc} uses Classes, SysUtils, StreamIO; type TTeeStream = class(TFileStream) Private FOriginalStdOut: Text; FNewStdOut: Text; public constructor Create(const AFileName: string; Mode: Word); destructor Destroy; override; function Write(const Buffer; Count : Longint) : Longint; override; end; constructor TTeeStream.Create(const AFileName: string; Mode: Word); begin inherited Create(AFileName, Mode); FOriginalStdOut := Output; // save original stdout AssignStream(FNewStdOut, Self); Rewrite(FNewStdOut); // The following code causes stdout to be redirected // to FNewStdOut (and our TTeeStream) Output := FNewStdOut; end; destructor TTeeStream.Destroy; begin Output := FOriginalStdOut; Close(FNewStdOut); inherited Destroy; end; function TTeeStream.Write(const Buffer; Count: Longint): Longint; begin Result := inherited Write(Buffer, Count); // FileWrite(System.StdOutPutHandle, Buffer, Count); //this also works FileWrite(TextRec(Output).Handle, Buffer, Count); end; var TeeStream: TTeeStream; begin WriteLn('WriteLn to stdout before TTeeStream redirect'); TeeStream := TTeeStream.Create('test.txt', fmCreate); try WriteLn('Hello, World! after creating TTeeStream'); WriteLn('(WriteLn to stdout redirected to console and to file)'); finally TeeStream.Free; end; WriteLn('WriteLn to stdout after destroying TTeeStream'); end. On Wed, Dec 27, 2023 at 3:25 AM James Richters via fpc-pascal wrote: > > I wanted to write what I thought should be a simple procedure, just instead > of calling WRITELN() with some arguments, > > call WRITELOG() with the same arguments that you would use to write to a > file, but my WRITELOG() procedure would > > write to the screen and the file.. but I can’t figure out how to pass all the > arguments to the two WRTIELNs. > > > > So…. > > > > Procedure WriteLog(Filename:String, AllOtherAurguments:); > > Begin > > Writeln(Filename,AllOtherAurguments); > > Writeln(AllOtherAurguments); > > End; > > > > How can I make this work? Since WRITELN can take any number of many kinds of > arguments, > > how can I get them all and pass them along without knowing how many or what > types they are? > > How does WRITELN even work when you don’t know this information? > > > > I’m guessing there should be some way to do this, because WRITELN itself > works, but how it could > > possibly work is not within my experience. > > > > The only way I could think of would be if there were versions of WRITELN with > every combination > > of possible arguments, but that seems completely unmanageable and ridiculous, > > so there must be something more advanced going on, but maybe WRTELN is > special and not something I can duplicate? > > > > > > Any Ideas? > > > > James > > ___ > fpc-pascal maillist - fpc-pascal@lists.freepascal.org > https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Procedures that work like WRITELN()
Am 27.12.2023 um 12:25 schrieb James Richters via fpc-pascal: I wanted to write what I thought should be a simple procedure, just instead of calling WRITELN() with some arguments, call WRITELOG() with the same arguments that you would use to write to a file, but my WRITELOG() procedure would write to the screen and the file.. but I can’t figure out how to pass all the arguments to the two WRTIELNs. So…. Procedure WriteLog(Filename:String, AllOtherAurguments:); Begin Writeln(Filename,AllOtherAurguments); Writeln(AllOtherAurguments); End; How can I make this work?Since WRITELN can take any number of many kinds of arguments, how can I get them all and pass them along without knowing how many or what types they are? How does WRITELN even work when you don’t know this information? I’m guessing there should be some way to do this, because WRITELN itself works, but how it could possibly work is not within my experience. The only way I could think of would be if there were versions of WRITELN with every combination of possible arguments, but that seems completely unmanageable and ridiculous, so there must be something more advanced going on, but maybe WRTELN is special and not something I can duplicate? Write(Ln) is a compiler intrinsic and thus can behave in ways that are not possible for ordinary functions. Your only ways are either to use "array of const" like "Format" does or write a text file driver as is done in the StreamIO unit which allows to assign a Stream to a TextFile that can in turn be used as the file parameter of Write(Ln). You can implement any other output through this. Regards, Sven___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Procedures that work like WRITELN()
On Wed, Dec 27, 2023 at 3:25 AM James Richters wrote: > I wanted to write what I thought should be a simple procedure, just instead > of calling WRITELN() with some arguments, call WRITELOG() with the same > arguments that you would use to write to a file, but my WRITELOG() procedure > would write to the screen and the file.. but I can’t figure out how to pass > all > the arguments to the two WRTIELNs. Essentially you want to emulate what the "tee" command does but internal to your program. You can intercept data written to STDOUT and copy the data to your desired destination(s) (i.e. to console and file). See message thread "redirecting stdout" here: https://lists.freepascal.org/pipermail/fpc-pascal/2010-July/thread.html#26149 Also redirecting stdout to a Stream / TMemo: https://forum.lazarus.freepascal.org/index.php/topic,34621.0.html ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Procedures that work like WRITELN()
It would be very useful if WriteStr() was a function that returned the resulting string instead of returning it via an output parameter. Then you could just wrap the Writeln parameters in WriteStr() and pass it to the new logging procedure. Unfortunately, the ISO extension did not end up doing that! Doug C.___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Procedures that work like WRITELN()
>Writeln() is special. You cannot duplicate it. That's good to know, I can stop trying. >What you can do is use WriteStr(), it has the same action as Writeln() but writes to a string instead of a file. I was hoping to just replace all existing Writeln()s with my procedure with a global search and replace. I think it's probably easiest to make my procedure: Procedure WriteLog(Filename:String, WriteString:String); Begin Writeln(Filename,WriteString); Writeln(WriteString); End; Then just fix the call to concatenate everything into a single string: So if I end up with this: WriteLog(Myfile,'some text ',MyInteger); I'll have to change it to this: WriteLog(Myfile,'some text '+InttoStr(MyInteger)); And if the arguments are really complicated I can just use WriteStr() to store it into a string and call my procedure with the resulting string. It will be a little more effort than doing a global search and replace but at least I know that it's the only way. Thanks for the help James ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Procedures that work like WRITELN()
I think he wants to define his own procedure. The nearest thing that comes into my mind is using ARRAY OF CONST, but the call requires square brackets, then: procedure myproc (x: string; y: array of const); begin ... end; myproc ('Hello world', ['Number 1', 'Number 2', 3, 4.0]); - Original Message - From: Michael Van Canneyt via fpc-pascal To: ja...@productionautomation.net Sent: Wednesday, December 27, 2023, 12:40:24 Subject: [fpc-pascal] Procedures that work like WRITELN() On Wed, 27 Dec 2023, James Richters via fpc-pascal wrote: > I wanted to write what I thought should be a simple procedure, just instead > of calling WRITELN() with some arguments, > call WRITELOG() with the same arguments that you would use to write to a > file, but my WRITELOG() procedure would > write to the screen and the file.. but I can't figure out how to pass all > the arguments to the two WRTIELNs. > So.. > Procedure WriteLog(Filename:String, AllOtherAurguments:); > Begin >Writeln(Filename,AllOtherAurguments); >Writeln(AllOtherAurguments); > End; > How can I make this work? Since WRITELN can take any number of many kinds > of arguments, > how can I get them all and pass them along without knowing how many or what > types they are? > How does WRITELN even work when you don't know this information? > I'm guessing there should be some way to do this, because WRITELN itself > works, but how it could > possibly work is not within my experience. > The only way I could think of would be if there were versions of WRITELN > with every combination > of possible arguments, but that seems completely unmanageable and > ridiculous, > so there must be something more advanced going on, but maybe WRTELN is > special and not something I can duplicate? Writeln() is special. You cannot duplicate it. What you can do is use WriteStr(), it has the same action as Writeln() but writes to a string instead of a file. https://www.freepascal.org/docs-html/current/rtl/system/writestr.html Michael. ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Procedures that work like WRITELN()
On Wed, 27 Dec 2023, James Richters via fpc-pascal wrote: I wanted to write what I thought should be a simple procedure, just instead of calling WRITELN() with some arguments, call WRITELOG() with the same arguments that you would use to write to a file, but my WRITELOG() procedure would write to the screen and the file.. but I can't figure out how to pass all the arguments to the two WRTIELNs. So.. Procedure WriteLog(Filename:String, AllOtherAurguments:); Begin Writeln(Filename,AllOtherAurguments); Writeln(AllOtherAurguments); End; How can I make this work? Since WRITELN can take any number of many kinds of arguments, how can I get them all and pass them along without knowing how many or what types they are? How does WRITELN even work when you don't know this information? I'm guessing there should be some way to do this, because WRITELN itself works, but how it could possibly work is not within my experience. The only way I could think of would be if there were versions of WRITELN with every combination of possible arguments, but that seems completely unmanageable and ridiculous, so there must be something more advanced going on, but maybe WRTELN is special and not something I can duplicate? Writeln() is special. You cannot duplicate it. What you can do is use WriteStr(), it has the same action as Writeln() but writes to a string instead of a file. https://www.freepascal.org/docs-html/current/rtl/system/writestr.html Michael. ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
[fpc-pascal] Procedures that work like WRITELN()
I wanted to write what I thought should be a simple procedure, just instead of calling WRITELN() with some arguments, call WRITELOG() with the same arguments that you would use to write to a file, but my WRITELOG() procedure would write to the screen and the file.. but I can't figure out how to pass all the arguments to the two WRTIELNs. So.. Procedure WriteLog(Filename:String, AllOtherAurguments:); Begin Writeln(Filename,AllOtherAurguments); Writeln(AllOtherAurguments); End; How can I make this work? Since WRITELN can take any number of many kinds of arguments, how can I get them all and pass them along without knowing how many or what types they are? How does WRITELN even work when you don't know this information? I'm guessing there should be some way to do this, because WRITELN itself works, but how it could possibly work is not within my experience. The only way I could think of would be if there were versions of WRITELN with every combination of possible arguments, but that seems completely unmanageable and ridiculous, so there must be something more advanced going on, but maybe WRTELN is special and not something I can duplicate? Any Ideas? James ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal