-- CharIOImpl.Mesa -- last edited by Russ Atkinson on 29-Oct-80 10:23:47 -- last edited by Satterthwaite on December 10, 1982 10:29 am 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 _ '\000; 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: 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; UNTIL c = SP OR c = CR DO 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].ORD - '0.ORD); 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] _ VAL[IF digit >= 10 THEN 'A.ORD + (digit-10) ELSE '0.ORD + 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]}; }.