123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371 |
- (*
- (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
- See the copyright notice in the ACK home directory, in the file "Copyright".
- *)
- (*$R-*)
- IMPLEMENTATION MODULE InOut ;
- (*
- Module: Wirth's Input/Output module
- Author: Ceriel J.H. Jacobs
- Version: $Id$
- *)
- IMPORT Streams;
- FROM Conversions IMPORT
- ConvertCardinal, ConvertInteger,
- ConvertOctal, ConvertHex;
- FROM Traps IMPORT Message;
- CONST TAB = 11C;
- TYPE numbuf = ARRAY[0..255] OF CHAR;
- VAR unread: BOOLEAN;
- unreadch: CHAR;
- CurrIn, CurrOut: Streams.Stream;
- result: Streams.StreamResult;
- PROCEDURE Read(VAR c : CHAR);
- BEGIN
- IF unread THEN
- unread := FALSE;
- c := unreadch;
- Done := TRUE;
- ELSE
- Streams.Read(CurrIn, c, result);
- Done := result = Streams.succeeded;
- END;
- END Read;
- PROCEDURE UnRead(ch: CHAR);
- BEGIN
- unread := TRUE;
- unreadch := ch;
- END UnRead;
- PROCEDURE Write(c: CHAR);
- BEGIN
- Streams.Write(CurrOut, c, result);
- END Write;
- PROCEDURE OpenInput(defext: ARRAY OF CHAR);
- VAR namebuf : ARRAY [1..128] OF CHAR;
- BEGIN
- IF CurrIn # Streams.InputStream THEN
- Streams.CloseStream(CurrIn, result);
- END;
- MakeFileName("Name of input file: ", defext, namebuf);
- IF NOT Done THEN RETURN; END;
- openinput(namebuf);
- END OpenInput;
- PROCEDURE OpenInputFile(filename: ARRAY OF CHAR);
- BEGIN
- IF CurrIn # Streams.InputStream THEN
- Streams.CloseStream(CurrIn, result);
- END;
- openinput(filename);
- END OpenInputFile;
- PROCEDURE openinput(namebuf: ARRAY OF CHAR);
- BEGIN
- IF (namebuf[0] = '-') AND (namebuf[1] = 0C) THEN
- CurrIn := Streams.InputStream;
- Done := TRUE;
- ELSE
- Streams.OpenStream(CurrIn, namebuf, Streams.text,
- Streams.reading, result);
- Done := result = Streams.succeeded;
- END;
- END openinput;
- PROCEDURE CloseInput;
- BEGIN
- IF CurrIn # Streams.InputStream THEN
- Streams.CloseStream(CurrIn, result);
- END;
- CurrIn := Streams.InputStream;
- END CloseInput;
- PROCEDURE OpenOutput(defext: ARRAY OF CHAR);
- VAR namebuf : ARRAY [1..128] OF CHAR;
- BEGIN
- IF CurrOut # Streams.OutputStream THEN
- Streams.CloseStream(CurrOut, result);
- END;
- MakeFileName("Name of output file: ", defext, namebuf);
- IF NOT Done THEN RETURN; END;
- openoutput(namebuf);
- END OpenOutput;
- PROCEDURE OpenOutputFile(filename: ARRAY OF CHAR);
- BEGIN
- IF CurrOut # Streams.OutputStream THEN
- Streams.CloseStream(CurrOut, result);
- END;
- openoutput(filename);
- END OpenOutputFile;
- PROCEDURE openoutput(namebuf: ARRAY OF CHAR);
- BEGIN
- IF (namebuf[1] = '-') AND (namebuf[2] = 0C) THEN
- CurrOut := Streams.OutputStream;
- Done := TRUE;
- ELSE
- Streams.OpenStream(CurrOut, namebuf, Streams.text,
- Streams.writing, result);
- Done := result = Streams.succeeded;
- END;
- END openoutput;
- PROCEDURE CloseOutput;
- BEGIN
- IF CurrOut # Streams.OutputStream THEN
- Streams.CloseStream(CurrOut, result);
- END;
- CurrOut := Streams.OutputStream;
- END CloseOutput;
- PROCEDURE MakeFileName(prompt, defext : ARRAY OF CHAR;
- VAR buf : ARRAY OF CHAR);
- VAR i : INTEGER;
- j : CARDINAL;
- BEGIN
- Done := TRUE;
- IF Streams.isatty(Streams.InputStream, result) THEN
- XWriteString(prompt);
- END;
- XReadString(buf);
- i := 0;
- WHILE buf[i] # 0C DO i := i + 1 END;
- IF i # 0 THEN
- i := i - 1;
- IF buf[i] = '.' THEN
- FOR j := 0 TO HIGH(defext) DO
- i := i + 1;
- buf[i] := defext[j];
- END;
- buf[i+1] := 0C;
- END;
- RETURN;
- END;
- Done := FALSE;
- END MakeFileName;
- PROCEDURE ReadInt(VAR integ : INTEGER);
- CONST
- SAFELIMITDIV10 = MAX(INTEGER) DIV 10;
- SAFELIMITREM10 = MAX(INTEGER) MOD 10;
- TYPE
- itype = [0..31];
- ibuf = ARRAY itype OF CHAR;
- VAR
- int : INTEGER;
- neg : BOOLEAN;
- safedigit: [0 .. 9];
- chvalue: CARDINAL;
- buf : ibuf;
- index : itype;
- BEGIN
- ReadString(buf);
- IF NOT Done THEN
- RETURN
- END;
- index := 0;
- IF buf[index] = '-' THEN
- neg := TRUE;
- INC(index);
- ELSIF buf[index] = '+' THEN
- neg := FALSE;
- INC(index);
- ELSE
- neg := FALSE
- END;
- safedigit := SAFELIMITREM10;
- IF neg THEN safedigit := safedigit + 1 END;
- int := 0;
- WHILE (buf[index] >= '0') & (buf[index] <= '9') DO
- chvalue := ORD(buf[index]) - ORD('0');
- IF (int > SAFELIMITDIV10) OR
- ( (int = SAFELIMITDIV10) AND
- (chvalue > safedigit)) THEN
- Message("integer too large");
- HALT;
- ELSE
- int := 10*int + VAL(INTEGER, chvalue);
- INC(index)
- END;
- END;
- IF neg THEN
- integ := -int
- ELSE
- integ := int
- END;
- IF buf[index] > " " THEN
- Message("illegal integer");
- HALT;
- END;
- Done := TRUE;
- END ReadInt;
- PROCEDURE ReadCard(VAR card : CARDINAL);
- CONST
- SAFELIMITDIV10 = MAX(CARDINAL) DIV 10;
- SAFELIMITREM10 = MAX(CARDINAL) MOD 10;
- TYPE
- itype = [0..31];
- ibuf = ARRAY itype OF CHAR;
-
- VAR
- int : CARDINAL;
- index : itype;
- buf : ibuf;
- safedigit: [0 .. 9];
- chvalue: CARDINAL;
- BEGIN
- ReadString(buf);
- IF NOT Done THEN RETURN; END;
- index := 0;
- safedigit := SAFELIMITREM10;
- int := 0;
- WHILE (buf[index] >= '0') & (buf[index] <= '9') DO
- chvalue := ORD(buf[index]) - ORD('0');
- IF (int > SAFELIMITDIV10) OR
- ( (int = SAFELIMITDIV10) AND
- (chvalue > safedigit)) THEN
- Message("cardinal too large");
- HALT;
- ELSE
- int := 10*int + chvalue;
- INC(index);
- END;
- END;
- IF buf[index] > " " THEN
- Message("illegal cardinal");
- HALT;
- END;
- card := int;
- Done := TRUE;
- END ReadCard;
- PROCEDURE ReadString(VAR s : ARRAY OF CHAR);
- TYPE charset = SET OF CHAR;
- VAR i : CARDINAL;
- ch : CHAR;
- BEGIN
- i := 0;
- REPEAT
- Read(ch);
- UNTIL NOT (ch IN charset{' ', TAB, 12C, 15C});
- IF NOT Done THEN
- RETURN;
- END;
- UnRead(ch);
- REPEAT
- Read(ch);
- termCH := ch;
- IF i <= HIGH(s) THEN
- s[i] := ch;
- IF (NOT Done) OR (ch <= " ") THEN
- s[i] := 0C;
- END;
- END;
- INC(i);
- UNTIL (NOT Done) OR (ch <= " ");
- IF Done THEN UnRead(ch); END;
- END ReadString;
- PROCEDURE XReadString(VAR s : ARRAY OF CHAR);
- VAR j : CARDINAL;
- ch : CHAR;
- BEGIN
- j := 0;
- LOOP
- Streams.Read(Streams.InputStream, ch, result);
- IF result # Streams.succeeded THEN
- EXIT;
- END;
- IF ch <= " " THEN
- s[j] := 0C;
- EXIT;
- END;
- IF j < HIGH(s) THEN
- s[j] := ch;
- INC(j);
- END;
- END;
- END XReadString;
- PROCEDURE XWriteString(s: ARRAY OF CHAR);
- VAR i: CARDINAL;
- BEGIN
- i := 0;
- LOOP
- IF (i <= HIGH(s)) AND (s[i] # 0C) THEN
- Streams.Write(Streams.OutputStream, s[i], result);
- INC(i);
- ELSE
- EXIT;
- END;
- END;
- END XWriteString;
- PROCEDURE WriteCard(card, width : CARDINAL);
- VAR
- buf : numbuf;
- BEGIN
- ConvertCardinal(card, width, buf);
- WriteString(buf);
- END WriteCard;
- PROCEDURE WriteInt(int : INTEGER; width : CARDINAL);
- VAR
- buf : numbuf;
- BEGIN
- ConvertInteger(int, width, buf);
- WriteString(buf);
- END WriteInt;
- PROCEDURE WriteHex(card, width : CARDINAL);
- VAR
- buf : numbuf;
- BEGIN
- ConvertHex(card, width, buf);
- WriteString(buf);
- END WriteHex;
- PROCEDURE WriteLn;
- BEGIN
- Write(EOL)
- END WriteLn;
- PROCEDURE WriteOct(card, width : CARDINAL);
- VAR
- buf : numbuf;
- BEGIN
- ConvertOctal(card, width, buf);
- WriteString(buf);
- END WriteOct;
- PROCEDURE WriteString(str : ARRAY OF CHAR);
- VAR
- nbytes : CARDINAL;
- BEGIN
- nbytes := 0;
- WHILE (nbytes <= HIGH(str)) AND (str[nbytes] # 0C) DO
- Write(str[nbytes]);
- INC(nbytes)
- END;
- END WriteString;
- BEGIN (* InOut initialization *)
- CurrIn := Streams.InputStream;
- CurrOut := Streams.OutputStream;
- unread := FALSE;
- END InOut.
|