-- CharIOImpl.Mesa -- last edited by Russ Atkinson on 29-Oct-80 10:23:47 -- last edited by Satterthwaite on May 21, 1982 12:46 pm DIRECTORY CharIO: TYPE USING [CR, Handle, NumberFormat, SP], Stream: TYPE USING [GetChar, PutChar], Strings: TYPE USING [AppendChar, String, SubString]; CharIOImpl: PROGRAM IMPORTS Strings, Stream EXPORTS CharIO = { OPEN CharIO, Strings; -- String i/o GetChar: PUBLIC PROC [in: Handle] RETURNS [CHAR] = { RETURN [in.GetChar]}; GetString: PUBLIC PROC [ in: Handle, s: String, test: PROC [CHAR] RETURNS [BOOL]] = { DO c: CHAR ← 0C; c ← in.GetChar[ ! ANY => EXIT]; IF test[c] THEN EXIT; AppendChar[s, c]; ENDLOOP}; PutChar: PUBLIC PROC [out: Handle, c: CHAR] = {out.PutChar[c]}; PutString: PUBLIC PROC [out: Handle, s: String] = { IF s # NIL THEN FOR i: CARDINAL IN [0..s.length) DO out.PutChar[s[i]] ENDLOOP}; PutLine: PUBLIC PROC [out: Handle, s: Strings.String] = { PutString[out, s]; PutChar[out, CR]}; PutSubString: PUBLIC PROC [out: Handle, ss: SubString] = { s: String = ss.base; IF s # NIL THEN FOR i: CARDINAL IN [ss.offset..ss.offset + ss.length) DO out.PutChar[s[i]] ENDLOOP}; GetLine: PUBLIC PROC [in: Handle, s: String] = { GetString[in, s, IsCR]}; IsCR: PROC [c: CHAR] RETURNS [BOOL] = {RETURN [c = CR]}; GetId: PUBLIC PROC [in: Handle, s: String] = { c: CHAR ← SP; DO c ← GetChar[in ! ANY => EXIT]; IF c # SP THEN EXIT; ENDLOOP; DO IF c = SP OR c = CR THEN EXIT; AppendChar[s, c]; c ← GetChar[in ! ANY => EXIT]; ENDLOOP}; -- Numerical i/o GetNumber: PUBLIC PROC [in: Handle, radix: CARDINAL] RETURNS [UNSPECIFIED] = { number: CARDINAL ← 0; negative: BOOL ← FALSE; s: STRING = [10]; pos, len: CARDINAL ← 0; GetId[in, s]; len ← s.length; IF len > 0 THEN SELECT s[len-1] FROM 'b, 'B => {radix ← 8; len ← len-1}; 'd, 'D => {radix ← 10; len ← len-1}; ENDCASE; IF pos < len AND s[pos] = '- THEN {pos ← pos + 1; negative ← TRUE}; FOR pos IN [pos..len) DO number ← number*radix + (s[pos] - '0); ENDLOOP; IF negative THEN number ← -number; RETURN [number]}; PutNumber: PUBLIC PROC [out: Handle, val: INTEGER, format: NumberFormat] = { i: CARDINAL ← 0; neg: BOOL ← FALSE; fill: CHAR = (IF format.zerofill THEN '0 ELSE ' ); s: STRING = [17]; card: CARDINAL ← val; radix: CARDINAL = format.base; IF radix < 2 OR radix > 36 THEN ERROR; IF val < 0 AND ~format.unsigned THEN {card ← -card; neg ← TRUE}; DO digit: CARDINAL = card MOD radix; s[i] ← IF digit >= 10 THEN 'A + (digit-10) ELSE '0 + digit; i ← i + 1; IF (card ← card/radix) = 0 THEN EXIT; ENDLOOP; s.length ← i; IF neg THEN { i ← i + 1; IF format.zerofill THEN {PutChar[out, '-]; neg ← FALSE}}; THROUGH (i..format.columns] DO PutChar[out, fill] ENDLOOP; IF neg THEN PutChar[out, '-]; i ← s.length; WHILE i > 0 DO PutChar[out, s[i ← i-1]] ENDLOOP}; PutDecimal: PUBLIC PROC [out: Handle, n: INTEGER] = { PutNumber[out, n, NumberFormat[10, FALSE, FALSE, 0]]}; PutOctal: PUBLIC PROC [out: Handle, n: UNSPECIFIED] = { PutNumber[out, n, NumberFormat[8, FALSE, TRUE, 0]]; IF CARDINAL[n] > 7 THEN PutChar[out, 'b]}; }.