-- File CIFExtNMOS.mesa
-- Written by Dan Fitzpatrick and Martin Newell, June 1980
-- Last updated: August 20, 1980 2:13 PM

DIRECTORY

CIFIODefs: FROM "CIFIODefs",
IODefs: FROM "IODefs" USING [SP, TAB, FF, LF, CR, NUL, WriteString, WriteLine],
SegmentDefs: FROM "SegmentDefs" USING[Write, OldFileOnly, FileNameError, FileError, FileHandle, NewFile, DestroyFile],
StreamDefs: FROM "StreamDefs" USING[StreamHandle],
StringDefs: FROM "StringDefs" USING[AppendLongDecimal, StringToLongNumber, StringToNumber, AppendDecimal],
InlineDefs: FROM "InlineDefs" USING [DIVMOD];

CIFIO: PROGRAM
IMPORTS IODefs, SegmentDefs, StringDefs, InlineDefs
EXPORTS CIFIODefs =

BEGIN OPEN IODefs, SegmentDefs, StreamDefs, StringDefs, StringDefs, InlineDefs;

ReadStringDirect: PUBLIC PROCEDURE [t: STRING, s: StreamHandle] =
BEGIN
i:CARDINAL;
t.length ← 0;
WHILE TRUE DO
SELECT (t.text[0] ← s.get[s]) FROM
SP, TAB, FF, LF, CR, ’, , NUL => BEGIN
IF s.endof[s] THEN RETURN;
LOOP;
END;
ENDCASE => EXIT;
ENDLOOP;
FOR i ← 1,i+1 DO
IF i = t.maxlength THEN BEGIN
t.length ← t.maxlength;
WriteLine["STRING OVERFLOW IN READSTRING (CIFExtIO)"];
WriteLine[t];
EXIT;
END;
SELECT (t.text[i] ← s.get[s]) FROM
SP, TAB, FF, LF, CR, ’,, NUL => BEGIN
EXIT;
END;
ENDCASE => IF s.endof[s] THEN RETURN;
ENDLOOP;
t.length ← i;
END;

ReadLineDirect: PUBLIC PROCEDURE [t: STRING, s: StreamHandle] =
BEGIN
i:CARDINAL;
WHILE TRUE DO
SELECT (t.text[0] ← s.get[s]) FROM
SP, TAB, FF, LF, ’, , NUL => LOOP;
CR => BEGIN
t ← "";
RETURN;
END;
ENDCASE => EXIT;
ENDLOOP;
FOR i ← 1,i+1 DO
IF i = t.maxlength THEN BEGIN
t.length ← t.maxlength;
WriteLine["STRING OVERFLOW IN READSTRING (CIFExtIO)"];
WriteLine[t];
EXIT;
END;
SELECT (t.text[i] ← s.get[s]) FROM
CR => EXIT;
ENDCASE;
ENDLOOP;
t.length ← i;
END;

WriteStringDirect: PUBLIC PROCEDURE [t: STRING, s: StreamHandle] =
BEGIN
i:CARDINAL;
FOR i ← 0,i+1 WHILE i < t.length DO
s.put[s,t.text[i]];
ENDLOOP;
END;

WriteLineDirect: PUBLIC PROCEDURE [t: STRING, s: StreamHandle] =
BEGIN
WriteStringDirect[t,s];
s.put[s,CR];
END;

ReadLong: PUBLIC PROCEDURE [s: StreamHandle] RETURNS [LONG UNSPECIFIED] =
BEGIN
t: STRING ← [50];
ReadStringDirect[t,s];
RETURN[StringToLongNumber[t,10]];
END;

ReadShort: PUBLIC PROCEDURE [s: StreamHandle] RETURNS [UNSPECIFIED] =
BEGIN
t: STRING ← [50];
ReadStringDirect[t,s];
RETURN[StringToNumber[t,10]];
END;

WriteLong: PUBLIC PROCEDURE [n:LONG UNSPECIFIED, s: StreamHandle] =
BEGIN
t: STRING ← [50];
AppendLongDecimal[t,n];
WriteStringDirect[t,s];
END;

WriteShort: PUBLIC PROCEDURE [n:UNSPECIFIED, s: StreamHandle] =
BEGIN
t: STRING ← [50];
AppendDecimal[t,n];
WriteStringDirect[t,s];
END;

PutShort: PUBLIC PROCEDURE [i: UNSPECIFIED, s: StreamHandle] =
BEGIN
byteHigh, byteLow : CARDINAL;
[byteHigh,byteLow] ← DIVMOD[i,256];
s.put[s,byteHigh];
s.put[s,byteLow];
END;

GetShort: PUBLIC PROCEDURE [s:StreamHandle] RETURNS [UNSPECIFIED] =
BEGIN
i: CARDINAL;
i ← s.get[s] * 256;
i ← i + s.get[s];
RETURN[i];
END;

PutLong: PUBLIC PROCEDURE [i: LONG UNSPECIFIED, s: StreamHandle] =
BEGIN
low,high: CARDINAL;
byteHigh, byteLow : CARDINAL;
[low,high] ← BreakLongPointer[i];
[byteHigh,byteLow] ← DIVMOD[low,256];
s.put[s,byteHigh];
s.put[s,byteLow];
[byteHigh,byteLow] ← DIVMOD[high,256];
s.put[s,byteHigh];
s.put[s,byteLow];
END;

GetLong: PUBLIC PROCEDURE [s:StreamHandle] RETURNS [LONG UNSPECIFIED] =
BEGIN
low,high: CARDINAL;
low ← s.get[s] * 256;
low ← low + s.get[s];
high ← s.get[s] * 256;
high ← high + s.get[s];
RETURN[MakeLongPointer[low,high]];
END;

PutReal: PUBLIC PROCEDURE [r: REAL, s:StreamHandle] =
BEGIN
PutLong[LOOPHOLE[r , LONG CARDINAL],s];
END;

GetReal: PUBLIC PROCEDURE [s:StreamHandle] RETURNS [r: REAL] =
BEGIN
r ← LOOPHOLE[GetLong[s],REAL];
END;

DeleteFile: PUBLIC PROCEDURE [s:STRING] =
-- Given a string find file with that name and remove it from directory
BEGIN
ENABLE BEGIN
FileNameError => CONTINUE;-- Signal generated because file didn’t exist: ignore
FileError => BEGIN
WriteString[s];
WriteLine[": Can’t Delete"];
CONTINUE
END;
END;
DestroyFile[NewFile[s,Write,OldFileOnly]];
END;

MakeLongPointer: PROCEDURE[low,high: UNSPECIFIED]
RETURNS[LONG POINTER] = MACHINE CODE
BEGIN --nothing to do-- END;

BreakLongPointer: PROCEDURE[lptr: LONG POINTER]
RETURNS[low,high: UNSPECIFIED] = MACHINE CODE
BEGIN --nothing to do-- END;

WriteLongDecimal: PUBLIC PROCEDURE[n: LONG CARDINAL] =
BEGIN
s: STRING ← [20];
AppendLongDecimal[s,n]; WriteString[s];
END;

END.