DIRECTORY Convert USING [RealFromRope, RopeFromReal], IO, PascalBasic, PascalInlineFiles, Real USING [DefaultSinglePrecision], RefText USING [TrustTextAsRope], Rope USING [Cat, Fetch, FromChar, Length]; PascalInlineFilesImpl: CEDAR PROGRAM IMPORTS Convert, IO, PascalBasic, PascalInlineFiles, RefText, Rope EXPORTS PascalInlineFiles = BEGIN OPEN PascalBasic, PascalInlineFiles; openFiles: MesaFilePtr _ NIL; PascalTextBREAK: PUBLIC PROCEDURE [file: PascalTextFilePtr] = TRUSTED BEGIN file.baseFile.str.Flush[]; END; PascalTextRESET: PUBLIC PROCEDURE [file: PascalTextFilePtr] = TRUSTED BEGIN file.baseFile.str.SetIndex[0 ! IO.Error => {IF ec = NotImplementedForThisStream THEN CONTINUE}]; file.baseFile.eof _ FALSE; PascalTextGET[file]; END; PascalTextREWRITE: PUBLIC PROCEDURE [file: PascalTextFilePtr] = TRUSTED BEGIN file.baseFile.str.SetIndex[0 ! IO.Error => {IF ec = NotImplementedForThisStream THEN CONTINUE}]; file.baseFile.str.SetLength[0 ! IO.Error => {IF ec = NotImplementedForThisStream THEN CONTINUE}]; file.baseFile.eof _ TRUE; END; PascalBREAK: PUBLIC PROCEDURE [ file: PascalFilePtr, length: CARDINAL, element: LONG POINTER] = TRUSTED {file.str.Flush[]}; PascalRESET: PUBLIC UNSAFE PROCEDURE [ file: PascalFilePtr, length: CARDINAL, element: LONG POINTER -- TO ARRAY[0..length/2) OF UNSPECIFIED --] = UNCHECKED BEGIN file.str.SetIndex[0]; file.eof _ FALSE; PascalGET[file, length, element]; END; PascalREWRITE: PUBLIC PROCEDURE [ file: PascalFilePtr, length: CARDINAL _ 0, element: LONG POINTER -- TO ARRAY[0..length/2) OF UNSPECIFIED -- _ NIL] = TRUSTED BEGIN file.str.SetIndex[0]; file.str.SetLength[0]; file.eof _ TRUE; END; PascalReadLn: PUBLIC PROCEDURE [file: PascalTextFilePtr] = TRUSTED BEGIN WHILE NOT PascalTextEOLN[file] DO PascalTextGET[file] ENDLOOP; PascalTextGET[file]; END; PascalWriteLn: PUBLIC PROCEDURE [file: PascalTextFilePtr] = TRUSTED BEGIN file.baseFile.str.PutChar['\N -- CarriageReturn -- ]; END; PascalReadInteger: PUBLIC PROCEDURE [file: PascalTextFilePtr] RETURNS [PascalInteger] = TRUSTED BEGIN SkipBlanks[file]; SELECT file.element FROM '- => {PascalTextGET[file]; RETURN[-ReadDecimal[file].n]}; '+ => {PascalTextGET[file]; RETURN[ReadDecimal[file].n]}; ENDCASE => RETURN[ReadDecimal[file].n]; END; SkipBlanks: PROCEDURE [file: PascalTextFilePtr] = TRUSTED BEGIN WHILE NOT PascalTextEOF[file] AND (SELECT file.element FROM '-, '+, IN ['0..'9], '., IN ['a..'z], IN ['A..'Z] => FALSE, ENDCASE => TRUE) DO PascalTextGET[file] ENDLOOP; END; ReadDecimal: PROCEDURE [file: PascalTextFilePtr] RETURNS [n, digitCount: PascalInteger] = TRUSTED BEGIN n _ 0; digitCount _ 0; IF NOT PascalTextEOF[file] AND file.element NOT IN ['0..'9] THEN SIGNAL NumericInputError; WHILE file.element IN ['0..'9] DO n _ 10*n + (file.element - '0); digitCount _ digitCount + 1; PascalTextGET[file]; ENDLOOP; END; PascalWriteInteger: PUBLIC PROCEDURE [ file: PascalTextFilePtr, item: PascalInteger, fieldMinLength: PascalInteger _ -1] = TRUSTED BEGIN sayMinus: BOOLEAN _ FALSE; digits: ARRAY [0..15] OF [0..9]; nDigits: [0..15] _ 0; i: PascalInteger; stream: IO.STREAM; stream _ file.baseFile.str; IF NOT fieldMinLength IN [0..1] THEN stream.PutChar[' ]; IF sayMinus _ item < 0 THEN { item _ -item; fieldMinLength _ fieldMinLength - 1}; IF item = 0 THEN {digits[0] _ 0; nDigits _ 1} ELSE WHILE item # 0 DO digits[nDigits] _ item MOD 10; nDigits _ nDigits + 1; item _ item/10; ENDLOOP; FOR i IN [1..fieldMinLength - nDigits] DO stream.PutChar[' ] ENDLOOP; IF sayMinus THEN stream.PutChar['-]; FOR i DECREASING IN [0..nDigits) DO stream.PutChar['0 + digits[i]] ENDLOOP; END; PascalReadReal: PUBLIC PROCEDURE [file: PascalTextFilePtr] RETURNS [PascalReal] = TRUSTED BEGIN s: REF TEXT _ NEW[TEXT[50]]; s.length _ 0; SkipBlanks[file]; WHILE (SELECT file.element FROM IN ['a..'z], IN ['A..'Z], '+, '-, '., IN ['0..'9] => TRUE, ENDCASE => FALSE) DO s[s.length] _ file.element; s.length _ s.length + 1; PascalTextGET[file]; ENDLOOP; RETURN[Convert.RealFromRope[RefText.TrustTextAsRope[s]]]; END; PascalWriteReal: PUBLIC PROCEDURE [ file: PascalTextFilePtr, item: PascalReal, fieldMinLength, fracLength: PascalInteger _ -1] = TRUSTED BEGIN shortFracLength: INTEGER _ fracLength; IF NOT fieldMinLength IN [0..1] THEN file.baseFile.str.PutChar[' ]; PascalWriteString[file, Convert.RopeFromReal[ from: item, precision: IF fracLength < 0 THEN Real.DefaultSinglePrecision ELSE shortFracLength], fieldMinLength]; END; PascalReadChar: PUBLIC PROCEDURE [file: PascalTextFilePtr] RETURNS [PascalChar] = TRUSTED BEGIN c: PascalChar; c _ PascalTextElement[file]; PascalTextGET[file]; RETURN[c]; END; PascalWriteChar: PUBLIC PROCEDURE [ file: PascalTextFilePtr, item: PascalChar, fieldMinLength: PascalInteger _ -1] = TRUSTED BEGIN i: PascalInteger; FOR i IN [1..fieldMinLength) DO file.baseFile.str.PutChar[' ] ENDLOOP; IF fieldMinLength#0 THEN BEGIN file.baseFile.str.PutChar[item]; file.element _ item; END; END; PascalReadBoolean: PUBLIC PROCEDURE [file: PascalTextFilePtr] RETURNS [PascalBoolean] = TRUSTED BEGIN b: PascalBoolean; SkipBlanks[file]; SELECT file.element FROM 'T, 't => b _ TRUE; 'F, 'f => b _ FALSE; ENDCASE => {SIGNAL NumericInputError; b _ FALSE}; WHILE (SELECT file.element FROM IN ['a..'z], IN ['A..'Z] => TRUE, ENDCASE => FALSE) DO PascalTextGET[file] ENDLOOP; RETURN[b]; END; PascalWriteBoolean: PUBLIC PROCEDURE [ file: PascalTextFilePtr, item: PascalBoolean, fieldMinLength: PascalInteger _ -1] = TRUSTED BEGIN IF NOT fieldMinLength IN [0..1] THEN PascalWriteChar[file, ' ]; PascalWriteString[file, IF item THEN "TRUE" ELSE "FALSE", fieldMinLength]; END; PascalReadArrayOfChar, PascalReadLongArrayOfChar: PUBLIC UNSAFE PROCEDURE [ file: PascalTextFilePtr, item: CharArrayPtr, arrayBound: PascalInteger] = UNCHECKED BEGIN v: CharArrayConcretePtr _ item; i: PascalInteger; FOR i IN [1..arrayBound] DO v[i] _ PascalTextElement[file]; PascalTextGET[file]; ENDLOOP; END; PascalWriteArrayOfChar, PascalWriteLongArrayOfChar: PUBLIC PROCEDURE [ file: PascalTextFilePtr, item: CharArrayPtr, arrayBound: PascalInteger, fieldMinLength: PascalInteger _ -1] = TRUSTED BEGIN v: CharArrayConcretePtr _ LOOPHOLE[item]; i, arrayLim: PascalInteger; FOR i IN [arrayBound..fieldMinLength) DO file.baseFile.str.PutChar[' ] ENDLOOP; arrayLim _ IF fieldMinLength < 0 THEN arrayBound ELSE MIN[fieldMinLength, arrayBound]; FOR i IN [1..arrayLim] DO file.baseFile.str.PutChar[v[i]] ENDLOOP; IF ((fieldMinLength < 0 AND arrayLim > 0) OR fieldMinLength>0) THEN file.element _ IF arrayLim > 0 THEN v[arrayLim] ELSE ' ; END; ReadString: PRIVATE PROCEDURE [file: PascalTextFilePtr] RETURNS [r: ROPE]= TRUSTED BEGIN r _ ""; WHILE NOT PascalTextEOLN[file] AND NOT file.baseFile.eof DO r _ Rope.Cat[r, Rope.FromChar[file.element]]; PascalTextGET[file]; ENDLOOP; END; PascalWriteString, PascalWriteLongString: PUBLIC PROCEDURE [ file: PascalTextFilePtr, item: ROPE, fieldMinLength: PascalInteger _ -1] = TRUSTED BEGIN i, len, stringLim: PascalInteger; len _ item.Length[]; FOR i IN [len..fieldMinLength) DO file.baseFile.str.PutChar[' ] ENDLOOP; stringLim _ IF fieldMinLength < 0 THEN len ELSE MIN[fieldMinLength, len]; FOR i IN [0..stringLim) DO file.baseFile.str.PutChar[Rope.Fetch[item, i]] ENDLOOP; IF ((fieldMinLength < 0 AND stringLim > 0) OR fieldMinLength>0) THEN file.element _ IF stringLim > 0 THEN Rope.Fetch[item, stringLim-1] ELSE ' ; END; PascalOpenTextFileWithStream: PUBLIC UNSAFE PROCEDURE [ file: PascalTextFilePtr, stream: IO.STREAM] = UNCHECKED BEGIN openFiles _ z.NEW[MesaFile _ [str: stream, openFileLink: openFiles]]; file.baseFile _ LOOPHOLE[openFiles]; END; PascalOpenTextFileTTYInput: PUBLIC UNSAFE PROCEDURE [ file: PascalTextFilePtr] = UNCHECKED BEGIN openFiles _ z.NEW[MesaFile _ [str: ttyInputStream, eof: FALSE, openFileLink: openFiles]]; file.baseFile _ LOOPHOLE[openFiles]; file.element _ ' ; file.eoln _ TRUE; END; PascalOpenTextFileTTYOutput: PUBLIC UNSAFE PROCEDURE [ file: PascalTextFilePtr] = UNCHECKED BEGIN openFiles _ z.NEW[MesaFile _ [str: ttyOutputStream, eof: TRUE, openFileLink: openFiles]]; file.baseFile _ LOOPHOLE[openFiles]; END; PascalCloseTextFile: PUBLIC UNSAFE PROCEDURE [file: PascalTextFilePtr] = UNCHECKED BEGIN IF file.baseFile # NIL THEN file.baseFile.str.Close[]; file.baseFile _ NIL; END; PascalOpenFileWithStream: PUBLIC UNSAFE PROCEDURE [ file: PascalFilePtr, stream: IO.STREAM] = UNCHECKED BEGIN openFiles _ z.NEW[MesaFile _ [str: stream, openFileLink: openFiles]]; file^ _ LOOPHOLE[openFiles]; END; PascalCloseFile: PUBLIC UNSAFE PROCEDURE [file: PascalFilePtr] = UNCHECKED BEGIN IF file^ # NIL THEN file.str.Close[]; file^ _ NIL; END; END. -- PascalInlineFilesImpl 8file: PascalInlineFilesImpl.mesa last modified by Ramshaw, December 25, 1982 11:01 am written by McCreight, December 19, 1980 10:44 AM a thin layer of Pascal files on top of IO.STREAM V A R I A B L E S (all private) P R O C E D U R E S Text File Operations: Binary File Operations: formatted input and output: P R O C E D U R E S NOT Called by PasMesa (and hence, intended to be called as external procedures by the Pascal program, or else from Mesa code that implements such external procedures). text file operations Allocates a new MesaFile and installs the specified stream Allocates a new MesaFile and sets up file to read from the terminal (no pre-read) Allocates a new MesaFile and sets up file to output to the terminal Closes the file, and sets the PascalFile to NIL; the MesaFile must continue to exist however, to avoid collecting non-garbage. binary file operations Allocates a new MesaFile and installs the specified stream Closes the file, and sets the PascalFile to NIL; the MesaFile must continue to exist however, to avoid collecting non-garbage. Ê â˜Jšœ!™!Jšœ4™4Jšœ1™1J˜Jšœ0™0J˜šÏk ˜ Jšœœ˜+Jšœ˜J˜ J˜Jšœœ˜$Jšœœ˜ Jšœœ ˜*J˜—šœœ˜$Jšœ œ/˜BJšœ˜J˜Jšœœ ˜*J˜J˜Jšœ ™ J˜Jšœœ˜J˜J˜Jšœ™J˜—Jšœ™˜šÏnœœ œ˜>Jšœ˜ J˜Jšœ˜J˜—šžœœ œ˜=Jšœ˜ ˜Jšœ œ"œœ˜A—Jšœœ˜J˜Jšœ˜J˜—šžœœ œ˜?Jšœ˜ ˜Jšœ œ"œœ˜A—˜Jšœ œ"œœ˜A—Jšœœ˜Jšœ˜J˜——Jšœ™˜šž œœ œ˜Jšœœ˜&Jšœ œœœ˜4J˜—šž œœœ œ˜&Jšœœ˜&Jšœ œœÏc*œ˜CJš œ˜J˜Jšœ œ˜J˜!Jšœ˜J˜—šž œœ œ˜!Jšœœ˜*Jš œ œœŸ*œœ˜IJšœ˜ J˜J˜Jšœ œ˜Jšœ˜J˜——Jšœ™˜šž œœ œ˜:Jšœ˜ Jšœœœœ˜>J˜Jšœ˜J˜—šž œœ œ˜;Jšœ˜ JšœŸœ˜5Jšœ˜J˜—šžœœ œ˜=Jšœ˜Jšœ˜ J˜šœ˜Jšœœ˜:Jšœœ˜9Jšœœ˜'—Jšœ˜J˜—šž œ œ˜1Jšœ˜ šœœ˜š˜šœœ˜Jš œœœ œ œ˜;Jšœœœœ˜0———Jšœ˜J˜—šž œ œ˜0Jšœ!˜(Jšœ˜ J˜J˜š œœœœœ ˜@Jšœ˜—šœœ ˜!J˜J˜J˜Jšœ˜—Jšœ˜J˜—šžœœ œ˜&J˜-J˜%Jšœ˜ Jšœ œœ˜Jšœœ œ˜ J˜J˜Jšœœœ˜J˜Jšœœœœ˜8šœœ˜J˜3—Jšœ œ˜-š˜šœ ˜Jšœœ˜J˜J˜Jšœ˜——Jšœœœœ˜EJšœ œ˜$šœ œœ˜#Jšœœ˜'—Jšœ˜J˜—šžœœ œ˜:Jšœ˜Jšœ˜ Jš œœœœœ˜J˜ J˜š˜šœœ˜Jšœ œœ œ˜:Jšœœ˜—J˜J˜J˜Jšœ˜—Jšœ3˜9Jšœ˜J˜—šžœœ œ˜#J˜*J˜1Jšœ˜ Jšœœ˜&šœœœ˜$J˜—˜-J˜ J˜ Jšœœœ#˜Z—Jšœ˜J˜—šžœœ œ˜:Jšœ˜Jšœ˜ ˜J˜—J˜Jšœ˜ Jšœ˜J˜—šžœœ œ˜#J˜*J˜%Jšœ˜ J˜šœœ˜Jšœœ˜&—šœ˜Jš˜J˜ J˜Jšœ˜—Jšœ˜J˜—šžœœ œ˜=Jšœ˜Jšœ˜ J˜J˜šœ˜Jšœœ˜Jšœœ˜Jšœœœ˜1—š˜šœœ˜Jšœ œ œ˜!Jšœœœœ˜1——Jšœ˜ Jšœ˜J˜—šžœœ œ˜&J˜-J˜%Jšœ˜ šœœœ˜$J˜—Jšœœœœ˜JJšœ˜J˜—˜1Jšœœ œ˜J˜J˜0Jš œ˜J˜J˜šœœ˜Jšœ5œ˜=—Jšœ˜J˜—˜3Jšœ œ˜J˜J˜J˜@Jšœ˜ Jšœœ˜)J˜šœœ˜(Jšœœ˜&—˜ Jšœœ œœ˜K—šœœ˜Jšœ œ˜(—šœœœ˜CJšœœœ œ˜8—Jšœ˜J˜—š ž œœ œœœ˜KJšœ˜ J˜š œœœœ˜;J˜-J˜Jšœ˜—Jšœ˜J˜—šœžœœ œ˜