(FILECREATED "26-JUL-83 22:00:34" {PHYLUM}<LISPCORE>SOURCES>AOFD.;22 56115Q 

      changes to:  (FNS OUTPUT INPUT)

      previous date: "24-JUL-83 19:45:32" {PHYLUM}<LISPCORE>SOURCES>AOFD.;20)


(* Copyright (c) 1981, 1982, 1983 by Xerox Corporation)

(PRETTYCOMPRINT AOFDCOMS)

(RPAQQ AOFDCOMS ((* Open file descriptors. This file is shared with VAX.)
		 (FNS CLOSEALL CLOSEF INPUT OPENP OUTPUT POSITION RANDACCESSP \IOMODEP)
		 [COMS (FNS \STRINGOFD \STRINGINIT \STRING.NAME.FROM.STREAM \STRINGSETFILEPTR)
		       (DECLARE: DONTCOPY (RECORDS STREAMOFSTRING))
		       (DECLARE: DONTEVAL@LOAD (P (\STRINGINIT]
		 [COMS (* STREAM interface to Read and Write to random memory)
		       (DECLARE: EVAL@COMPILE DONTCOPY (RECORDS BASEBYTESTREAM))
		       (FNS \BASEBYTES.IO.INIT \MAKEBASEBYTESTREAM \BASEBYTES.NAME.FROM.STREAM 
			    \BASEBYTES.BLOCKIO)
		       (GLOBALVARS \BASEBYTESDEVICE)
		       (DECLARE: DONTEVAL@LOAD (P (\BASEBYTES.IO.INIT))
				 (P (MOVD? (QUOTE NILL)
					   (QUOTE \CREATE.TTYDISPLAYSTREAM]
		 (FNS GETOFD GETSTREAM \ADDOFD \DELETEOFD \GETOFD \RESETOFDS \CLEAROFD)
		 (INITVARS (\STRINGOFDS (CONS (HARRAY 12Q)))
			   (\OPENFILES))
		 (GLOBALVARS \OPENFILES)
		 (LOCALVARS . T)))



(* Open file descriptors. This file is shared with VAX.)

(DEFINEQ

(CLOSEALL
  [LAMBDA (ALLFLG)                                           (* wt: "24-JUL-78 23:03")
    (DECLARE (LOCALVARS . T))

          (* The OPENP in the when catches the case where a WHENCLOSE on an earlier file closes a later file in the original
	  value of OPENP)


    (MAPCONC (OPENP)
	     (FUNCTION (LAMBDA (FL)
		 (AND (OPENP FL)
		      [OR ALLFLG (NOT (GETPROP FL (QUOTE CLOSEALL]
		      (LIST (CLOSEF FL])

(CLOSEF
  [LAMBDA (FILE)                                             (* rrb "21-JUL-83 10:55")
    (PROG ((OFD (\GETOFD FILE)))
          (COND
	    ((OR (\OUTTERMP OFD)
		 (NOT (fetch USERCLOSEABLE of OFD)))
	      (RETURN NIL)))
          (\CLEAROFD)
          (COND
	    ((EQ OFD \PRIMIN.OFD)
	      (SETQ \PRIMIN.OFD \LINEBUF.OFD)))
          (COND
	    ((EQ OFD \PRIMOUT.OFD)
	      (SETQ \PRIMOUT.OFD \TERM.OFD)))
          (\DELETEOFD OFD)

          (* Logical close before physical close; otherwise, we might have a logically open file with no physically open 
	  file behind it. (Device LPT depends on this))


          (\CLOSEFILE OFD)
          (RETURN (fetch FULLNAME of OFD])

(INPUT
  [LAMBDA (FILE)                                             (* bvm: "26-JUL-83 21:59")
    (PROG1 (fetch FULLNAME of \PRIMIN.OFD)
	   (COND
	     (FILE (SETQ \PRIMIN.OFD (COND
		       ((EQ FILE T)                          (* Check explicitly for T to avoid needless creations)
			 \LINEBUF.OFD)
		       (T (\GETOFD FILE (QUOTE INPUT])

(OPENP
  [LAMBDA (FILE ACCESS)                                      (* rmk: "16-MAR-82 23:31")
    (DECLARE (GLOBALVARS \OPENFILES))
    (for OFD in \OPENFILES first [COND
				   (FILE (RETURN (AND (SETQ OFD (\GETOFD FILE ACCESS T))
						      (fetch FULLNAME of OFD]
       when (AND (fetch USERVISIBLE of OFD)
		 (\IOMODEP OFD ACCESS T))
       collect (fetch FULLNAME of OFD])

(OUTPUT
  [LAMBDA (FILE)                                             (* bvm: "26-JUL-83 21:54")
    (PROG1 (fetch FULLNAME of \PRIMOUT.OFD)
	   (COND
	     (FILE (SETQ \PRIMOUT.OFD (COND
		       ((EQ FILE T)                          (* Check for this special so we don't create a tty 
							     window needlessly)
			 \TERM.OFD)
		       (T (\GETOFD FILE (QUOTE OUTPUT])

(POSITION
  [LAMBDA (FILE N)                                           (* rrb "21-JUL-83 12:26")
    (PROG [(OFD (COND
		  (FILE (\GETOFD FILE))
		  (T \PRIMOUT.OFD]
          (RETURN (PROG1 (fetch XPOSITION of OFD)
			 (COND
			   (N (replace XPOSITION of OFD with (COND
							       ((IGREATERP N 0)
								 N)
							       (T 
                                                             (* compatible with PDP-10 version)
								  0])

(RANDACCESSP
  [LAMBDA (FILE)                                             (* bvm: "30-JAN-82 17:33")
    (PROG ((STREAM (\GETOFD FILE)))
          (RETURN (AND (fetch RANDOMACCESSP of (fetch DEVICE of STREAM))
		       (NEQ STREAM \LINEBUF.OFD)
		       (fetch FULLNAME of STREAM])

(\IOMODEP
  [LAMBDA (OFD ACCESS NOERROR)                               (* lmm "16-JUL-82 03:07")
                                                             (* Returns OFD if it represents a File open with access 
							     mode ACCESS)
    (COND
      ([COND
	  ((NOT ACCESS)
	    (fetch ACCESS of OFD))
	  ((EQ ACCESS (fetch ACCESS of OFD)))
	  [(EQ (fetch ACCESS of OFD)
	       (QUOTE BOTH))
	    (FMEMB ACCESS (QUOTE (INPUT OUTPUT]
	  ((EQ (fetch ACCESS of OFD)
	       (QUOTE APPEND))
	    (EQ ACCESS (QUOTE OUTPUT]
	OFD)
      (NOERROR NIL)
      (T (LISPERROR "FILE NOT OPEN" (fetch FULLNAME of OFD])
)
(DEFINEQ

(\STRINGOFD
  [LAMBDA (STR)                                              (* dav: " 2-FEB-83 13:00")
                                                             (* (dav: " 9-JUL-82 11:19"))
                                                             (* \GETOFD must see it but OPENP must not)
    (DECLARE (GLOBALVARS \STRINGOFDS \STRINGFDEV))           (* Use a hash-table cause the STREAM then might be 
							     collected)
    (PROG (STRORIG (STREAM (GETHASH STR \STRINGOFDS))
		   (BASE (fetch (STRINGP BASE) of STR))
		   (OFFST (fetch (STRINGP OFFST) of STR))
		   (LEN (fetch (STRINGP LENGTH) of STR)))

          (* STRINGORIGIN maintains the parity of the original first character in the string. We do not let SETFILEPTR or 
	  BACKFILEPTR back behind this, and it is subtracted by GETFILEPTR and GETEOFPTR. This is necessary because the 
	  offset of a substring can be odd. BASE can be NIL for empty strings, with LEN=0 also. Adjust base and offset so 
	  that COFFSET will stay below 512 for small strings.)


          (SETQ STRORIG (IMOD OFFST BYTESPERWORD))
          (add LEN STRORIG)
          (RETURN (COND
		    (STREAM [SELECTQ (SYSTEMTYPE)
				     [VAX (COND
					    ((OR (NEQ OFFST (fetch CPPTR of STREAM))
						 (NEQ LEN (fetch EOFFSET of STREAM))
						 (NEQ BASE (fetch EPAGE of STREAM)))
					      (UNINTERRUPTABLY
                                                  (replace CPPTR of STREAM with OFFST)
						  (replace COFFSET of STREAM with 0)
						  (replace EOFFSET of STREAM with LEN)
						  (replace CBUFSIZE of STREAM with LEN)
						  (replace EPAGE of STREAM with BASE))]
				     (COND
				       ((OR (NEQ (\ADDBASE BASE (FOLDLO OFFST BYTESPERWORD))
						 (fetch CPPTR of STREAM))
					    (NEQ LEN (fetch EOFFSET of STREAM)))
					 (UNINTERRUPTABLY
                                             [replace CPPTR of STREAM
						with (AND BASE (\ADDBASE BASE (FOLDLO OFFST 
										     BYTESPERWORD]
					     (replace STRINGORIGIN of STREAM
						with (replace COFFSET of STREAM with STRORIG))
					     (replace EOFFSET of STREAM with LEN)
					     (replace CBUFSIZE of STREAM with LEN))]
			    STREAM)
		    (T (PUTHASH STR (create STREAMOFSTRING
					    FULLFILENAME ← STR
					    DEVICE ← \STRINGFDEV
					    ACCESS ←(QUOTE INPUT)
					    CPPTR ←(SELECTQ (SYSTEMTYPE)
							    [D (AND BASE (\ADDBASE BASE
										   (FOLDLO OFFST 
										     BYTESPERWORD]
							    (VAX (OR OFFST (PROGN 
                                                             (* Force \TURNPAGE to get called if no buffer)
										  0)))
							    (SYSTEMTYPEPUNT))
					    CPAGE ← 0
					    COFFSET ← STRORIG
					    STRINGORIGIN ← STRORIG
					    EPAGE ← 0
					    EOFFSET ← LEN
					    CBUFSIZE ← LEN
					    F2 ← 0)
				\STRINGOFDS])

(\STRINGINIT
  [LAMBDA NIL                                                (* rmk: "18-MAY-83 22:16")
                                                             (* Initializes the "String" device)
    (DECLARE (GLOBALVARS \STRINGFDEV))
    (SETQ \STRINGFDEV (create FDEV
			      DEVICENAME ←(FUNCTION STRING)
			      RESETABLE ← T
			      RANDOMACCESSP ← T
			      PAGEMAPPED ← NIL
			      CLOSEFILE ←(FUNCTION [LAMBDA (STREAM)
				  (DECLARE (GLOBALVARS \STRINGOFDS))
				  (PUTHASH (fetch (STREAM FULLNAME) of STREAM)
					   NIL \STRINGOFDS])
			      DELETEFILE ←(FUNCTION NILL)
			      GETFILEINFO ←(FUNCTION NILL)
			      OPENFILE ←(FUNCTION \STRINGOFD)
			      READPAGES ←(FUNCTION NILL)
			      SETFILEINFO ←(FUNCTION NILL)
			      GENERATEFILES ←(FUNCTION \GENERATENOFILES)
			      TRUNCATEFILE ←(FUNCTION NILL)
			      WRITEPAGES ←(FUNCTION \ILLEGAL.DEVICEOP)
			      GETFILENAME ←(FUNCTION \STRING.NAME.FROM.STREAM)
			      REOPENFILE ←(FUNCTION \STRINGOFD)
			      EVENTFN ←(FUNCTION NILL)
			      DIRECTORYNAMEP ←(FUNCTION NILL)
			      HOSTNAMEP ←(FUNCTION NILL)
			      BIN ←(SELECTQ (SYSTEMTYPE)
					    (VAX (FUNCTION \STRINGBIN))
					    (FUNCTION \PAGEDBIN))
			      BOUT ←(FUNCTION \ILLEGAL.DEVICEOP)
			      PEEKBIN ←(SELECTQ (SYSTEMTYPE)
						(VAX (FUNCTION \STRINGPEEKBIN))
						(FUNCTION \PAGEDPEEKBIN))
			      BACKFILEPTR ←[FUNCTION (LAMBDA (STREAM)
				  (AND (NEQ (fetch COFFSET of STREAM)
					    (fetch STRINGORIGIN of STREAM))
				       (\PAGEDBACKFILEPTR STREAM]
			      SETFILEPTR ←(SELECTQ (SYSTEMTYPE)
						   [VAX (FUNCTION (LAMBDA (STREAM INDX)
							    (replace F2 of STREAM with INDX]
						   (FUNCTION \STRINGSETFILEPTR))
			      GETFILEPTR ←[SELECTQ (SYSTEMTYPE)
						   [VAX (FUNCTION (LAMBDA (STREAM)
							    (fetch F2 of STREAM]
						   (FUNCTION (LAMBDA (STREAM)
						       (IDIFFERENCE (\PAGEDGETFILEPTR STREAM)
								    (fetch STRINGORIGIN of STREAM]
			      GETEOFPTR ←[SELECTQ (SYSTEMTYPE)
						  [VAX (FUNCTION (LAMBDA (STREAM)
							   (IDIFFERENCE (fetch EOFFSET of STREAM)
									(fetch F1 of STREAM]
						  (FUNCTION (LAMBDA (STREAM)
						      (IDIFFERENCE (\PAGEDGETEOFPTR STREAM)
								   (fetch STRINGORIGIN of STREAM]
			      EOFP ←(FUNCTION \PAGEDEOFP)))
    (\DEFINEDEVICE NIL \STRINGFDEV])

(\STRING.NAME.FROM.STREAM
  [LAMBDA (STREAM)                                           (* bvm: "28-DEC-81 16:57")
    (fetch FULLFILENAME of STREAM])

(\STRINGSETFILEPTR
  [LAMBDA (STREAM INDX)                                      (* rmk: " 2-JUL-82 14:59")
    (add INDX (fetch STRINGORIGIN of STREAM))
    (COND
      [(IGREATERP INDX (\GETEOFPTR STREAM))
	(ERROR "ATTEMPT TO SET STREAFILEPTR BEYOND END OF STRING"
	       (LIST (fetch FULLNAME of STREAM)
		     (IDIFFERENCE INDX (fetch STRINGORIGIN of STREAM]
      (T (replace COFFSET of STREAM with INDX])
)
(DECLARE: DONTCOPY 
[DECLARE: EVAL@COMPILE 

(RECORD STREAMOFSTRING STREAM (SUBRECORD STREAM)
			      [ACCESSFNS ((STRINGORIGIN (fetch (STREAM F1) of DATUM)
							(replace (STREAM F1) of DATUM with NEWVALUE])
]
)
(DECLARE: DONTEVAL@LOAD 
(\STRINGINIT)
)



(* STREAM interface to Read and Write to random memory)

(DECLARE: EVAL@COMPILE DONTCOPY 
[DECLARE: EVAL@COMPILE 

(RECORD BASEBYTESTREAM STREAM (SUBRECORD STREAM)
			      [ACCESSFNS ((BIASOFFST (fetch (STREAM FW6) of DATUM)
						     (replace (STREAM FW6) of DATUM with NEWVALUE))
					  (BBSNCHARS (fetch (STREAM FW7) of DATUM)
						     (replace (STREAM FW7) of DATUM with NEWVALUE))
					  (WRITEXTENSIONFN (fetch (STREAM F1) of DATUM)
							   (replace (STREAM F1) of DATUM
							      with NEWVALUE])
]
)
(DEFINEQ

(\BASEBYTES.IO.INIT
  [LAMBDA NIL
    (DECLARE (GLOBALVARS \BASECHARDEVICE))                   (* JonL " 8-JUL-83 02:22")
    (SETQ \BASEBYTESDEVICE
      (create FDEV
	      DEVICENAME ←(QUOTE BASEBYTES)
	      RESETABLE ← T
	      RANDOMACCESSP ← T
	      PAGEMAPPED ← NIL
	      CLOSEFILE ←(FUNCTION NILL)
	      DELETEFILE ←(FUNCTION NILL)
	      DIRECTORYNAMEP ←(FUNCTION NILL)
	      EVENTFN ←(FUNCTION NILL)
	      GENERATEFILES ←(FUNCTION \GENERATENOFILES)
	      GETFILEINFO ←(FUNCTION NILL)
	      GETFILENAME ←(FUNCTION \BASEBYTES.NAME.FROM.STREAM)
	      HOSTNAMEP ←(FUNCTION NILL)
	      OPENFILE ←(FUNCTION \MAKEBASEBYTESTREAM)
	      READPAGES ←(FUNCTION NILL)
	      REOPENFILE ←(FUNCTION NILL)
	      SETFILEINFO ←(FUNCTION NILL)
	      TRUNCATEFILE ←[FUNCTION (LAMBDA (STREAM I)
		  ([LAMBDA (I' BO EO)
		      (add I' BO)
		      (if (ILESSP I 0)
			  then (add I' EO))
		      (if (OR (ILESSP I BO)
			      (IGREATERP I' EO))
			  then (ERROR "Beyond end of byte range" I)
			else (replace EOFFSET of STREAM with I']
		    I
		    (fetch BIASOFFST of STREAM)
		    (fetch EOFFSET of STREAM]
	      WRITEPAGES ←(FUNCTION \ILLEGAL.DEVICEOP)
	      BIN ←(FUNCTION \PAGEDBIN)
	      BOUT ←[FUNCTION (LAMBDA (STREAM BYTE)
		  (PROG (CO)
		    A   (if (IGEQ (SETQ CO (fetch COFFSET of STREAM))
				  (fetch EOFFSET of STREAM))
			    then (if (SETQ CO (fetch (BASEBYTESTREAM WRITEXTENSIONFN) of STREAM))
				     then (APPLY* CO STREAM)
					  (GO A)
				   else (ERROR "Attempt to write past end of bytes block")))
		        (RETURN (\PUTBASEBYTE (fetch CPPTR of STREAM)
					      (PROG1 CO (freplace COFFSET of STREAM
							   with (ADD1 CO)))
					      BYTE]
	      PEEKBIN ←(FUNCTION \PAGEDPEEKBIN)
	      READP ←[FUNCTION (LAMBDA (STREAM FLG)          (* JonL "13-JUN-83 19:06")
		  (PROG ((CO (fetch COFFSET of STREAM))
			 (#LEFT (fetch EOFFSET of STREAM)))
		        (add #LEFT (IMINUS CO))
		        (RETURN (OR (IGEQ #LEFT 2)
				    (if (ZEROP #LEFT)
					then NIL
				      elseif FLG
				      else (NEQ (\GETBASEBYTE (fetch CPPTR of STREAM)
							      (fetch COFFSET of STREAM))
						(CHARCODE CR]
	      BACKFILEPTR ←[FUNCTION (LAMBDA (STREAM)
		  (AND (NEQ (fetch COFFSET of STREAM)
			    (fetch BIASOFFST of STREAM))
		       (\PAGEDBACKFILEPTR STREAM]
	      SETFILEPTR ←[FUNCTION (LAMBDA (STREAM I)
		  ([LAMBDA (I')
		      (if (IGREATERP I'(fetch EOFFSET of STREAM))
			  then (ERROR "Beyond end of byte range" I)
			else (replace COFFSET of STREAM with I']
		    (IPLUS I (fetch BIASOFFST of STREAM]
	      GETFILEPTR ←[FUNCTION (LAMBDA (STREAM)
		  (IDIFFERENCE (\PAGEDGETFILEPTR STREAM)
			       (fetch BIASOFFST of STREAM]
	      GETEOFPTR ←[FUNCTION (LAMBDA (STREAM)
		  (IDIFFERENCE (\PAGEDGETEOFPTR STREAM)
			       (fetch BIASOFFST of STREAM]
	      EOFP ←[FUNCTION (LAMBDA (STREAM)
		  (IGEQ (fetch COFFSET of STREAM)
			(fetch EOFFSET of STREAM]
	      BLOCKIN ←[FUNCTION (LAMBDA (STREAM BASE OFFST N)
		  (\BASEBYTES.BLOCKIO STREAM BASE OFFST N (QUOTE INPUT]
	      BLOCKOUT ←[FUNCTION (LAMBDA (STREAM BASE OFFST N)
		  (\BASEBYTES.BLOCKIO STREAM BASE OFFST N (QUOTE OUTPUT]
	      RENAMEFILE ←(FUNCTION \ILLEGAL.DEVICEOP)))
    (\DEFINEDEVICE NIL \BASEBYTESDEVICE])

(\MAKEBASEBYTESTREAM
  [LAMBDA (BASE OFFST LEN ACCESS WRITEXTENSIONFN OSTREAM)    (* JonL " 8-JUL-83 02:14")
                                                             (* If an error is to occur due to non-numeric arg or 
							     range restrictions, then let it happen outside the 
							     UNINTERRUPTABLY)
    (OR (AND (SMALLP OFFST)
	     (SMALLP LEN)
	     (SMALLP (add LEN OFFST)))
	(SHOULDNT "Currently can't support fixp-sized offsets"))
    (SELECTQ ACCESS
	     (NIL (SETQ ACCESS (QUOTE INPUT)))
	     ((INPUT OUTPUT BOTH))
	     (\ILLEGAL.ARG ACCESS))
    [OR (AND (type? STREAM OSTREAM)
	     (EQ (ffetch (STREAM DEVICE) of OSTREAM)
		 \BASEBYTESDEVICE))
	(SETQ OSTREAM
	  (create BASEBYTESTREAM
		  DEVICE ← \BASEBYTESDEVICE
		  USERCLOSEABLE ← NIL
		  USERVISIBLE ← NIL
		  EPAGE ← 0
		  BYTESIZE ← BITSPERBYTE
		  CPAGE ← 0
		  LINELENGTH ← 0
		  OUTCHARFN ←(FUNCTION (LAMBDA (STREAM CHAR)
		      (BOUT (SETQ STREAM (\DTEST STREAM (QUOTE STREAM)))
			    CHAR)
		      (add (ffetch BBSNCHARS of STREAM)
			   1]
    (UNINTERRUPTABLY
        (freplace CPPTR of OSTREAM with BASE)
	(freplace COFFSET of OSTREAM with (freplace BIASOFFST of OSTREAM with OFFST))
	(freplace CBUFSIZE of OSTREAM with (freplace EOFFSET of OSTREAM with LEN))
	(freplace BINABLE of OSTREAM with (SELECTQ ACCESS
						   ((INPUT BOTH)
						     T)
						   NIL))
	(freplace BOUTABLE of OSTREAM with (SELECTQ ACCESS
						    ((OUTPUT BOTH)
						      (freplace WRITEXTENSIONFN of OSTREAM
							 with WRITEXTENSIONFN)
						      T)
						    NIL))
	(freplace ACCESSBITS of OSTREAM with (SELECTQ ACCESS
						      (INPUT ReadBit)
						      (OUTPUT OutputBits)
						      (BOTH BothBits)
						      NoBits))
	(freplace BBSNCHARS of OSTREAM with 0))
    OSTREAM])

(\BASEBYTES.NAME.FROM.STREAM
  [LAMBDA (STREAM)                                           (* JonL "14-JUN-83 12:00")
    ([LAMBDA (BO)
	(LIST (fetch CPPTR of STREAM)
	      BO
	      (IDIFFERENCE (fetch EOFFSET of STREAM)
			   BO]
      (fetch BIASOFFST of STREAM])

(\BASEBYTES.BLOCKIO
  [LAMBDA (STREAM BASE OFFST N DIRECTION)                    (* JonL " 8-JUL-83 01:54")
    (PROG (SBASE CO EO)
      A   (if (ILEQ N 0)
	      then (RETURN))
          (SETQ SBASE (fetch CPPTR of STREAM))
          (SETQ CO (fetch COFFSET of STREAM))
          (SETQ EO (fetch EOFFSET of STREAM))
          (if (IGREATERP N (IDIFFERENCE EO (SUB1 CO)))
	      then (if (EQ DIRECTION (QUOTE INPUT))
		       then (STREAMOP (QUOTE ENDOFSTREAMOP)
				      STREAM STREAM)
		     else                                    (* Do a single BOUT to see if the WRITEXTENSIONFN will 
							     fix it up)
			  (BOUT STREAM (\GETBASEBYTE BASE OFFST))
			  (add OFFST 1)
			  (add N -1)
			  (GO A)))
          (replace COFFSET of STREAM with (IPLUS CO N))
          (if (EQ DIRECTION (QUOTE OUTPUT))
	      then (swap SBASE BASE)
		   (swap CO OFFST))
          (\MOVEBYTES SBASE CO BASE OFFST N])
)
(DECLARE: DOEVAL@COMPILE DONTCOPY

(ADDTOVAR GLOBALVARS \BASEBYTESDEVICE)
)
(DECLARE: DONTEVAL@LOAD 
(\BASEBYTES.IO.INIT)

(MOVD? (QUOTE NILL)
       (QUOTE \CREATE.TTYDISPLAYSTREAM))
)
(DEFINEQ

(GETOFD
  [LAMBDA (FILE ACCESS)                                      (* lmm "20-APR-82 22:19")
                                                             (* OLD NAME)
    (\GETOFD FILE ACCESS])

(GETSTREAM
  [LAMBDA (FILE ACCESS)                                      (* lmm "20-APR-82 22:19")
                                                             (* USER ENTRY)
    (\GETOFD FILE ACCESS])

(\ADDOFD
  [LAMBDA (OFD)                                              (* rmk: "11-OCT-79 14:49")
                                                             (* Returns the OFD it adds to \OPENFILES)
    (\CLEAROFD)
    (CAR (push \OPENFILES OFD])

(\DELETEOFD
  [LAMBDA (OFD)                                              (* rmk: "25-OCT-79 08:20")
    (SETQ \OPENFILES (DREMOVE OFD \OPENFILES])

(\GETOFD
  [LAMBDA (X ACCESS NOERROR)                                 (* rrb "24-JUL-83 16:05")

          (* \GETOFD accepts either a: file name, a file handle, an OFD, a string, NIL, T, a DisplayStream, or a partial 
	  file name. -
	  ACCESS is INPUT, OUTPUT, APPEND, BOTH or NIL -
	  NOERROR, if non-NIL, means to return NIL if the file is not open in the specified access mode;
	  otherwise, an error is caused)


    (DECLARE (GLOBALVARS \OPENFILES \DEFAULTLINEBUF \DEFAULTTTYDISPLAYSTREAM))
    (COND
      ((NULL X)
	(SELECTQ ACCESS
		 (INPUT (COND
			  ((EQ \PRIMIN.OFD \DEFAULTLINEBUF)
			    (\CREATE.TTYDISPLAYSTREAM)))
			\PRIMIN.OFD)
		 (OUTPUT (COND
			   ((AND \DEFAULTTTYDISPLAYSTREAM (EQ \PRIMOUT.OFD (fetch \SFOFD
									      of 
									 \DEFAULTTTYDISPLAYSTREAM)))
                                                             (* this fetch will be removed as soon as displaystream 
							     are merged with streams.)
			     (\CREATE.TTYDISPLAYSTREAM)))
			 \PRIMOUT.OFD)
		 (\IOMODEP (COND
			     ((NOT (EQ \PRIMIN.OFD \LINEBUF.OFD))
			       \PRIMIN.OFD)
			     (T \PRIMOUT.OFD))
			   ACCESS NOERROR)))
      [(EQ X T)
	(SELECTQ ACCESS
		 (INPUT (COND
			  ((EQ \LINEBUF.OFD \DEFAULTLINEBUF)
			    (\CREATE.TTYDISPLAYSTREAM)))
			\LINEBUF.OFD)
		 ((OUTPUT NIL)
		   (COND
		     ((AND \DEFAULTTTYDISPLAYSTREAM (EQ \TERM.OFD (fetch \SFOFD of 
									 \DEFAULTTTYDISPLAYSTREAM)))
                                                             (* this fetch will be removed as soon as displaystream 
							     are merged with streams.)
		       (\CREATE.TTYDISPLAYSTREAM)))
		   \TERM.OFD)
		 (COND
		   (NOERROR NIL)
		   (T (LISPERROR "FILE NOT OPEN" T]
      ((type? STREAM X)
	(\IOMODEP X ACCESS NOERROR))
      [(LITATOM X)
	(OR (for STREAM in \OPENFILES when (EQ X (fetch FULLNAME of STREAM))
	       do (RETURN (\IOMODEP STREAM ACCESS NOERROR)))
	    (for STREAM (NAME ←(\GETFILENAME X (QUOTE OLD))) in \OPENFILES
	       when (EQ NAME (fetch FULLNAME of STREAM)) do (RETURN (\IOMODEP STREAM ACCESS NOERROR))
	       finally (OR NOERROR (LISPERROR "FILE NOT OPEN" X]
      ((STRINGP X)
	(\IOMODEP (\STRINGOFD X)
		  ACCESS NOERROR))
      ((\DISPLAYSTREAMP X)
	(\GetOFDFromDisplayStream X ACCESS NOERROR))
      ((type? WINDOW X)
	(\GetOFDFromDisplayStream (fetch (WINDOW DSP) of X)
				  ACCESS NOERROR))
      (NOERROR NIL)
      (T (LISPERROR "FILE NOT OPEN" X])

(\RESETOFDS
  [LAMBDA NIL                                                (* rrb "22-JUL-83 15:51")
    (DECLARE (GLOBALVARS \OPENFILES))
    [MAP.PROCESSES (FUNCTION (LAMBDA NIL
		       (\OPENLINEBUF)
		       (SETQ \PRIMOUT.OFD \TERM.OFD)
		       (SETQ \PRIMIN.OFD \LINEBUF.OFD)
		       (SETQ \DRIBBLE.OFD]
    (for OFD in \OPENFILES
       do (replace CPPTR of OFD with NIL)
	  (FORGETPAGES OFD)
	  (replace ACCESS of OFD with NIL))                  (* Perhaps do the AFTER function ?)
    (SETQ \OPENFILES])

(\CLEAROFD
  [LAMBDA NIL                                                (* lmm "30-SEP-80 20:08")
                                                             (* IF GETOFD CACHES ITS ARGS, THIS CAN CLEAR THE CACHE)
    ])
)

(RPAQ? \STRINGOFDS (CONS (HARRAY 12Q)))

(RPAQ? \OPENFILES )
(DECLARE: DOEVAL@COMPILE DONTCOPY

(ADDTOVAR GLOBALVARS \OPENFILES)
)
(DECLARE: DOEVAL@COMPILE DONTCOPY

(LOCALVARS . T)
)
(PUTPROPS AOFD COPYRIGHT ("Xerox Corporation" 3675Q 3676Q 3677Q))
(DECLARE: DONTCOPY
  (FILEMAP (NIL (2403Q 12070Q (CLOSEALL 2415Q . 3323Q) (CLOSEF 3325Q . 4663Q) (INPUT 4665Q . 5445Q) (
OPENP 5447Q . 6343Q) (OUTPUT 6345Q . 7166Q) (POSITION 7170Q . 10126Q) (RANDACCESSP 10130Q . 10625Q) (
\IOMODEP 10627Q . 12066Q)) (12071Q 25764Q (\STRINGOFD 12103Q . 20027Q) (\STRINGINIT 20031Q . 24576Q) (
\STRING.NAME.FROM.STREAM 24600Q . 25045Q) (\STRINGSETFILEPTR 25047Q . 25762Q)) (27530Q 44741Q (
\BASEBYTES.IO.INIT 27542Q . 36430Q) (\MAKEBASEBYTESTREAM 36432Q . 42277Q) (\BASEBYTES.NAME.FROM.STREAM
 42301Q . 42753Q) (\BASEBYTES.BLOCKIO 42755Q . 44737Q)) (45234Q 55464Q (GETOFD 45246Q . 45571Q) (
GETSTREAM 45573Q . 46123Q) (\ADDOFD 46125Q . 46540Q) (\DELETEOFD 46542Q . 46774Q) (\GETOFD 46776Q . 
54020Q) (\RESETOFDS 54022Q . 55107Q) (\CLEAROFD 55111Q . 55462Q)))))
STOP