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: BOOLEANFALSE;
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.