<> <> <> <> DIRECTORY Basics USING [LowByte], Convert USING [RealFromRope, RopeFromReal], IO, PascalBasic, PascalWizardFiles, PrincOpsUtils USING [LongCopy], Real USING [DefaultSinglePrecision], RefText USING [TrustTextAsRope], Rope USING [Cat, Fetch, FromChar, Length]; PascalWizardFilesImpl: CEDAR PROGRAM IMPORTS Basics, Convert, IO, PascalBasic, PrincOpsUtils, RefText, Rope EXPORTS PascalWizardFiles = BEGIN OPEN PascalBasic, PascalWizardFiles; <> openFiles: MesaFilePtr _ NIL; <

> <> PascalTextBREAK: PUBLIC PROCEDURE [file: PascalTextFilePtr] = TRUSTED BEGIN file.baseFile.str.Flush[]; END; PascalTextGET: PUBLIC PROCEDURE [file: PascalTextFilePtr] = TRUSTED BEGIN file.element _ file.baseFile.str.GetChar[ ! IO.EndOfStream => GOTO EOF]; SELECT file.element FROM '\N --CarriageReturn-- => { file.eoln _ TRUE; file.element _ ' }; ENDCASE => file.eoln _ FALSE; EXITS EOF => { file.baseFile.eof _ file.eoln _ TRUE; file.element _ ' }; END; PascalTextElement: PUBLIC PROCEDURE [file: PascalTextFilePtr] RETURNS [PascalChar] = TRUSTED BEGIN RETURN[file.element]; END; PascalTextPUT: PUBLIC PROCEDURE [file: PascalTextFilePtr] = TRUSTED BEGIN file.baseFile.str.PutChar[file.element]; 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; PascalTextPAGE: PUBLIC PROCEDURE [file: PascalTextFilePtr] = BEGIN PascalWriteLn[file: file]; PascalWriteChar[file: file, item: '\F --form feed--]; PascalWriteLn[file: file] END; PascalTextEOF: PUBLIC PROCEDURE [file: PascalTextFilePtr] RETURNS [BOOLEAN] = TRUSTED BEGIN RETURN[file.baseFile.eof]; END; PascalTextEOLN: PUBLIC PROCEDURE [file: PascalTextFilePtr] RETURNS [BOOLEAN] = TRUSTED BEGIN RETURN[file.eoln]; END; <> PascalBREAK: PUBLIC PROCEDURE [ file: PascalFilePtr, length: CARDINAL, element: LONG POINTER] = TRUSTED {file.str.Flush[]}; PascalGET: PUBLIC UNSAFE PROCEDURE [ file: PascalFilePtr, length: CARDINAL, element: LONG POINTER -- TO ARRAY[0..length) OF UNSPECIFIED --] = UNCHECKED BEGIN IF length = 1 THEN element^ _ file.str.GetChar[ ! IO.EndOfStream => {file.eof _ TRUE; CONTINUE}] ELSE IF length # file.str.UnsafeGetBlock[[base: element, startIndex: 0, count: length]] THEN file.eof _ TRUE; END; PascalPUT: PUBLIC PROCEDURE [ file: PascalFilePtr, length: CARDINAL, element: LONG POINTER -- TO ARRAY[0..length) OF UNSPECIFIED --] = TRUSTED BEGIN IF length = 1 THEN file.str.PutChar[LOOPHOLE[Basics.LowByte[LOOPHOLE[element^]]]] ELSE file.str.UnsafePutBlock[[base: element, startIndex: 0, count: length]]; END; 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; PascalRead, PascalReadLong: PUBLIC UNSAFE PROCEDURE [ file: PascalFilePtr, length: CARDINAL, element: LONG POINTER -- TO ARRAY[0..length/2) OF UNSPECIFIED --, item: LONG POINTER -- TO ARRAY[0..length/2) OF UNSPECIFIED --] = UNCHECKED BEGIN IF length = 1 THEN item^ _ element^ ELSE PrincOpsUtils.LongCopy[from: element, nwords: length/2, to: item]; PascalGET[file: file, length: length, element: element]; END; PascalWrite, PascalWriteLong: PUBLIC UNSAFE PROCEDURE [ file: PascalFilePtr, length: CARDINAL, element: LONG POINTER TO -- ARRAY[0..length/2) OF -- UNSPECIFIED, item: LONG POINTER TO -- ARRAY[0..length/2) OF -- UNSPECIFIED] = UNCHECKED BEGIN IF length = 1 THEN element^ _ item^ ELSE PrincOpsUtils.LongCopy[from: item, nwords: length/2, to: element]; PascalPUT[file: file, length: length, element: element]; END; PascalEOF: PUBLIC PROCEDURE [file: PascalFilePtr] RETURNS [BOOLEAN] = TRUSTED { RETURN[file.eof]}; <> 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; <

> <<(and hence, intended to be called as external procedures by the Pascal>> <> <> 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. -- PascalWizardFilesImpl