Hi
downloaded gcc-3.3.4 today. building gcc-20040516 with Waldek's Make-lang.in patch,
configure --enable-languages=c,c++,pascal
test results:
Unsupported: regextest.pas # of tests 3910 # of expected passes 3909 # of unsupported tests 1
gpc version 20040516, based on gcc-3.3.4
Good. Thanks, Russ
Advice sought on terminal input to a gpc program:
I'm trying to read character at a time from the terminal, to allow my program to respond to each keystroke when typed. Also, I don't want to hang waiting for input if nothing has been typed.
Thus I'm using IOSelectRead with a timeout. (excessive timeout, below, just for testing.) My test program below works, but keyboard typing is line buffered, that is, it doesn't know the user has typed anything (returns with SelectValue=1) unless a Return has been typed.
---------------------- program ios (input,output); import GPC; var SelectValue: Integer; microsec: Integer; SelectInput: array [1 .. 1] of PAnyFile = (@Input); begin SelectValue := IOSelectRead (SelectInput, 2000000); writeln('selectvalue=', SelectValue:5); end. ----------------------
I don't want to use the CRT unit, because that disturbs terminal's processing of escape sequences, e.g. for VT102 ANSI sequences. (Incidentally, I'm running on Macintosh OSX, using terminal. But this question should be generic GPC/Unix.)
How do I get 'input' to not line buffer? Or do I use another file? Or change the handle?
Thanks,
Willett Kempton Visible Software
willett wrote:
Advice sought on terminal input to a gpc program:
I'm trying to read character at a time from the terminal, to allow my program to respond to each keystroke when typed. Also, I don't want to hang waiting for input if nothing has been typed.
Thus I'm using IOSelectRead with a timeout. (excessive timeout, below, just for testing.) My test program below works, but keyboard typing is line buffered, that is, it doesn't know the user has typed anything (returns with SelectValue=1) unless a Return has been typed.
I don't want to use the CRT unit, because that disturbs terminal's processing of escape sequences, e.g. for VT102 ANSI sequences.
Not really disturbs. It interprets them and returns key codes for them (on input) or converts screen drawing to the sequences (on output).
(Incidentally, I'm running on Macintosh OSX, using terminal.
Are you sure your program will always run on this terminal? Not perhaps sometime on another machine, or just another terminal via ssh or so? Then CRT's (actually ncurses's) escape sequence interpretation may be beneficial.
But this question should be generic GPC/Unix.)
Generic Unix. Terminals by default do line buffering themselves (this is useful, so if the user types abd<backspace>c<enter>, a program that just does `ReadLn' etc. gets `abc' as expected).
If you really don't want to use CRT, you might have to do it yourself (probably in C, using a Pascal interface), see termios.
As for not waiting, IOSelectRead is correct.
Frank
The test program below (kempbug1.pas) shows how one can import CRT to use the keystroke processing not available in Standard Pascal (e.g. function Keypressed and ReadKeyWord), yet re-assign 'output' so that it bypasses CRT and continues to use standard output. (Thanks to Frank for this suggestion.)
Thus, you can use CRT for input, while using escape sequences on standard output. This is useful only in particular circumstances, for example, if you require terminal-specific escape sequences not supported by ncurses and you are willing to either limit your program to those terminals or have your program detect terminal type and make adjustments before calling ncurses/CRT.
This was tested on Mac OSX, using the standard OSX terminal emulator (which implements most of a vt102).
Willett Kempton wrote:
What I meant by 'disturbs' is that if I IMPORT CRT, then try to write a direct screen-control escape sequence, it doesn't work. ... the esc gets changed to "<". What am I missing?
Frank Heckenbach wrote:
CRT redirects `Output'. You can, however, assign a `Text' variable (including `Output' if you like) to '' (empty string) or '-', meaning standard output directly, and write to it.
But it still won't play well with curses since curses then has a wrong idea of the cursor position, and when it next updates the screen, it will overwrite your characters.
You could try doing input via CRT and all output directly, but I'm not sure if this works well (never needed to).
Yes it works! In the process I discovered two problems, tentatively labelled bugs:
bug 1: The "assign/rewrite" of the predeclared file output works alright if followed by the GPC-imported call "sleep" (or possibly other calls) but without it, no subsequent output appears on standard output (or at least not on the screen). A call to CRTInit rather than sleep does NOT fix the problem. Using another non-predeclared text file variable rather than output does not fix the problem.
bug 2: After the assign/rewrite, the predeclared procedure writeln does just a LF, not a CR. To get normal output, one has to manually write the CR, e.g. write(chr(13)). I understand that this is happening because output is being treated as a text file, but either 'rewrite' should be smarter about recognizing standard output, or there should be some optional field of BindingType so the programmer can tell writeln to keep using.
I'm not capable of developing a patch to the runtimes, but I would be glad to volunteer to write or edit documentation, given some guidance as to what would be helpful.
Willett Kempton Visible Software
------------------------------------------------------------------------ -------------------------------------------
program kempbug1(input,output); { This program shows how to use standard output for "write", and do escape sequences } { directly, even those not in ncurses, while using the CRT package for input. } { Two problems are illustrated in this test program: see BUG1 and BUG2 in main prog. }
import GPC only (sleep,SleepMicroSeconds); CRT; { import direct keyboard input, but redirect output so it's not affected }
type attributes = ( none, bold, x2,x3, underscore, ansiblink, x6, reverse); (* the ordinal values of the above are the ANSI screen codes. *) attset = set of attributes;
procedure writelncon; { send LF CR to output, a workaround for bug } begin write(chr(10),chr(13)); end;
procedure SetAttributes( att : attset); (* set ANSI attributes for subsequent write *) const esc = 27; var a: attributes; begin for a:= none to reverse do if a in att then write(output,chr(esc),'[',ord(a):1,'m'); end;
procedure big; (* vt102-specific escape codes: write in big letters. *) (* code is: esc, poundsign, 3 for top; esc, poundsign, 4 for bottom *) var i: 3..4; begin for i:= 3 to 4 do begin write(chr(27),chr(35), i:1,'Big letters'); writelncon { bug workaround } end; end;
procedure ansiline; { a line testing ANSI attributes } begin write('normal'); setattributes([bold]); write('bold'); setattributes([none,underscore]); write('underscore'); setattributes([ none]); write('normal'); end;
begin (* kempbug1 *) writeln(output, 'writeln to output, with CRT package'); ansiline; { ANSI escape sequences do NOT work with output via CRT } writeln; writeln('preparing to assign(output,'''');'); rewrite(output,''); (* eliminate GPC redirection of 'output' *) sleep(1); { BUG 1: if this sleep is not done, subsequent output is not visible! } writeln( 'writeln to output after assign(output'''')'); writeln('another writeln, should begin at left margin'); { BUG 2: only LF, no CR from writeln } writelncon; ansiline; writelncon; write('next try vt102 big letters (just a double-line on non-vt terminals)'); writelncon; big; { escape sequences work correctly even though not in ncurses } end (* kempbug1 *).
Hi,
On Sat, Jul 17, 2004 at 11:02:39PM -0400, willett wrote:
bug 2: After the assign/rewrite, the predeclared procedure writeln does just a LF, not a CR. To get normal output, one has to manually write the CR, e.g. write(chr(13)). I understand that this is happening because output is being treated as a text file, but either 'rewrite' should be smarter about recognizing standard output, or there should be some optional field of BindingType so the programmer can tell writeln to keep using.
This might be due to confused stdout tty settings. Normally, it's not the job of the application to add the CR, but the system's terminal driver will do it (if the OPOST ONLCR flags are set, see "stty -a").
As the tty settings apply to input and output (same tty), chances are good that setting the input to "RAW" is also messing with the output settings.
I don't understand the GPC environment well enough to offer a workaround, so this is only meant as "background information" to help people diagnose this.
gert
Gert Doering wrote:
This might be due to confused stdout tty settings. Normally, it's not the job of the application to add the CR, but the system's terminal driver will do it (if the OPOST ONLCR flags are set, see "stty -a").
As the tty settings apply to input and output (same tty), chances are good that setting the input to "RAW" is also messing with the output settings.
I don't understand the GPC environment well enough to offer a workaround, so this is only meant as "background information" to help people diagnose this.
Indeed this seems to be the problem. I'm short of time now, and I don't know a quick solution. Maybe you'll have to mess with termios yourself after all. More perhaps in 2-3 weeks, sorry ...
Frank