-- File Output.mesa -- Last edited by Sandman on July 8, 1980 8:38 AM -- Last edited by Sweet on September 19, 1980 4:01 PM -- Last edited by Lewis on 9-Dec-80 10:18:06 -- Last edited by Satterthwaite on August 13, 1982 2:28 pm DIRECTORY Ascii USING [CR, TAB, SP], Format USING [NumberFormat], LongString USING [SubString], OutputDefs USING [], Segments USING [DefaultVersion, NewFile, Write], Streams USING [CreateStream, Destroy, Handle, PutChar], String USING [AppendNumber, AppendString, SubString, SubStringDescriptor], Time USING [Append, Packed, Unpack]; Output: PROGRAM IMPORTS Segments, Streams, String, Time EXPORTS OutputDefs = BEGIN outStream: PUBLIC Streams.Handle ← NIL; GetOutputStream: PUBLIC PROC RETURNS [Streams.Handle] = {RETURN[outStream]}; -- calling this start traps the module where -- simply reading outStream does not PutTab: PUBLIC PROC = {PutChar[Ascii.TAB]}; PutCR: PUBLIC PROC = {PutChar[Ascii.CR]}; PutChar: PUBLIC PROC [c: CHARACTER] = {Streams.PutChar[outStream, c]}; PutString: PUBLIC PROC [s: STRING] = {FOR i: CARDINAL IN [0..s.length) DO Streams.PutChar[outStream, s[i]]; ENDLOOP}; PutLongString: PUBLIC PROC [s: LONG STRING] = {FOR i: CARDINAL IN [0..s.length) DO Streams.PutChar[outStream, s[i]]; ENDLOOP}; PutSubString: PUBLIC PROC [s: String.SubString] = BEGIN FOR i: CARDINAL IN [s.offset..s.offset + s.length) DO Streams.PutChar[outStream, s.base[i]]; ENDLOOP; END; PutLongSubString: PUBLIC PROC [s: LongString.SubString] = BEGIN FOR i: CARDINAL IN [s.offset..s.offset + s.length) DO Streams.PutChar[outStream, s.base[i]]; ENDLOOP; END; PutTime: PUBLIC PROC [t: Time.Packed] = BEGIN s: STRING ← [20]; Time.Append[s, Time.Unpack[t]]; IF s[0] = Ascii.SP THEN BEGIN desc: String.SubStringDescriptor ← [base: s, offset: 1, length: (s.length - 1)]; PutSubString[@desc]; END ELSE PutString[s]; END; PutNumber: PUBLIC PROC [val: CARDINAL, format: Format.NumberFormat] = BEGIN i: CARDINAL; neg: BOOLEAN ← FALSE; fill: CHARACTER ← (IF format.zerofill THEN '0 ELSE ' ); s: STRING ← [10]; IF INTEGER[val] < 0 AND ~format.unsigned THEN {val ← -INTEGER[val]; neg ← TRUE}; String.AppendNumber[s, val, format.base]; i ← s.length; IF neg THEN BEGIN i ← i + 1; IF format.zerofill THEN {Streams.PutChar[outStream, '-]; neg ← FALSE}; END; THROUGH (i..format.columns] DO Streams.PutChar[outStream, fill] ENDLOOP; IF neg THEN Streams.PutChar[outStream, '-]; PutString[s]; END; PutDecimal: PUBLIC PROC [val: CARDINAL] = {PutNumber[val, [10, FALSE, FALSE, 1]]}; PutOctal: PUBLIC PROC [val: UNSPECIFIED] = BEGIN PutNumber[val, [8, FALSE, TRUE, 1]]; IF val NOT IN [0..7] THEN Streams.PutChar[outStream, 'B]; END; OpenOutput: PUBLIC PROC [root: STRING, ext: STRING] = BEGIN name: STRING ← [40]; String.AppendString[name, root]; FOR i: CARDINAL IN [0..name.length) DO IF name[i] = '. THEN {name.length ← i; EXIT}; ENDLOOP; String.AppendString[name, ext]; outStream ← Streams.CreateStream[ file: Segments.NewFile[ name: name, access: Segments.Write, version: Segments.DefaultVersion], access: Segments.Write]; END; CloseOutput: PUBLIC PROC = {Streams.Destroy[outStream]; outStream ← NIL}; END.