Sign in Join

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

Mailing lists / fpc-pascal / 2015-03

Where is the 'write' function defined and how is it different from 'writeln'?

12 messages · 5 people · –

Reply by email Subscribe to this list Your subscription

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

leledumbo
to vfclists .
Where is the 'write' function defined and how is it different from

'writeln'?

I can see a lot of fpc_writeXXX and other xxxxWrite functions, but no 'write' itself

those fpc_writeXXX ARE the actual write. Write(Ln) is NOT a function as like others whose implementation you can clearly see. It's rather a command for the compiler to translate to the correct fpc_writeXXX call. So, if you:

WriteLn(123,' is an integer');

the compiler will translate it to:

fpc_write_text_shortint(123);
fpc_write_text_shortstring('is an integer');
fpc_writeln_end;

The same case applies to Read(Ln). AFAIK Pascal's I/O is part of the language, not the RTL.

Reply by email

vfclists .
to leledumbo
leledumbo wrote 24 lines
> Where is the 'write' function defined and how is it different from 'writeln'? > > I can see a lot of fpc_writeXXX and other xxxxWrite functions, but no > 'write' itself those fpc_writeXXX ARE the actual write. Write(Ln) is NOT a function as like others whose implementation you can clearly see. It's rather a command for the compiler to translate to the correct fpc_writeXXX call. So, if you: WriteLn(123,' is an integer'); the compiler will translate it to: fpc_write_text_shortint(123); fpc_write_text_shortstring('is an integer'); fpc_writeln_end; The same case applies to Read(Ln). AFAIK Pascal's I/O is part of the language, not the RTL.

Where does the output go? Is it for stdout, strderr or the console?

Frank Church ======================= http://devblog.brahmancreations.com

Reply by email

Sven Barth
to vfclists .
"vfclists ." wrote 12 lines
On 20 March 2015 at 18:01, leledumbo wrote: > > > Where is the 'write' function defined and how is it different from > 'writeln'? > > > > I can see a lot of fpc_writeXXX and other xxxxWrite functions, but no > > 'write' itself > > those fpc_writeXXX ARE the actual write. Write(Ln) is NOT a function as

like

> others whose implementation you can clearly see. It's rather a command

for

Show quoted text 16 lines
> the compiler to translate to the correct fpc_writeXXX call. So, if you: > > WriteLn(123,' is an integer'); > > the compiler will translate it to: > > fpc_write_text_shortint(123); > fpc_write_text_shortstring('is an integer'); > fpc_writeln_end; > > The same case applies to Read(Ln). AFAIK Pascal's I/O is part of the > language, not the RTL. > > Where does the output go? Is it for stdout, strderr or the console?

It depends.

Write('foobar');

Will write to whatever Textfile is contained in Output and

Write(xyz, 'foobar');

Will write to the xyz Textfile. And these Textfiles can basically be anything. By default Output simply writes to StdOut (there's also a variable for StdErr, but I have forgotten how it's called...), but you could also use an implementation that writes to a TStream or one which uses sockets. It's quite flexible...

Regards,
Sven

Reply by email

vfclists .
to Sven Barth
Sven Barth wrote 52 lines
Am 20.03.2015 19:19 schrieb "vfclists ." : > > > > On 20 March 2015 at 18:01, leledumbo wrote: >> >> > Where is the 'write' function defined and how is it different from >> 'writeln'? >> > >> > I can see a lot of fpc_writeXXX and other xxxxWrite functions, but no >> > 'write' itself >> >> those fpc_writeXXX ARE the actual write. Write(Ln) is NOT a function as like >> others whose implementation you can clearly see. It's rather a command for >> the compiler to translate to the correct fpc_writeXXX call. So, if you: >> >> WriteLn(123,' is an integer'); >> >> the compiler will translate it to: >> >> fpc_write_text_shortint(123); >> fpc_write_text_shortstring('is an integer'); >> fpc_writeln_end; >> >> The same case applies to Read(Ln). AFAIK Pascal's I/O is part of the >> language, not the RTL. >> >> > > Where does the output go? Is it for stdout, strderr or the console? It depends. Write('foobar'); Will write to whatever Textfile is contained in Output and Write(xyz, 'foobar'); Will write to the xyz Textfile. And these Textfiles can basically be anything. By default Output simply writes to StdOut (there's also a variable for StdErr, but I have forgotten how it's called...), but you could also use an implementation that writes to a TStream or one which uses sockets. It's quite flexible... Regards, Sven How do you ensure own implementation overrides the system's

implementation, does the compiler take care of that automatically, or will you have to name your function differently?

Frank Church ======================= http://devblog.brahmancreations.com

Reply by email

Sven Barth
to vfclists .
vfclists . wrote 66 lines
On 20 March 2015 at 19:34, Sven Barth < > wrote: Am 20.03.2015 19:19 schrieb "vfclists ." < >: > > > > On 20 March 2015 at 18:01, leledumbo < > wrote: >> >> > Where is the 'write' function defined and how is it different from >> 'writeln'? >> > >> > I can see a lot of fpc_writeXXX and other xxxxWrite functions, but no >> > 'write' itself >> >> those fpc_writeXXX ARE the actual write. Write(Ln) is NOT a function as like >> others whose implementation you can clearly see. It's rather a command for >> the compiler to translate to the correct fpc_writeXXX call. So, if you: >> >> WriteLn(123,' is an integer'); >> >> the compiler will translate it to: >> >> fpc_write_text_shortint(123); >> fpc_write_text_shortstring('is an integer'); >> fpc_writeln_end; >> >> The same case applies to Read(Ln). AFAIK Pascal's I/O is part of the >> language, not the RTL. >> >> > > Where does the output go? Is it for stdout, strderr or the console? It depends. Write('foobar'); Will write to whatever Textfile is contained in Output and Write(xyz, 'foobar'); Will write to the xyz Textfile. And these Textfiles can basically be anything. By default Output simply writes to StdOut (there's also a variable for StdErr, but I have forgotten how it's called...), but you could also use an implementation that writes to a TStream or one which uses sockets. It's quite flexible... Regards, Sven How do you ensure own implementation overrides the system's implementation, does the compiler take care of that automatically, or will you have to name your function differently?

There is no need to ensure that. Here is an example:

=== code begin ===

var
   f, oldout: TextFile;
begin
   Writeln('Hello Output as StdOut');
   oldout := Output;
   Assign(Output, 'test.txt');
   Rewrite(Output);
   Writeln('Hello Output as file');
   Close(f);
   Output := oldout;
   Writeln('Hello Output as StdOut again');
end.

=== code end ===

To see how such a TextFile is implemented you can take a look at unit StreamIO which is part of FPC's units.

(Though I wonder why "Assign(f, 'test.txt'); Output := f; Writeln('Hello
Output as file');" does not work :/ )

Regards,
Sven

Reply by email

vfclists .
to Sven Barth
Sven Barth wrote 11 lines
On 20.03.2015 21:18, vfclists . wrote: > > > On 20 March 2015 at 19:34, Sven Barth < > > wrote: > > Am 20.03.2015 19:19 schrieb "vfclists ." < > >: >

snip

Show quoted text 43 lines
How do you ensure own implementation overrides the system's > implementation, does the compiler take care of that automatically, or > will you have to name your function differently? > There is no need to ensure that. Here is an example: === code begin === var f, oldout: TextFile; begin Writeln('Hello Output as StdOut'); oldout := Output; Assign(Output, 'test.txt'); Rewrite(Output); Writeln('Hello Output as file'); Close(f); Output := oldout; Writeln('Hello Output as StdOut again'); end. === code end === To see how such a TextFile is implemented you can take a look at unit StreamIO which is part of FPC's units. (Though I wonder why "Assign(f, 'test.txt'); Output := f; Writeln('Hello Output as file');" does not work :/ ) Regards, Sven _______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

I need to get the output of a program which uses a lot of Write and Writeln commands into the GUI in realtime, by that I not having to output it to a text file and reading it afterwards, but by capturing the output of each Write command into a variable and displaying it in the GUI immediately.

If each Write or Writeln could trigger an event, I could use the event to capture the output. My other option is to replace the calls to write with my own function, but Write has different number of call parameters and it may require as many variants of the function as are used in the program, assuming that the call syntax is regular, not something like this one - write(JSValToDouble(cx,pom^)):1:scale).

Frank Church ======================= http://devblog.brahmancreations.com

Reply by email

Florian Klaempfl
to vfclists .
vfclists . wrote 12 lines
I need to get the output of a program which uses a lot of Write and Writeln commands into the GUI in realtime, by that I not having to output it to a text file and reading it afterwards, but by capturing the output of each Write command into a variable and displaying it in the GUI immediately. If each Write or Writeln could trigger an event, I could use the event to capture the output. My other option is to replace the calls to write with my own function, but Write has different number of call parameters and it may require as many variants of the function as are used in the program, assuming that the call syntax is regular, not something like this one - write(JSValToDouble(cx,pom^)):1:scale).

Check the implementation of the FPC CRT unit how a unit can hook into the write(ln) mechanisms:

http://svn.freepascal.org/cgi-bin/viewvc.cgi/trunk/packages/rtl-console/src/unix/crt.pp?revision=26372&view=markup

Have a look at AssignCrt and CrtOpen, how it is done.

Reply by email

Sven Barth
to vfclists .: snip I need to get the output of a program which uses a lot of Write and Writeln commands…
vfclists . wrote 80 lines
On 20 March 2015 at 20:54, Sven Barth < > wrote: On 20.03.2015 21:18, vfclists . wrote: On 20 March 2015 at 19:34, Sven Barth < < >> wrote: Am 20.03.2015 19:19 schrieb "vfclists ." < < >>: snip How do you ensure own implementation overrides the system's implementation, does the compiler take care of that automatically, or will you have to name your function differently? There is no need to ensure that. Here is an example: === code begin === var f, oldout: TextFile; begin Writeln('Hello Output as StdOut'); oldout := Output; Assign(Output, 'test.txt'); Rewrite(Output); Writeln('Hello Output as file'); Close(f); Output := oldout; Writeln('Hello Output as StdOut again'); end. === code end === To see how such a TextFile is implemented you can take a look at unit StreamIO which is part of FPC's units. (Though I wonder why "Assign(f, 'test.txt'); Output := f; Writeln('Hello Output as file');" does not work :/ ) Regards, Sven _________________________________________________ fpc-pascal maillist - http://lists.freepascal.org/__cgi-bin/mailman/listinfo/fpc-__pascal <http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal> I need to get the output of a program which uses a lot of Write and Writeln commands into the GUI in realtime, by that I not having to output it to a text file and reading it afterwards, but by capturing the output of each Write command into a variable and displaying it in the GUI immediately. If each Write or Writeln could trigger an event, I could use the event to capture the output. My other option is to replace the calls to write with my own function, but Write has different number of call parameters and it may require as many variants of the function as are used in the program, assuming that the call syntax is regular, not something like this one - write(JSValToDouble(cx,pom^)):1:scale).

The usage of a text file was merely an example. As I said there already is the possibility to use a TStream provided by FPC. But since I'm nice here you also have an example for a TMemo, I'm sure you can adjust that for your needs:

=== code begin ===

resourcestring
   SErrNilMemo = 'Memo is nil';
type
   PMemo = ^TMemo;
function GetMemo(var F: TTextRec): TMemo;
begin
   Result:=PMemo(@F.Userdata)^;
end;
function MemoWrite(var F: TTextRec): LongInt;
var
   s: String;
begin
   Result := 0;
   with F do
     if BufPos > 0 then
       try
         SetLength(s, BufPos);
         Move(BufPtr^, s[1], BufPos);
         GetMemo(F).SelText := s;
         BufPos:=0;
       except
         Result:=101;
       end;
end;
function MemoClose(var F: TTextRec): LongInt;
begin
   Result := 0;
end;
function MemoOpen(var F: TTextRec): LongInt;
begin
   Result := 0;
   with F do begin
     BufPos:=0;
     Bufend:=0;
     case Mode of
       fmInput: begin
         Result := 104;
       end;
       fmOutput, fmAppend: begin
         InOutFunc := @MemoWrite;
         FlushFunc := @MemoWrite;
         if Mode = fmAppend then
           Try
             with GetMemo(F) do begin
               SelStart := Length(Text);
             end;
           except
             Result := 156;
           end;
         end else begin
           GetMemo(F).Clear;
         end;
     end;
     end;
end;
procedure AssignMemo(var F: Text; aMemo: TMemo);
var
   e: EInoutError;
begin
   if not Assigned(aMemo) then begin
     E:=EInOutError.Create(SErrNilMemo);
     E.ErrorCode:=6;
     Raise E;
   end;
   with TTextRec(F) do begin
     OpenFunc := @MemoOpen;
     CloseFunc := @MemoClose;
     case DefaultTextLineBreakStyle Of
       tlbsLF:
         TextRec(f).LineEnd := #10;
       tlbsCRLF:
         TextRec(f).LineEnd := #13#10;
       tlbsCR:
         TextRec(f).LineEnd := #13;
     end;
     PMemo(@UserData)^ := aMemo;
     Mode := fmClosed;
     BufSize := SizeOf(Buffer);
     BufPtr := @Buffer;
     Name[0] := #0;
   end;
end;

=== code end ===

To use it you should use the following code (for example in FormCreate):

=== code begin ===

   fOldOutput := Output; // store the old Output somewhere
   AssignMemo(Output, Memo1);
   Rewrite(Output);

=== code end ===

Then in FormDestroy you cleanup:

=== code begin ===

   CloseFile(Output);
   Output := fOldOutput; // restore old Output

=== code end ===

And to illustrate that it works I've used a TTimer and added the following to its OnTimer event:

=== code begin ===

   Writeln('Hello World ', fIndex);
   Inc(fIndex); // fIndex is a LongInt field of the form

=== code end ===

And with that TMemo gets spammed with 'Hello World N' messages ;)

You could of course also implement it in a way that you assign a event handler to a text file instead of a memo. As I said the Pascal I/O mechanism is very flexible here.

And just in case: by using this mechanism you don't need to adjust any of the Write(Ln)s, the full spectrum of variants of how Write(Ln) can be called is supported.

Regards,
Sven

Reply by email

vfclists .
to Sven Barth
Sven Barth wrote 230 lines
On 21.03.2015 11:13, vfclists . wrote: > > > On 20 March 2015 at 20:54, Sven Barth < > > wrote: > > On 20.03.2015 21:18, vfclists . wrote: > > > > On 20 March 2015 at 19:34, Sven Barth > < > < > >> wrote: > > Am 20.03.2015 19:19 schrieb "vfclists ." > < > < >>: > > > > snip > > How do you ensure own implementation overrides the system's > implementation, does the compiler take care of that > automatically, or > will you have to name your function differently? > > > There is no need to ensure that. Here is an example: > > === code begin === > > var > f, oldout: TextFile; > begin > Writeln('Hello Output as StdOut'); > > oldout := Output; > > Assign(Output, 'test.txt'); > Rewrite(Output); > > Writeln('Hello Output as file'); > > Close(f); > > Output := oldout; > > Writeln('Hello Output as StdOut again'); > end. > > === code end === > > To see how such a TextFile is implemented you can take a look at > unit StreamIO which is part of FPC's units. > > (Though I wonder why "Assign(f, 'test.txt'); Output := f; > Writeln('Hello Output as file');" does not work :/ ) > > Regards, > Sven > > _________________________________________________ > fpc-pascal maillist - > > http://lists.freepascal.org/__cgi-bin/mailman/listinfo/fpc-__pascal > <http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal> > > > I need to get the output of a program which uses a lot of Write and > Writeln commands into the GUI in realtime, by that I not having to > output it to a text file and reading it afterwards, but by capturing the > output of each Write command into a variable and displaying it in the > GUI immediately. > > If each Write or Writeln could trigger an event, I could use the event > to capture the output. My other option is to replace the calls to write > with my own function, but Write has different number of call parameters > and it may require as many variants of the function as are used in the > program, assuming that the call syntax is regular, not something like > this one - write(JSValToDouble(cx,pom^)):1:scale). > The usage of a text file was merely an example. As I said there already is the possibility to use a TStream provided by FPC. But since I'm nice here you also have an example for a TMemo, I'm sure you can adjust that for your needs: === code begin === resourcestring SErrNilMemo = 'Memo is nil'; type PMemo = ^TMemo; function GetMemo(var F: TTextRec): TMemo; begin Result:=PMemo(@F.Userdata)^; end; function MemoWrite(var F: TTextRec): LongInt; var s: String; begin Result := 0; with F do if BufPos > 0 then try SetLength(s, BufPos); Move(BufPtr^, s[1], BufPos); GetMemo(F).SelText := s; BufPos:=0; except Result:=101; end; end; function MemoClose(var F: TTextRec): LongInt; begin Result := 0; end; function MemoOpen(var F: TTextRec): LongInt; begin Result := 0; with F do begin BufPos:=0; Bufend:=0; case Mode of fmInput: begin Result := 104; end; fmOutput, fmAppend: begin InOutFunc := @MemoWrite; FlushFunc := @MemoWrite; if Mode = fmAppend then Try with GetMemo(F) do begin SelStart := Length(Text); end; except Result := 156; end; end else begin GetMemo(F).Clear; end; end; end; end; procedure AssignMemo(var F: Text; aMemo: TMemo); var e: EInoutError; begin if not Assigned(aMemo) then begin E:=EInOutError.Create(SErrNilMemo); E.ErrorCode:=6; Raise E; end; with TTextRec(F) do begin OpenFunc := @MemoOpen; CloseFunc := @MemoClose; case DefaultTextLineBreakStyle Of tlbsLF: TextRec(f).LineEnd := #10; tlbsCRLF: TextRec(f).LineEnd := #13#10; tlbsCR: TextRec(f).LineEnd := #13; end; PMemo(@UserData)^ := aMemo; Mode := fmClosed; BufSize := SizeOf(Buffer); BufPtr := @Buffer; Name[0] := #0; end; end; === code end === To use it you should use the following code (for example in FormCreate): === code begin === fOldOutput := Output; // store the old Output somewhere AssignMemo(Output, Memo1); Rewrite(Output); === code end === Then in FormDestroy you cleanup: === code begin === CloseFile(Output); Output := fOldOutput; // restore old Output === code end === And to illustrate that it works I've used a TTimer and added the following to its OnTimer event: === code begin === Writeln('Hello World ', fIndex); Inc(fIndex); // fIndex is a LongInt field of the form === code end === And with that TMemo gets spammed with 'Hello World N' messages ;) You could of course also implement it in a way that you assign a event handler to a text file instead of a memo. As I said the Pascal I/O mechanism is very flexible here. And just in case: by using this mechanism you don't need to adjust any of the Write(Ln)s, the full spectrum of variants of how Write(Ln) can be called is supported. Regards, Sven _______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Much obliged.

Is the Text object the Write is using global for the whole program or thread, ie all Writes will go to that Text object until it is reverted back to the default?

In case of wanting to use different Text objects is it possible to prefix the Write command with the Text e.g Write(TextObject, 'outputtext')? Do Write and WriteLn support something like that?

Frank Church ======================= http://devblog.brahmancreations.com

Reply by email

Sven Barth
to vfclists .: Much obliged. Is the Text object the Write is using global for the whole program or…
vfclists . wrote
Is the Text object the Write is using global for the whole program or thread, ie all Writes will go to that Text object until it is reverted back to the default?

The variables Output, Input and StdErr are thread local so you need to set them up for each thread.

In case of wanting to use different Text objects is it possible to prefix the Write command with the Text e.g Write(TextObject, 'outputtext')? Do Write and WriteLn support something like that?

As I already wrote Write('outputtext') is essentially the same as Write(Output, 'outputtext') so you can of course write Write(SomeOtherFile, 'outputtext')

Regards,
Sven

Reply by email