IMPLEMENTATION MODULE IO ;
FROM StrLib IMPORT StrCopy ;
FROM SYSTEM IMPORT ADR ;
FROM M2RTS IMPORT InstallTerminationProcedure ;
FROM libc IMPORT read, write, system, isatty ;
FROM ASCII IMPORT cr, eof, nl;
CONST
MaxBuffer = 65536 ;
VAR
IsInRawMode: BOOLEAN ;
Eof : BOOLEAN ;
Buffer : ARRAY [0..MaxBuffer] OF CHAR ;
BufferLimit: CARDINAL ;
PROCEDURE Read (VAR ch: CHAR) ;
BEGIN
Flush ;
IF Eof OR (read(0, ADR(ch), 1)#1)
THEN
Eof := TRUE ;
ch := eof
END ;
IF ch=nl
THEN
ch := cr
END
END Read ;
PROCEDURE Write (ch: CHAR) ;
BEGIN
IF (ch#cr) OR IsInRawMode
THEN
Buffer[BufferLimit] := ch ;
INC(BufferLimit) ;
IF (BufferLimit=MaxBuffer) OR (ch=nl)
THEN
Flush
END
END
END Write ;
PROCEDURE Error (ch: CHAR) ;
VAR
res: INTEGER ;
BEGIN
res := write(2, ADR(ch), 1)
END Error ;
PROCEDURE Flush ;
VAR
res: INTEGER ;
BEGIN
IF BufferLimit>0
THEN
res := write(1, ADR(Buffer), INTEGER(BufferLimit)) ;
BufferLimit := 0
END
END Flush ;
PROCEDURE IOInRawMode ;
VAR
Command: ARRAY [0..30] OF CHAR ;
res : INTEGER ;
BEGIN
IF isatty()
THEN
IsInRawMode := TRUE ;
StrCopy("stty raw -echo", Command) ;
res := system(ADR(Command))
END
END IOInRawMode ;
PROCEDURE IOInBufferedMode ;
VAR
Command: ARRAY [0..30] OF CHAR ;
res: INTEGER ;
BEGIN
IF IsInRawMode
THEN
StrCopy("stty sane", Command) ;
res := system(ADR(Command))
END ;
Flush
END IOInBufferedMode ;
BEGIN
IsInRawMode := FALSE ;
BufferLimit := 0 ;
Eof := FALSE ;
InstallTerminationProcedure(IOInBufferedMode)
END IO.