Problems with writing to console

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

Problems with writing to console

Darius Blaszyk
Hi,

I have been mixing "writeln(StdOut" and regular writeln in my application (actually a couple of applications working together) and found that the output on the console is mangled when I do that. Output is being overwritten and placed semi randomly on the console. What is the standard output for writeln? I thought it would be StdOut as the name suggests. Using StdOut at the same time will not allow colors (TextColor) from the crt unit to be shown on the console. On the other hand reading output from the console does require writing to StdOut.

So I guess my question is, How can I use color, and read the output with a TProcess from the console? If I get a solution for that I will not need to mix different output text files.

I'm using Windows and FPC 3.0.4 btw. I have not yet tested Linux nor macOS.

Appreciate any help. TIA!

Rgds, Darius

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Problems with writing to console

Michael Van Canneyt


On Tue, 9 Jan 2018, Darius Blaszyk wrote:

> Hi,
>
> I have been mixing "writeln(StdOut" and regular writeln in my
> application (actually a couple of applications working together) and
> found that the output on the console is mangled when I do that. Output
> is being overwritten and placed semi randomly on the console. What is
> the standard output for writeln? I thought it would be StdOut as the
> name suggests. Using StdOut at the same time will not allow colors
> (TextColor) from the crt unit to be shown on the console. On the other
> hand reading output from the console does require writing to StdOut.

Take care, stdout and output are not the same text file.

if no file is specified, then output is assumed.

The crt unit only redirects output. not stdout.
(See around line 438 of crt.inc)

using crt and output redirection together is not supported.


Michael.
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Problems with writing to console

Zaaphod
I suspect the output when writing to StdOut is moving the cursor to a location that is not known or kept track of by regular writeln in the CRT unit.  If this is what's causing seemingly random positioning,   You could possibly keep track of where the cursor is supposed to be yourself with the CRT functions WhereX32 & WhereY32 then move the cursor to  a fixed position with the CRT function GotoXY32 , perform the Writeln to StdOut, then move the cursor back to the position saved by WhereX32/WhereY32 with another GotoXY32.  You mentioned you have several applications that work together, so maybe you can somehow use these functions to keep things straight in the console window, by possibly parking the cursor in a known position and relaying the position to the other program.

One problem with using WhereX32, WhereY32, and GotoXY32 with windows consoles, is that the console window is not a predetermined shape, it depends on how the user has the system configured. You can get around this two ways:

1. by detecting the existing shape of the console window with GetConsoleScreenBufferInfo()   Now you will know the shape of the console window and stay within it.
2. force the windows console window to be  particular shape with SetConsoleWindowInfo();  and you can also force a particular console screen buffer with SetConsoleScreenBufferSize();   I believe there is also a way to force the font, and font size for windows consoles as well.

I've attached a CRT Demo program that uses the above functions as an example.

It's not clear If you are using StdOut for redirection purposes, however if the output is redirected, none of this will work, because as Michael mentioned, CRT with redirection is not supported.. if you try it, StdOut is all that is redirected and Output is just lost. so then you don't have anything on the screen and none of the positioning will mean anything.   I did notice you can also write stuff to StdErr and it will redirect separately from output with 2> but if you use 2>&1 then you get no screen output.  So if you did want some stuff on the screen and to redirect other stuff, then the stuff you want redirected could be done with stderr and you could also still use positioning functions for normal output.  I attached another sample program that demonstrates this, try to run it with various redirects and it will be clear what is redirected and what isn't  It also shows writing things to stderr then using gotoxy32 to write over it so it won't even show up on the screen. If the program is run without redirection. (set wait4key to false to see this)

James

-----Original Message-----
From: fpc-pascal [mailto:[hidden email]] On Behalf Of Michael Van Canneyt
Sent: Tuesday, January 09, 2018 7:16 PM
To: FPC-Pascal users discussions <[hidden email]>
Subject: Re: [fpc-pascal] Problems with writing to console



On Tue, 9 Jan 2018, Darius Blaszyk wrote:

> Hi,
>
> I have been mixing "writeln(StdOut" and regular writeln in my
> application (actually a couple of applications working together) and
> found that the output on the console is mangled when I do that. Output
> is being overwritten and placed semi randomly on the console. What is
> the standard output for writeln? I thought it would be StdOut as the
> name suggests. Using StdOut at the same time will not allow colors
> (TextColor) from the crt unit to be shown on the console. On the other
> hand reading output from the console does require writing to StdOut.
Take care, stdout and output are not the same text file.

if no file is specified, then output is assumed.

The crt unit only redirects output. not stdout.
(See around line 438 of crt.inc)

using crt and output redirection together is not supported.


Michael.
_______________________________________________
fpc-pascal maillist  -  [hidden email] http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Console_Size_Detect_Demo.pas (4K) Download Attachment
test.pas (981 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Problems with writing to console

Zaaphod
If all you want is colors and simple positioning,  you could use Ansi escape codes instead of the CRT unit, then you would not have the issue with redirection and CRT not being supported.  Windows 10 builds after 10586 have re-enabled Ansi escape codes, however after build 14393 it is no longer enabled for executables by default.  It can be enabled with SetConsoleMode();   note that constants related to the windows 10 virtual terminal are not defined in FPC yet.  Here's a FPC example:

Const
ENABLE_VIRTUAL_TERMINAL_PROCESSING =$0004;
Var
dwOriginalOutMode,
dwRequestedOutModes,
dwRequestedInModes,
dwOutMode:Dword;
Begin
GetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE), dwOriginalOutMode);
dwRequestedOutModes := ENABLE_VIRTUAL_TERMINAL_PROCESSING;
dwOutMode := dwOriginalOutMode OR dwRequestedOutModes;
SetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE), dwOutMode);
Writeln('^<ESC^>[30m ',#27,'[30mBlack',#27,'[0m (black)');
Writeln('^<ESC^>[31m ',#27,'[31mRed',#27,'[0m');
Writeln('^<ESC^>[32m ',#27,'[32mGreen',#27,'[0m');
Writeln('^<ESC^>[33m ',#27,'[33mYellow',#27,'[0m');
Writeln('^<ESC^>[34m ',#27,'[34mBlue',#27,'[0m');
Writeln('^<ESC^>[35m ',#27,'[35mMagenta',#27,'[0m');
Writeln('^<ESC^>[36m ',#27,'[36mCyan',#27,'[0m');
Writeln('^<ESC^>[37m ',#27,'[37mWhite',#27,'[0m');
Readln;
End.

See full example attached.    Of course the program is intended to run on versions of random versions of windows, many of which had Ansi capability disabled, then this would not be a potential solution.  Windows 3.11, Windows 95 and Windows 98 had Ansi capability, but Windows 2000, Windows XP, Widnows 7, and Windows 10 before build 10586 did not, then Windows 10 build 10586 had Ansi capability again by default until Build 14393 where it still had Ansi Capability but not turned on by default anymore.

James

-----Original Message-----
From: fpc-pascal [mailto:[hidden email]] On Behalf Of James Richters
Sent: Tuesday, January 09, 2018 10:28 PM
To: 'FPC-Pascal users discussions' <[hidden email]>
Subject: Re: [fpc-pascal] Problems with writing to console

I suspect the output when writing to StdOut is moving the cursor to a location that is not known or kept track of by regular writeln in the CRT unit.  If this is what's causing seemingly random positioning,   You could possibly keep track of where the cursor is supposed to be yourself with the CRT functions WhereX32 & WhereY32 then move the cursor to  a fixed position with the CRT function GotoXY32 , perform the Writeln to StdOut, then move the cursor back to the position saved by WhereX32/WhereY32 with another GotoXY32.  You mentioned you have several applications that work together, so maybe you can somehow use these functions to keep things straight in the console window, by possibly parking the cursor in a known position and relaying the position to the other program.

One problem with using WhereX32, WhereY32, and GotoXY32 with windows consoles, is that the console window is not a predetermined shape, it depends on how the user has the system configured. You can get around this two ways:

1. by detecting the existing shape of the console window with GetConsoleScreenBufferInfo()   Now you will know the shape of the console window and stay within it.
2. force the windows console window to be  particular shape with SetConsoleWindowInfo();  and you can also force a particular console screen buffer with SetConsoleScreenBufferSize();   I believe there is also a way to force the font, and font size for windows consoles as well.

I've attached a CRT Demo program that uses the above functions as an example.

It's not clear If you are using StdOut for redirection purposes, however if the output is redirected, none of this will work, because as Michael mentioned, CRT with redirection is not supported.. if you try it, StdOut is all that is redirected and Output is just lost. so then you don't have anything on the screen and none of the positioning will mean anything.   I did notice you can also write stuff to StdErr and it will redirect separately from output with 2> but if you use 2>&1 then you get no screen output.  So if you did want some stuff on the screen and to redirect other stuff, then the stuff you want redirected could be done with stderr and you could also still use positioning functions for normal output.  I attached another sample program that demonstrates this, try to run it with various redirects and it will be clear what is redirected and what isn't  It also shows writing things to stderr then using gotoxy32 to write over it so it won't even show up on the screen. If the program is run without redirection. (set wait4key to false to see this)

James

-----Original Message-----
From: fpc-pascal [mailto:[hidden email]] On Behalf Of Michael Van Canneyt
Sent: Tuesday, January 09, 2018 7:16 PM
To: FPC-Pascal users discussions <[hidden email]>
Subject: Re: [fpc-pascal] Problems with writing to console



On Tue, 9 Jan 2018, Darius Blaszyk wrote:

> Hi,
>
> I have been mixing "writeln(StdOut" and regular writeln in my
> application (actually a couple of applications working together) and
> found that the output on the console is mangled when I do that. Output
> is being overwritten and placed semi randomly on the console. What is
> the standard output for writeln? I thought it would be StdOut as the
> name suggests. Using StdOut at the same time will not allow colors
> (TextColor) from the crt unit to be shown on the console. On the other
> hand reading output from the console does require writing to StdOut.
Take care, stdout and output are not the same text file.

if no file is specified, then output is assumed.

The crt unit only redirects output. not stdout.
(See around line 438 of crt.inc)

using crt and output redirection together is not supported.


Michael.
_______________________________________________
fpc-pascal maillist  -  [hidden email] http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Windows 10 colors.pas (3K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Problems with writing to console

Zaaphod
> note that constants related to the windows 10 virtual terminal are not defined in FPC yet.
Correction:  They were not added as of 3.0.4.rc1, they have been added now, not sure exactly which version they are/were included.

James

-----Original Message-----
From: fpc-pascal [mailto:[hidden email]] On Behalf Of James Richters
Sent: Wednesday, January 10, 2018 6:14 AM
To: 'FPC-Pascal users discussions' <[hidden email]>
Subject: Re: [fpc-pascal] Problems with writing to console

If all you want is colors and simple positioning,  you could use Ansi escape codes instead of the CRT unit, then you would not have the issue with redirection and CRT not being supported.  Windows 10 builds after 10586 have re-enabled Ansi escape codes, however after build 14393 it is no longer enabled for executables by default.  It can be enabled with SetConsoleMode();   note that constants related to the windows 10 virtual terminal are not defined in FPC yet.  Here's a FPC example:

Const
   ENABLE_VIRTUAL_TERMINAL_PROCESSING =$0004;
Var dwOriginalOutMode, dwRequestedOutModes, dwRequestedInModes, dwOutMode:Dword;
Begin
GetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE), dwOriginalOutMode);
dwRequestedOutModes := ENABLE_VIRTUAL_TERMINAL_PROCESSING;
dwOutMode := dwOriginalOutMode OR dwRequestedOutModes;
SetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE), dwOutMode);
Writeln('^<ESC^>[30m ',#27,'[30mBlack',#27,'[0m (black)');
Writeln('^<ESC^>[31m ',#27,'[31mRed',#27,'[0m');
Writeln('^<ESC^>[32m ',#27,'[32mGreen',#27,'[0m');
Writeln('^<ESC^>[33m ',#27,'[33mYellow',#27,'[0m');
Writeln('^<ESC^>[34m ',#27,'[34mBlue',#27,'[0m');
Writeln('^<ESC^>[35m ',#27,'[35mMagenta',#27,'[0m');
Writeln('^<ESC^>[36m ',#27,'[36mCyan',#27,'[0m');
Writeln('^<ESC^>[37m ',#27,'[37mWhite',#27,'[0m');
Readln;
End.

See full example attached.    Of course the program is intended to run on versions of random versions of windows, many of which had Ansi capability disabled, then this would not be a potential solution.  Windows 3.11, Windows 95 and Windows 98 had Ansi capability, but Windows 2000, Windows XP, Widnows 7, and Windows 10 before build 10586 did not, then Windows 10 build 10586 had Ansi capability again by default until Build 14393 where it still had Ansi Capability but not turned on by default anymore.

James

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal