DIRECTORY Basics USING [LongNumber], FS USING [AccessOptions, Error, ErrorDesc, StreamOpen], IO USING [Close, EndOfStream, Error, GetByte, GetChar, PutByte, PutChar, STREAM], PS USING [Error, File, NewFile, PopFile, PopInt, PopString, PushBool, PushFile, PushInt, PushString, Register, RegisterPrimitives, Root, RopeFromString, String, StringGet, StringGetInterval, StringIndex, StringPut], Rope USING [Equal, ROPE]; PSFileImpl: CEDAR PROGRAM IMPORTS FS, IO, PS, Rope ~ BEGIN OPEN PS; ROPE: TYPE ~ Rope.ROPE; STREAM: TYPE ~ IO.STREAM; FileCreate: PROC [string1, string2: String] RETURNS [File] ~ { fileName: ROPE ~ RopeFromString[string1]; fileAccess: ROPE ~ RopeFromString[string2]; accessOptions: FS.AccessOptions _ read; stream: STREAM _ NIL; fsError: FS.ErrorDesc; SELECT TRUE FROM Rope.Equal[fileAccess, "r"] => accessOptions _ read; Rope.Equal[fileAccess, "w"] => accessOptions _ create; ENDCASE => ERROR Error[invalidfileaccess]; stream _ FS.StreamOpen[fileName: fileName, accessOptions: accessOptions ! FS.Error => { fsError _ error; CONTINUE }; ]; IF stream=NIL THEN SELECT fsError.group FROM user => ERROR Error[undefinedfilename]; ENDCASE => ERROR Error[ioerror]; RETURN [NewFile[executable: FALSE, access: unlimited, stream: stream]]; }; WriteString: PROC [file: File, string: String] ~ { IF file.access GOTO IOError; ]; ENDLOOP; EXITS IOError => ERROR Error[ioerror]; }; Pfile: PROC [self: Root] ~ { string2: String ~ PopString[self]; string1: String ~ PopString[self]; PushFile[self, FileCreate[string1, string2]]; }; Pclosefile: PROC [self: Root] ~ { file: File ~ PopFile[self]; IO.Close[file.stream]; }; Pread: PROC [self: Root] ~ { file: File ~ PopFile[self]; int: INT; IF file.access GOTO EndOfFile; IO.Error => IF ec=StreamClosed THEN GOTO EndOfFile ELSE GOTO IOError; ]; PushInt[self, int]; PushBool[self, TRUE]; EXITS EndOfFile => PushBool[self, FALSE]; IOError => ERROR Error[ioerror]; }; Pwrite: PROC [self: Root] ~ { int: INT ~ PopInt[self]; file: File ~ PopFile[self]; IF file.access GOTO IOError; IO.Error => GOTO IOError; ]; EXITS IOError => ERROR Error[ioerror]; }; Preadhexstring: PROC [self: Root] ~ { string: String ~ PopString[self]; file: File ~ PopFile[self]; hi: [0..2] _ 0; h: ARRAY [0..2) OF [0..16) _ ALL[0]; si: StringIndex _ 0; IF file.access EXIT; IO.Error => GOTO IOError; ]; SELECT char FROM IN ['0..'9] => { h[hi] _ (char-'0); hi _ hi+1 }; IN ['A..'F] => { h[hi] _ 10+(char-'A); hi _ hi+1 }; IN ['a..'f] => { h[hi] _ 10+(char-'a); hi _ hi+1 }; ENDCASE; IF hi=2 THEN { StringPut[string, si, VAL[h[0]*16+h[1]]]; si _ si+1; hi _ 0 }; ENDLOOP; IF si=string.length THEN { PushString[self, string]; PushBool[self, TRUE] } ELSE { PushString[self, StringGetInterval[string, 0, si]]; PushBool[self, FALSE] }; EXITS IOError => ERROR Error[ioerror]; }; Pwritehexstring: PROC [self: Root] ~ { string: String ~ PopString[self]; file: File ~ PopFile[self]; IF file.access GOTO IOError; ]; IO.PutChar[file.stream, Hex[byte MOD 16] ! IO.Error => GOTO IOError; ]; ENDLOOP; EXITS IOError => ERROR Error[ioerror]; }; Preadstring: PROC [self: Root] ~ { string: String ~ PopString[self]; file: File ~ PopFile[self]; si: StringIndex _ 0; IF file.access EXIT; IO.Error => GOTO IOError; ]; StringPut[string, si, char]; si _ si+1; ENDLOOP; IF si=string.length THEN { PushString[self, string]; PushBool[self, TRUE] } ELSE { PushString[self, StringGetInterval[string, 0, si]]; PushBool[self, FALSE] }; EXITS IOError => ERROR Error[ioerror]; }; Pwritestring: PROC [self: Root] ~ { string: String ~ PopString[self]; file: File ~ PopFile[self]; WriteString[file, string]; }; Preadline: PROC [self: Root] ~ { }; Pbytesavailable: PROC [self: Root] ~ { }; Pflush: PROC [self: Root] ~ { }; Pflushfile: PROC [self: Root] ~ { }; Presetfile: PROC [self: Root] ~ { }; Pstatus: PROC [self: Root] ~ { }; Prun: PROC [self: Root] ~ { }; Pcurrentfile: PROC [self: Root] ~ { }; Pprint: PROC [self: Root] ~ { string: String ~ PopString[self]; WriteString[self.stdout, string]; }; Pecho: PROC [self: Root] ~ { }; FilePrimitives: PROC [self: Root] ~ { Register[self, "file", Pfile]; Register[self, "closefile", Pclosefile]; Register[self, "read", Pread]; Register[self, "write", Pwrite]; Register[self, "readhexstring", Preadhexstring]; Register[self, "writehexstring", Pwritehexstring]; Register[self, "readstring", Preadstring]; Register[self, "writestring", Pwritestring]; Register[self, "readline", Preadline]; Register[self, "bytesavailable", Pbytesavailable]; Register[self, "flush", Pflush]; Register[self, "flushfile", Pflushfile]; Register[self, "resetfile", Presetfile]; Register[self, "status", Pstatus]; Register[self, "run", Prun]; Register[self, "currentfile", Pcurrentfile]; Register[self, "print", Pprint]; Register[self, "echo", Pecho]; }; RegisterPrimitives[FilePrimitives]; END. \PSFileImpl.mesa Copyright Σ 1986, 1987 by Xerox Corporation. All rights reserved. Doug Wyatt, May 14, 1987 11:38:33 am PDT PostScript implementation: file operations. File operations SELECT TRUE FROM Rope.Equal[fileName, "%stdin"] => xxx; Rope.Equal[fileName, "%stdout"] => xxx; Rope.Equal[fileName, "%stderr"] => xxx; ENDCASE; Primitives Κή˜codešœ™KšœB™BK™(—K˜K™+K™šΟk ˜ Kšœœ˜Kšœœ/˜7KšœœAœ˜QKšœœΟ˜ΧKšœœ œ˜—K˜KšΟn œœ˜Kšœœœœ˜šœœœœ˜K˜Kšœœœ˜Kšœœœœ˜—head™šž œœœ ˜>Kšœ œ˜)Kšœ œ˜+Kšœœ˜'Kšœœœ˜Kšœ œ ˜šœœ™Kšœ&™&Kšœ'™'Kšœ'™'Kšœ™—šœœ˜Kšœ4˜4Kšœ6˜6Kšœœ˜*—šœ œ>˜IKšœœ˜*K˜—š œœœœ˜,Kšœœ˜'Kšœœ˜ —Kšœœ&˜GK˜K˜—šž œœ!˜2Kšœœœ˜9šœœ˜+Kšœœ˜#šœ˜Kšœ œ ˜Kšœ˜—Kšœ˜—š˜Kšœ œ˜ —K˜K˜——™ šžœœ˜K˜"K˜"K˜-K˜K˜—šž œœ˜!K˜Kšœ˜K˜K˜—šžœœ˜K˜Kšœœ˜ Kšœœœ˜8šœœ˜Kšœœ ˜!Kš œ œœœ œœ ˜EKšœ˜—Kšœ˜Kšœœ˜š˜Kšœœ˜#Kšœ œ˜ —K˜K˜—šžœœ˜Kšœœ˜K˜Kšœœœ˜9šœœ˜=Kšœœ ˜Kšœ œ ˜Kšœ˜—š˜Kšœ œ˜ —K˜K˜—šžœœ˜%K˜!K˜K˜Kšœœœ œ˜$K˜Kšœœœ˜8šœ˜šœœœ˜%Kšœœ˜Kšœ œ ˜K˜—šœ˜Kšœ.˜0Kšœ1˜3Kšœ1˜3Kšœ˜—Kšœœœ%˜MKšœ˜—Kšœœ,œ˜KKšœFœ˜Sš˜Kšœ œ˜ —K˜K˜—šžœœ˜&K˜!K˜Kšœœœ˜9šœœ˜+Kšœœœ˜(šžœœœœ˜)Kšœœœœ ˜*Kšœ˜—šœ$˜&Kšœ œ ˜Kšœ˜—šœœ˜*Kšœ œ ˜Kšœ˜—Kšœ˜—š˜Kšœ œ˜ —K˜K˜—šž œœ˜"K˜!K˜K˜Kšœœœ˜8šœ˜šœœœ˜%Kšœœ˜Kšœ œ ˜K˜—Kšœ˜Kšœ ˜ Kšœ˜—Kšœœ,œ˜KKšœFœ˜Sš˜Kšœ œ˜ —K˜K˜—šž œœ˜#K˜!K˜K˜K˜K˜—šž œœ˜ K˜K˜—šžœœ˜&K˜K˜—šžœœ˜K˜K˜—šž œœ˜!K˜K˜—šž œœ˜!K˜K˜—šžœœ˜K˜K˜—šžœœ˜K˜K˜—šž œœ˜#K˜K˜—šžœœ˜K˜!Kšœ!˜!K˜K˜—šžœœ˜K˜K˜—J˜šžœœ˜%Kšœ˜Kšœ(˜(Kšœ˜Kšœ ˜ Kšœ0˜0Kšœ2˜2Kšœ*˜*Kšœ,˜,Kšœ&˜&Kšœ2˜2Kšœ ˜ Kšœ(˜(Kšœ(˜(Kšœ"˜"Kšœ˜Kšœ,˜,Kšœ ˜ Kšœ˜J˜J˜—J˜#—J˜Jšœ˜—…—V