(FILECREATED "16-AUG-83 13:08:33" {PHYLUM}<SYBALSKY>TEXTOFD.;147 86371        changes to:  (FNS \DELETECH OPENTEXTSTREAM TXTFILE \COPYTEXT \INSERTCH \INSERTCR \INSERTPIECE 			\SETUPGETCH \SPLITPIECE \TEXTCLOSEF \TEXTGETEOFPTR \TEXTGETFILEPTR \TEXTOPENF 			\TEXTOUTCHARFN \TEXTTTYBOUT \TEXTBOUT \TEXTSETFILEPTR PPCHAIN PRINTPIECE 			SEEPCTB SEETEXT SEETXT)		   (RECORDS TEXTOBJ)      previous date: " 9-AUG-83 11:22:19" {PHYLUM}<SYBALSKY>TEXTOFD.;145)(PRETTYCOMPRINT TEXTOFDCOMS)(RPAQQ TEXTOFDCOMS ((FNS * TEXTOFDFNS)		    (RECORDS PIECE TEXTOBJ)		    (P (ADDTOVAR GLOBALVARS \TEXTOFD \TEXTFDEV)		       (\TEXTINIT))		    (MACROS * TEXTOFDMACROS)		    [COMS (* Private data structures and constants)			  (DECLARE: EVAL@COMPILE DONTCOPY (CONSTANTS (\EditEOFChar# 1000000)								     (\PCTBFreePieces 0)								     (\PCTBLastPieceOffset 1)								     (\FirstPieceOffset 2)								     (\SecondPieceOffset 4)								     (\EltsPerPiece 2]		    (COMS (* Debugging functions)			  (FNS PPCHAIN PRINTPIECE SEEPCTB SEETEXT SEETXT))))(RPAQQ TEXTOFDFNS (OPENTEXTSTREAM TXTFILE \CHTOPC \CHTOPCNO \CLEARPCTB \COPYTEXT \CREATEPIECE 				  \DELETECH \DELETEPIECE \FINDPIECE \INSERTCH \INSERTCR \INSERTPIECE 				  \MAKEPCTB \SETUPGETCH \SPLITPIECE \TEXTCLOSEF \TEXTEOFP 				  \TEXTGETEOFPTR \TEXTGETFILEPTR \TEXTINIT \TEXTOPENF \TEXTOUTCHARFN 				  \TEXTPEEKBIN \TEXTTTYBOUT \TEXTBACKFILEPTR \TEXTBIN \TEXTBOUT 				  \TEXTSETEOF \TEXTSETFILEPTR))(DEFINEQ(OPENTEXTSTREAM  [LAMBDA (TEXT WINDOW START END PROPS)                      (* jds "14-JUL-83 14:22")                                                             (* Create a text-type STREAM to describe TEXT.							     Optionally, connect that to WINDOW for display.)    (PROG ((THISLINE (create THISLINE))	   [TEXTOBJ (COND		      ((AND (type? STREAM TEXT)			    (type? TEXTOBJ (fetch F3 of TEXT)))                                                             (* If the guy gave us a text stream to edit, use its 							     TEXTOBJ as ours.)			(create TEXTOBJ reusing (fetch F3 of TEXT)						\INSERTFIRSTCH _ -1 \INSERTNEXTCH _ -1))		      (T (create TEXTOBJ				 THISLINE _ NIL]	   FONT SEL PCTB PC TEXTSTREAM (TEDIT.GET.FINISHEDFORMS NIL))          (replace THISLINE of TEXTOBJ with THISLINE)          (replace \WINDOW of TEXTOBJ with WINDOW)           (* Necessary because some incoming object types depend 							     on knowing where the window is.)          [COND	    ((AND (type? STREAM TEXT)		  (type? TEXTOBJ (fetch F3 of TEXT)))        (* We got a TEXTOFD stream to edit;							     just use it)	      (SETQ TEXTSTREAM TEXT)	      (replace F3 of TEXTSTREAM with TEXTOBJ)	      (replace EDITFINISHEDFLG of TEXTOBJ with NIL)                                                             (* Mark the edit incomplete.)	      (replace \DIRTY of TEXTOBJ with NIL)           (* And mark it not changed.)	      )	    (T                                               (* Otherwise, create a TEXTOFD to describe the text 							     we're editing.-)	       [SETQ FONT (OR (LISTGET1 PROPS (QUOTE FONT))			      (AND WINDOW (CHARLOOKS.FROM.FONT (DSPFONT NIL WINDOW]	       (COND		 ((type? FONTDESCRIPTOR FONT)                (* He can pass in a FONT)		   (SETQ FONT (CHARLOOKS.FROM.FONT FONT)))		 ((type? CHARLOOKS FONT)                     (* Or a CHARLOOKS.)		   )		 (WINDOW                                     (* Anything else is illegal.)			 (\ILLEGAL.ARG FONT)))	       (SETQ PC (\CREATEPIECE TEXT FONT START END))	       (SETQ TEXTSTREAM (replace STREAMHINT of TEXTOBJ				   with (create STREAM using \TEXTOFD F3 _ TEXTOBJ)))	       [COND		 ((type? PIECE PC)		   (replace PCTB of TEXTOBJ with (SETQ PCTB (\MAKEPCTB)))		   (\INSERTPIECE PC (QUOTE LASTPIECE)				 TEXTOBJ))		 (T (replace PCTB of TEXTOBJ with (SETQ PCTB (TEDIT.BUILD.PCTB PC TEXTOBJ START END)))		    (SETQ PC (\EDITELT PCTB (ADD1 \FirstPieceOffset]	       (for FORM in TEDIT.GET.FINISHEDFORMS do (EVAL FORM))	       (COND		 ((fetch PFILE of PC)		   (replace TXTFILE of TEXTOBJ with (fetch PFILE of PC)))		 (T (replace TXTFILE of TEXTOBJ with TEXT)))	       (\TEXTSETEOF (fetch STREAMHINT of TEXTOBJ)			    (replace TEXTLEN of TEXTOBJ with (SUB1 (\EDITELT PCTB									     (SUB1 (\EDITELT PCTB 									     \PCTBLastPieceOffset]          (replace CARET of TEXTOBJ with (create CARET						 CARETDS _(AND WINDOW (WINDOWPROP WINDOW										  (QUOTE DSP)))						 FORCEUP _ T))          (replace DESC of THISLINE with NIL)          (replace LEN of THISLINE with 0)          (replace CHARS of THISLINE with (ARRAY 255 (QUOTE POINTER)						 0 0))          (replace WIDTHS of THISLINE with (ARRAY 255 (QUOTE SMALLP)						  0 0))          (replace LOOKS of THISLINE with (ARRAY 255 (QUOTE POINTER)						 0 0))          (replace TXTREADONLY of TEXTOBJ with (MEMB (QUOTE READONLY)						     PROPS))          (replace TXTTERMSA of TEXTOBJ with (LISTGET1 PROPS (QUOTE TERMSA)))          (COND	    (WINDOW                                          (* Only if there's a window to display it in:)		    (\TEDIT.WINDOW.SETUP WINDOW TEXTOBJ TEXTSTREAM THISLINE PROPS)                                                             (* Set up the window, and display the initial text.)		    ))          (RETURN TEXTSTREAM])(TXTFILE  [LAMBDA (TEXTOBJ)                                          (* jds "30-AUG-82 14:59")                                                             (* This function is for compiled access to the TXTFILE 							     field in RESETSAVE expressions)    (fetch TXTFILE of TEXTOBJ])(\CHTOPC  [LAMBDA (CH# PCTB)                                         (* jds "22-MAR-83 15:34")          (* Given a character # in a text object, and the object's piece table, return a pointer to the piece containing 	  that character, else NIL)    (DECLARE (LOCALVARS . T))    (PROG ((LPROBE (IDIFFERENCE \FirstPieceOffset 2))	   (PROBE (LOGAND (LRSH (IPLUS \FirstPieceOffset (SUB1 (\EDITELT PCTB \PCTBLastPieceOffset)))				1)			  65534))	   (HPROBE (ADD1 (\EDITELT PCTB \PCTBLastPieceOffset)))	   TRIALVALUE)          (SETQ TRIALVALUE (\EDITELT PCTB PROBE))            (* Initial trial value for the search)          (RETURN (do [COND			[(ILESSP TRIALVALUE CH#)             (* If we're below the target ch#, then move upward half 							     the remaining unsearched table)			  (COND			    ((IEQP (SETQ LPROBE PROBE)				   (SETQ PROBE (LOGAND (LRSH (IPLUS PROBE HPROBE)							     1)						       65534)))			      (RETURN (\EDITELT PCTB (ADD1 PROBE]			[(IGREATERP TRIALVALUE CH#)          (* If we're above the target ch#, move down half the 							     remaining distance)			  (COND			    ((IEQP (SETQ HPROBE PROBE)				   (SETQ PROBE (LOGAND (LRSH (IPLUS LPROBE PROBE)							     1)						       65534)))			      (RETURN (\EDITELT PCTB (ADD1 (IMAX PROBE \FirstPieceOffset]			(T                                   (* If we hit the target directly, this is us.)			   (RETURN (\EDITELT PCTB (ADD1 PROBE]		      (SETQ TRIALVALUE (\EDITELT PCTB PROBE])(\CHTOPCNO  [LAMBDA (CH# PCTB)                                         (* jds " 7-APR-83 15:30")          (* Given a character # in a text object, and the object's piece table, return a pointer to the piece containing 	  that character, else NIL)    (DECLARE (LOCALVARS . T))    (PROG ((ARRBASE (fetch (ARRAYP BASE) of PCTB))	   (LPROBE (LLSH (IDIFFERENCE \FirstPieceOffset 2)			 1))	   (PROBE (LOGAND (IPLUS \FirstPieceOffset (SUB1 (\EDITELT PCTB \PCTBLastPieceOffset)))			  65532))	   (HPROBE (LLSH (ADD1 (\EDITELT PCTB \PCTBLastPieceOffset))			 1))	   TRIALVALUE)          (SETQ TRIALVALUE (GETBASEPTR (\ADDBASE ARRBASE PROBE)				       0))                   (* Initial trial value for the search)          (RETURN (LRSH (do (COND			      [(ILESSP TRIALVALUE CH#)       (* If we're below the target ch#, then move upward half 							     the remaining unsearched table)				(COND				  ((IEQP (SETQ LPROBE PROBE)					 (SETQ PROBE (LOGAND (LRSH (IPLUS PROBE HPROBE)								   1)							     65532)))				    (RETURN PROBE]			      [(IGREATERP TRIALVALUE CH#)    (* If we're above the target ch#, move down half the 							     remaining distance)				(COND				  ((IEQP (SETQ HPROBE PROBE)					 (SETQ PROBE (LOGAND (LRSH (IPLUS LPROBE PROBE)								   1)							     65532)))				    (RETURN (IMAX PROBE \FirstPieceOffset]			      (T                             (* If we hit the target directly, this is us.)				 (RETURN PROBE)))			    (SETQ TRIALVALUE (GETBASEPTR (\ADDBASE ARRBASE PROBE)							 0)))			1])(\CLEARPCTB  [LAMBDA (PCTB)                                             (* jds "29-DEC-82 10:32")    (PROG ((OLASTPC (\EDITELT PCTB \PCTBLastPieceOffset)))          (\EDITSETA PCTB \FirstPieceOffset 1)               (* Create the LASTPIECE pseudo-piece placeholder in the 							     first piece of the table)          (\EDITSETA PCTB (ADD1 \FirstPieceOffset)		     (QUOTE LASTPIECE))          (for I from \SecondPieceOffset to OLASTPC	     do                                              (* Now remove the other pieces, setting them to NIL)		(\EDITSETA PCTB I NIL))          (\EDITSETA PCTB \PCTBLastPieceOffset (ADD1 \FirstPieceOffset))                                                             (* Fix up the last-piece pointer)          (\EDITSETA PCTB \PCTBFreePieces (IPLUS (\EDITELT PCTB \PCTBFreePieces)						 (LRSH (IDIFFERENCE OLASTPC (ADD1 \FirstPieceOffset))						       1)))                                                             (* And the free count of pieces.)          (RETURN PCTB])(\COPYTEXT  [LAMBDA (FROMOBJ TOOBJ FROMCH1 FROMCHLIM INSERTCH#)        (* jds " 3-AUG-83 19:04")                                                             (* Copy some text from FROM to TO, within the limits 							     specified, and to the insertion point given.)    (PROG ((TOPCTB (fetch PCTB of TOOBJ))	   (FROMPCTB (fetch PCTB of FROMOBJ))	   (TOTEXTLEN (fetch TEXTLEN of TOOBJ))	   (CROSSCOPY (NEQ FROMOBJ TOOBJ))	   PCLST INSPC INSPC# LEN PC NPC PCCH NPCCH OPLEN EVENT REPLACING)          [SETQ INSPC# (OR (\CHTOPCNO INSERTCH# TOPCTB)			   (SUB1 (\EDITELT TOPCTB \PCTBLastPieceOffset]                                                             (* Get a handle on the piece we're to insert within or 							     in front of)          (SETQ INSPC (\EDITELT TOPCTB (ADD1 INSPC#)))       (* And the piece, itself.)          (replace \INSERTNEXTCH of TOOBJ with -1)           (* Force later insertions to make new pieces.)          (replace \INSERTFIRSTCH of TOOBJ with -1)          [COND	    ((IGEQ INSERTCH# TOTEXTLEN)                      (* We're inserting at end of file;							     leave the piece to insert before as LASTPIECE)	      )	    ((IEQP INSERTCH# (\EDITELT TOPCTB INSPC#))       (* The insertion is IN FRONT of this piece;							     just continue on)	      )	    (T (SETQ INSPC (\SPLITPIECE INSPC INSERTCH# TOOBJ INSPC#))	       (SETQ INSPC# (ADD1 INSPC#]                    (* Nope, we're inserting INSIDE this piece.							     Split it in two.)          (SETQ PCLST (TCONC NIL))          [for I from \FirstPieceOffset to (IDIFFERENCE (\EDITELT FROMPCTB \PCTBLastPieceOffset)							\EltsPerPiece)	     by \EltsPerPiece	     do                                              (* Gather a list of pieces to be copied)		(SETQ PCCH (\EDITELT FROMPCTB I))            (* CH# for this piece)		(SETQ PC (\EDITELT FROMPCTB (ADD1 I)))       (* The piece itself)		(SETQ NPCCH (\EDITELT FROMPCTB (IPLUS I \EltsPerPiece)))                                                              (* Next piece's CH#)		(COND		  ((ILEQ NPCCH FROMCH1)                      (* The current piece isn't inside the region to be 							     copied.)		    )		  ((IGREATERP PCCH FROMCHLIM)                (* We've passed beyond the copy region.							     Bail out.)		    (RETURN))		  (T                                         (* This piece overlaps the copy-source region of the 							     document)		     (TCONC PCLST (SETQ NPC (create PIECE using PC)))                                                             (* Add it to the copy list.)		     [COND		       ((ILESSP PCCH FROMCH1)                (* The piece overlaps the bottom of the copy region: 							     Chop off its front part.)			 (SETQ OPLEN (fetch PLEN of NPC))			 (replace PLEN of NPC with (IDIFFERENCE (fetch PLEN of NPC)								(IDIFFERENCE FROMCH1 PCCH)))                                                             (* Shorten its length)			 (COND			   [(fetch PSTR of NPC)              (* Shorten the string that represents it.)			     (replace PSTR of NPC with (SUBSTRING (fetch PSTR of NPC)								  (ADD1 (IDIFFERENCE FROMCH1 PCCH]			   (                                 (* Or change the FILEPTR for its file)			     (replace PFPOS of NPC with (IPLUS (fetch PFPOS of NPC)							       (IDIFFERENCE FROMCH1 PCCH]		     (COND		       ((ILESSP FROMCHLIM NPCCH)             (* This piece overlaps the end of the copy region.							     Shorten it at the end.)			 [replace PLEN of NPC with (IDIFFERENCE (fetch PLEN of NPC)								(SUB1 (IDIFFERENCE NPCCH FROMCHLIM]                                                             (* By shortening its apparent length)			 (replace PPARALAST of NPC with NIL)                                                             (* We really did cut this piece off -- must mark it no 							     longer the end of a paragraph.)			 (RETURN]          (SETQ LEN 0)          (for PC in (CDAR PCLST)	     do                                              (* Now insert the copied pieces into the new place)		(COND		  ((AND CROSSCOPY (fetch PFILE of PC))          (* If this is a cross-document copy, and the text comes from a file, we must REALLY make a copy of the text, lest 	  the source file be deleted.)		    (replace PSTR of PC with (ALLOCSTRING (fetch PLEN of PC)))		    (SETFILEPTR (fetch PFILE of PC)				(fetch PFPOS of PC))		    [bind (BASE _(fetch (STRINGP BASE) of (fetch PSTR of PC)))			  (OFFST _(fetch (STRINGP OFFST) of (fetch PSTR of PC))) for I from 0		       to (SUB1 (fetch PLEN of PC)) do (PUTBASEBYTE BASE (IPLUS OFFST I)								    (\BIN (fetch PFILE of PC]		    (replace PFILE of PC with NIL)))		(\INSERTPIECE PC INSPC TOOBJ)                (* Insert the piece into the new document)		(add LEN (fetch PLEN of PC)))          (SETQ EVENT (CAR TEDIT.HISTORYLST))          [SETQ REPLACING (AND (EQ (fetch THACTION of EVENT)				   (QUOTE Delete))			       (IEQP INSERTCH# (fetch THCH# of EVENT]          (\TEDIT.HISTORYADD (create TEDITHISTORYEVENT				     THACTION _(COND				       (REPLACING (QUOTE Replace))				       (T (QUOTE Copy)))				     THLEN _ LEN				     THCH# _ INSERTCH#				     THFIRSTPIECE _(CADAR PCLST)				     THTEXTOBJ _ TOOBJ				     THOLDINFO _(AND REPLACING EVENT)))                                                             (* Make a history-list entry for the COPY.)          (replace \DIRTY of TOOBJ with T)                   (* Mark the document changed)          (\TEXTSETEOF (fetch STREAMHINT of TOOBJ)		       (replace TEXTLEN of TOOBJ with (IPLUS LEN TOTEXTLEN)))                                                             (* Set the new length)          (RETURN LEN])(\CREATEPIECE  [LAMBDA (STRING LOOKS START END)                           (* jds "18-JUL-83 15:53")                                                             (* Given a source for text, build a PIECE to describe 							     it.)                                                             (* HOWEVER-- if it's aformatted file, return the stream 							     for that file.)    (PROG (PC)          [SETQ PC (COND	      ((STRINGP STRING)                              (* It's a string.)		(create PIECE			PSTR _ STRING			PFILE _ NIL			PLEN _(NCHARS STRING)))	      ((NULL STRING)                                 (* If it's NIL, use an empty string for the text.)		(create PIECE			PSTR _ ""			PFILE _ NIL			PLEN _ 0))	      [(ATOM STRING)                                 (* An atom is a file name. Open it.)		(SETQ STRING (\GETOFD (OPENFILE STRING (QUOTE INPUT)						(QUOTE OLD))				      (QUOTE INPUT)))		(AND (\TEDIT.FORMATTEDP1 STRING END)		     (RETURN STRING))		(create PIECE			PSTR _ NIL			PFILE _ STRING			PFPOS _(OR START 0)			PLEN _(COND			  (END (IDIFFERENCE END (OR START 0)))			  (T (GETFILEINFO (fetch FULLFILENAME of STRING)					  (QUOTE LENGTH]	      [(type? STREAM STRING)                         (* It's a stream, so it's already open.)		(AND (\TEDIT.FORMATTEDP1 STRING END)		     (RETURN STRING))		(create PIECE			PSTR _ NIL			PFILE _ STRING			PFPOS _(OR START 0)			PLEN _(COND			  (END (IDIFFERENCE END (OR START 0)))			  (T (GETFILEINFO (fetch FULLFILENAME of STRING)					  (QUOTE LENGTH]	      ((type? PIECE STRING)		STRING)	      (T                                             (* Anything else is coerced to a string first.)		 (SETQ STRING (MKSTRING STRING))		 (create PIECE			 PSTR _ STRING			 PFILE _ NIL			 PLEN _(NCHARS STRING]          (replace PLOOKS of PC with (OR LOOKS (CHARLOOKS.FROM.FONT TEDIT.DEFAULT.FONT)))          (RETURN PC])(\DELETECH  [LAMBDA (CH# CHLIM LEN TEXTOBJ)                            (* jds "21-JUL-83 13:19")                                                             (* Delete the indicated characters from the text object 							     represented by TEXTOBJ)    (PROG ((\INFIRSTCH (fetch \INSERTFIRSTCH of TEXTOBJ))	   (TEXTLEN (fetch TEXTLEN of TEXTOBJ))	   (PCTB (fetch PCTB of TEXTOBJ)))          [COND	    [(AND (IEQP CHLIM (SUB1 (fetch \INSERTNEXTCH of TEXTOBJ)))		  (IGEQ CH# \INFIRSTCH))                     (* The deletion is from the end of the most recent 							     type-in. Just adjust the buffer string.)	      (freplace \INSERTLEN of TEXTOBJ with (replace PLEN of (fetch \INSERTPC of TEXTOBJ)						      with (IDIFFERENCE CH# \INFIRSTCH)))                                                             (* Cut back the length)	      (freplace \INSERTNEXTCH of TEXTOBJ with (IPLUS (fetch \INSERTLEN of TEXTOBJ)							     \INFIRSTCH))                                                             (* and ch# of next insertion 							     (i.e., 1 past the top CH# in the insert piece.))	      (replace THLEN of (CAR TEDIT.HISTORYLST) with (IDIFFERENCE (fetch THLEN									    of (CAR TEDIT.HISTORYLST))									 LEN))                                                             (* Reduce the length of the insertion in the history 							     list, too.)	      (for I from (IPLUS \EltsPerPiece (\CHTOPCNO CH# PCTB)) to (\EDITELT PCTB 									     \PCTBLastPieceOffset)		 by \EltsPerPiece		 do (\EDITSETA PCTB I (IDIFFERENCE (\EDITELT PCTB I)						   LEN))     (* Adjust CH#s in the Piece Table.)		    )	      (COND		((ZEROP (fetch \INSERTLEN of TEXTOBJ))       (* He's completely emptied the type-in piece.							     Remove it and force creation of a fresh one at next 							     type-in.)		  (\DELETEPIECE (fetch \INSERTPC of TEXTOBJ)				PCTB)		  (freplace \INSERTNEXTCH of TEXTOBJ with -1]	    ((ILEQ CH# TEXTLEN)                              (* General case of deletion: Remove pieces as needed to 							     do it.)	      (PROG ((PCNO1 (\CHTOPCNO CH# PCTB))		     PCN PC1 PCNON PCSOUT (HIPC NIL)		     HI LO)		    (SETQ PC1 (\EDITELT PCTB (ADD1 PCNO1)))                                                             (* Piece # of piece containing start of deleted text)		    (COND		      ((IGREATERP CH# (\EDITELT PCTB PCNO1))                                                             (* Split the piece, so the deleted text now starts on a 							     piece boundary)			(\SPLITPIECE PC1 CH# TEXTOBJ PCNO1)			(SETQ PCTB (fetch PCTB of TEXTOBJ))			(SETQ PCNO1 (IPLUS PCNO1 \EltsPerPiece))                                                             (* Remember the PCNO1 of the first piece to be deleted.)			)		      (T (SETQ PC1 (fetch PREVPIECE of PC1))                                                             (* PC1 _ piece before the first piee to be deleted.-)			 ))		    (\TEDIT.HISTORYADD (create TEDITHISTORYEVENT					       THACTION _(QUOTE Delete)					       THLEN _ LEN					       THCH# _ CH#					       THFIRSTPIECE _[COND						 (PC1 (fetch NEXTPIECE of PC1))						 (T (\EDITELT PCTB (ADD1 \FirstPieceOffset]					       THTEXTOBJ _ TEXTOBJ))                                                             (* Add this event to the history list)		    [COND		      [(ILESSP CHLIM TEXTLEN)			(SETQ PCNON (\CHTOPCNO (ADD1 CHLIM)					       PCTB))        (* Find the peice that contains the END of the deleted 							     section)			(SETQ PCN (\EDITELT PCTB (ADD1 PCNON]		      (T (SETQ PCNON (SUB1 (\EDITELT PCTB \PCTBLastPieceOffset)))			 (SETQ PCN (QUOTE LASTPIECE]		    [COND		      ((ATOM PCN)                            (* Deleting before the end of text.)			)		      (T                                     (* Deleting in front of a real piece of text)			 (COND			   ((IGREATERP (ADD1 CHLIM)				       (\EDITELT PCTB PCNON))			     (SETQ HIPC (\SPLITPIECE PCN (ADD1 CHLIM)						     TEXTOBJ PCNON))			     (SETQ PCNON (IPLUS PCNON \EltsPerPiece))			     (SETQ PCTB (fetch PCTB of TEXTOBJ)))			   (T (SETQ HIPC PCN]                (* if not on a piece bound, split the last piece.)		    (bind [PC _(COND				(PC1 (fetch NEXTPIECE of PC1))				(T (\EDITELT PCTB (ADD1 \FirstPieceOffset]		       while (AND PC (NEQ PC HIPC))		       do (AND (fetch POBJ of PC)			       (fetch DELETEFN of (fetch OBJREF of (fetch POBJ of PC)))			       (APPLY* (fetch DELETEFN of (fetch OBJREF of (fetch POBJ of PC)))				       (fetch POBJ of PC)				       (fetch STREAMHINT of TEXTOBJ)				       PC))			  (SETQ PC (fetch NEXTPIECE of PC)))		    (SETQ LO PCNO1)                          (* Find the first piece to be deleted in the PCTB.)		    (SETQ HI PCNON)                          (* Counter for next after last piece to delete.)		    (SETQ PCSOUT (LRSH (IDIFFERENCE HI LO)				       1))                   (* # of pieces to delete)		    (for I from HI to (\EDITELT PCTB \PCTBLastPieceOffset) as J from LO		       do                                    (* Move top of table down over the freed-up pieces.)			  (\EDITSETA PCTB J (\EDITELT PCTB I)))		    (\EDITSETA PCTB \PCTBFreePieces (IPLUS (\EDITELT PCTB \PCTBFreePieces)							   PCSOUT))                                                             (* Adjust the free piece count in PCTB)		    (\EDITSETA PCTB \PCTBLastPieceOffset (IDIFFERENCE (\EDITELT PCTB 									     \PCTBLastPieceOffset)								      (IDIFFERENCE HI LO)))                                                             (* Adjust the offset pointer to the final active piece.)		    (for I from LO to (\EDITELT PCTB \PCTBLastPieceOffset) by \EltsPerPiece		       do                                    (* Adjust the CH#s of the undeleted pieces.)			  (\EDITSETA PCTB I (IDIFFERENCE (\EDITELT PCTB I)							 LEN)))		    (COND		      (PC1 (replace NEXTPIECE of PC1 with HIPC)))		    (COND		      (HIPC (replace PREVPIECE of HIPC with PC1)))		    (replace \INSERTNEXTCH of TEXTOBJ with -1]          (\TEXTSETEOF (fetch STREAMHINT of TEXTOBJ)		       (freplace TEXTLEN of TEXTOBJ with (IDIFFERENCE TEXTLEN LEN)))                                                             (* Update the file's length)          (replace \DIRTY of TEXTOBJ with T])(\DELETEPIECE  [LAMBDA (PC PCTB)                                          (* jds "28-JAN-83 09:30")                                                             (* Remove piece PC from the piece table PCTB.							     Adjust the character numbers of succeeding pieces, if 							     need be.)    (PROG ((PCNO (\FINDPIECE PC PCTB))	   [PCLEN (COND		    ((ATOM PC)		      0)		    (T (fetch PLEN of PC]	   (PCLIM (\EDITELT PCTB \PCTBLastPieceOffset)))          (COND	    (PCNO (bind LOBASE HIBASE for HI from (IPLUS PCNO \EltsPerPiece) by \EltsPerPiece		     to PCLIM as LO from PCNO by \EltsPerPiece		     do (\RPLPTR (SETQ LOBASE (\ADDBASE2 (fetch (ARRAYP BASE) of PCTB)							 LO))				 2				 (GETBASEPTR (SETQ HIBASE (\ADDBASE2 (fetch (ARRAYP BASE)									of PCTB)								     HI))					     2))			(\RPLPTR LOBASE 0 (IDIFFERENCE (GETBASEPTR HIBASE 0)						       PCLEN))                                                             (* Move the table down over the deleted piece.)			)		  (\EDITSETA PCTB \PCTBLastPieceOffset (IDIFFERENCE PCLIM \EltsPerPiece))                                                             (* Adjust the end-of-table pointer)		  (\EDITSETA PCTB \PCTBFreePieces (ADD1 (\EDITELT PCTB \PCTBFreePieces)))                                                             (* and the free-pieces count.)		  ))          [COND	    ((fetch NEXTPIECE of PC)	      (replace PREVPIECE of (fetch NEXTPIECE of PC) with (fetch PREVPIECE of PC]                                                             (* Break any forward link from the piece)          [COND	    ((fetch PREVPIECE of PC)	      (replace NEXTPIECE of (fetch PREVPIECE of PC) with (fetch NEXTPIECE of PC]                                                             (* and any backward link.)      ])(\FINDPIECE  [LAMBDA (PC PCTB)                                          (* jds " 3-MAY-82 10:58")                                                             (* Given a piece and the pctb it's in, return the elt # 							     of the CH# entry for that piece in the table)    (COND      [(for I from (ADD1 \FirstPieceOffset) to (\EDITELT PCTB \PCTBLastPieceOffset) by \EltsPerPiece	  do (COND	       ((EQ PC (\EDITELT PCTB I))		 (RETURN (SUB1 I]      (T (ERROR "Piece not found:  " PC])(\INSERTCH  [LAMBDA (CH CH# TEXTOBJ)                                   (* jds "21-JUL-83 13:22")          (* If the current ch is 1+last ch in the distinguished INPUTPIECE, then append this text to that piece 	  (make a new one if need be.), and fix up ch#s in the PCTB)          (* else, create a new input piece (as a substring of the old one) and INSERT it at the right spot, perhaps after 	  splitting a piece to make room.)    (PROG (PC (LEN (COND		     ((type? STRINGP CH)		       (NCHARS CH))		     (T 1)))	      (PCNO NIL)	      CHNO NEWPC PREVPC EVENT REPLACING (NEWFLAG NIL)	      (\INEXTCH (fetch \INSERTNEXTCH of TEXTOBJ))	      (\INLEN (fetch \INSERTLEN of TEXTOBJ))	      (\INLEFT (fetch \INSERTLEFT of TEXTOBJ))	      (\INSTRING (fetch \INSERTSTRING of TEXTOBJ))	      (\INPC (fetch \INSERTPC of TEXTOBJ))	      (\INFIRSTCH (fetch \INSERTFIRSTCH of TEXTOBJ))	      (PCTB (ffetch PCTB of TEXTOBJ))	      (TEXTLEN (fetch TEXTLEN of TEXTOBJ)))          [COND	    ((IEQP CH# \INEXTCH)                             (* We're inserting at the end of a previous insertion, 							     for which we already have a piece built.							     Just add to it.)	      (COND		((IGEQ \INLEFT LEN)                          (* There's enough room in this piece -- fill it in.)		  (COND		    ((type? STRINGP CH)                      (* If input is a string, copy it to the insert piece's 							     string)		      (RPLSTRING \INSTRING (ADD1 \INLEN)				 CH))		    (T                                       (* If it's a single charcode, move it to the piece's 							     string)		       (RPLCHARCODE \INSTRING (ADD1 \INLEN)				    CH)))		  (replace PLEN of \INPC with (freplace \INSERTLEN of TEXTOBJ						 with (IPLUS \INLEN LEN)))                                                             (* Fix the length of the insert piece)		  (freplace \INSERTLEFT of TEXTOBJ with (IDIFFERENCE \INLEFT LEN))                                                             (* And the space left in the piece)		  (freplace \INSERTNEXTCH of TEXTOBJ with (IPLUS \INEXTCH LEN))                                                             (* And the next CH#)		  (SETQ PCNO (fetch \INSERTPCNO of TEXTOBJ))                                                             (* And the piece # for future use)		  )		(T                                           (* No room. Chop this piece & start a new one.)		   (replace PSTR of \INPC with (SUBSTRING \INSTRING 1 \INLEN))                                                             (* Chop the current piece's string to length)		   (SETQ NEWPC (create PIECE				       PSTR _(ALLOCSTRING 512 (QUOTE % ))				       PLOOKS _(fetch PLOOKS of \INPC)				       PPARALOOKS _(fetch PPARALOOKS of \INPC)				       PPARALAST _ NIL))     (* Create the new piece)		   (freplace \INSERTSTRING of TEXTOBJ with (SETQ \INSTRING (fetch PSTR of NEWPC)))                                                             (* Set the \INSTRING field in TEXTOBJ)		   (COND		     ((type? STRINGP CH)                     (* If input is a string, copy it to the insert piece's 							     string)		       (RPLSTRING \INSTRING 1 CH))		     (T                                      (* If it's a single charcode, move it to the piece's 							     string)			(RPLCHARCODE \INSTRING 1 CH)))		   (replace PLEN of NEWPC with LEN)          (* So far, the present input is the only thing in the 							     piece)		   (replace \INSERTPCNO of TEXTOBJ with (\INSERTPIECE NEWPC								      (OR (fetch NEXTPIECE									     of \INPC)									  (QUOTE LASTPIECE))								      TEXTOBJ))                                                             (* Insert the new piece into the text and save the piece							     #)		   (SETQ PCTB (fetch PCTB of TEXTOBJ))       (* Which may have caused a PCTB overflow)		   (freplace \INSERTPC of TEXTOBJ with (SETQ \INPC NEWPC))		   (freplace \INSERTLEFT of TEXTOBJ with (IDIFFERENCE 512 LEN))		   (freplace \INSERTLEN of TEXTOBJ with LEN)		   (replace \INSERTFIRSTCH of TEXTOBJ with CH#)                                                             (* CH# of the first inserted character)		   (replace \INSERTNEXTCH of TEXTOBJ with (IPLUS CH# LEN))                                                             (* The CH# of the next character, if it's inserted at 							     the current caret.)		   (SETQ NEWFLAG T)                          (* Note the new piece's creation)		   ))	      (add (fetch THLEN of (CAR TEDIT.HISTORYLST))		   LEN)                                      (* Update the length of the insertion/replacement text.)	      )	    (T           (* NEW INSERTION POINT; IF THERE'S ANYTHING LEFT OF THE PREVIOUS INSERT PIECE, CRACK OFF A NEW ONE & FILL IT.	  THEN FIGURE OUT WHERE TO SHOEHORN IT IN.)	       (SETQ PCNO (\CHTOPCNO CH# PCTB))	       (SETQ PC (\EDITELT PCTB (ADD1 PCNO)))	       [COND		 ((AND \INPC (IGEQ \INLEFT LEN))             (* There's room left in the prior input-piece's string;							     re-use it.)		   (SETQ NEWPC (create PIECE				       PSTR _(SUBSTRING \INSTRING (ADD1 \INLEN))				       PLOOKS _(\TEDIT.GET.INSERT.CHARLOOKS \INPC)				       PPARALOOKS _(OR (AND \INPC (fetch PPARALOOKS of \INPC))						       (create FMTSPEC copying (fetch FMTSPEC										  of TEXTOBJ)))				       PPARALAST _ NIL))     (* Build the new piece)		   (replace PSTR of \INPC with (SUBSTRING \INSTRING 1 \INLEN))		   (replace PLEN of NEWPC with LEN)		   (freplace \INSERTLEFT of TEXTOBJ with (IDIFFERENCE \INLEFT LEN))		   (freplace \INSERTSTRING of TEXTOBJ with (SETQ \INSTRING (fetch PSTR of NEWPC)))		   (freplace \INSERTPC of TEXTOBJ with (SETQ \INPC NEWPC))		   (COND		     ((type? STRINGP CH)                     (* Insert the characters into the piece)		       (RPLSTRING \INSTRING 1 CH))		     (T (RPLCHARCODE \INSTRING 1 CH)))		   (freplace \INSERTLEN of TEXTOBJ with LEN))		 (T                                          (* No room left; build a whole new piece.)		    (SETQ NEWPC (create PIECE					PSTR _(freplace \INSERTSTRING of TEXTOBJ						 with (SETQ \INSTRING (ALLOCSTRING 512)))					PLOOKS _(\TEDIT.GET.INSERT.CHARLOOKS \INPC)					PPARALOOKS _(OR (AND \INPC (fetch PPARALOOKS of \INPC))							(create FMTSPEC copying (fetch FMTSPEC										   of TEXTOBJ)))					PPARALAST _ NIL))		    (replace PLEN of NEWPC with LEN)		    (COND		      ((type? STRINGP CH)                    (* Insert the characters into the piece)			(RPLSTRING \INSTRING 1 CH))		      (T (RPLCHARCODE \INSTRING 1 CH)))		    (freplace \INSERTPC of TEXTOBJ with (SETQ \INPC NEWPC))		    (freplace \INSERTLEN of TEXTOBJ with LEN)		    (freplace \INSERTLEFT of TEXTOBJ with (IDIFFERENCE 512 LEN]	       (freplace \INSERTFIRSTCH of TEXTOBJ with CH#)                                                             (* Cache the first-inserted-ch #, for backspace speed)	       (SETQ NEWFLAG T)	       [COND		 ((OR (IGREATERP CH# TEXTLEN)		      (IEQP CH# (\EDITELT PCTB PCNO)))       (* We're inserting on a piece boundary;							     do it, then remember the prior piece.)		   (SETQ PCNO (\INSERTPIECE \INPC PC TEXTOBJ)))		 (T                                          (* Not on a piece boundary; split the piece we're inside							     of, then insert.)		    (SETQ PCNO (\INSERTPIECE \INPC (\SPLITPIECE PC CH# TEXTOBJ)					     TEXTOBJ]	       (replace \INSERTPCNO of TEXTOBJ with PCNO)    (* Save the pcno for future insertions)	       (SETQ PCTB (fetch PCTB of TEXTOBJ))           (* The PCTB may have expanded during the insert.)	       (SETQ PREVPC (OR (fetch PREVPIECE of NEWPC)				PC))                         (* The piece we're to take the inserted characters' 							     looks from)	       [replace INSERTFONT of TEXTOBJ		  with (replace PLOOKS of NEWPC			  with (COND				 ((ZEROP TEXTLEN)            (* If there are no characters, use the default font to 							     build a set of looks)				   (CHARLOOKS.FROM.FONT TEDIT.DEFAULT.FONT))				 (T                          (* Otherwise try to use the looks from the selected 							     characters)				    (SELECTQ (fetch POINT of (fetch SEL of TEXTOBJ))					     (LEFT (SETQ PREVPC (OR (fetch NEXTPIECE of NEWPC)								    PREVPC)))					     NIL)				    (\TEDIT.GET.INSERT.CHARLOOKS PREVPC]	       [replace PPARALOOKS of NEWPC with (COND						   ((ZEROP TEXTLEN)                                                             (* No text yet; use default paralooks)						     (create FMTSPEC copying TEDIT.DEFAULT.FMTSPEC))						   ((SETQ PREVPC (fetch NEXTPIECE of \INPC))                                                             (* There's later text. Use its para looks)						     (fetch PPARALOOKS of PREVPC))						   ((SETQ PREVPC (fetch PREVPIECE of \INPC))                                                             (* There's earlier text. Use its looks, copied if need 							     be.)						     (COND						       ((fetch PPARALAST of PREVPC)							 (create FMTSPEC							    copying (fetch PPARALOOKS of PREVPC)))						       (T (fetch PPARALOOKS of PREVPC]	       (SETQ EVENT (CAR TEDIT.HISTORYLST))           (* Prior edit event.)	       [SETQ REPLACING (AND (EQ (fetch THACTION of EVENT)					(QUOTE Delete))				    (IEQP CH# (fetch THCH# of EVENT]	       (\TEDIT.HISTORYADD (create TEDITHISTORYEVENT					  THACTION _(COND					    (REPLACING (QUOTE Replace))					    (T (QUOTE Insert)))					  THLEN _(fetch PLEN of \INPC)					  THCH# _ CH#					  THFIRSTPIECE _ \INPC					  THPOINT _(QUOTE RIGHT)					  THTEXTOBJ _ TEXTOBJ					  THOLDINFO _(AND REPLACING EVENT]          [OR NEWFLAG (PROGN                                 (* We didn't add a piece, so we must update character 							     numbers in the PCTB)			     (OR PCNO (SETQ PCNO (\CHTOPCNO (SUB1 CH#)							    PCTB)))                                                             (* The insert-piece's PCTB entry)			     (for I from (IPLUS PCNO \EltsPerPiece) to (\EDITELT PCTB 									     \PCTBLastPieceOffset)				by \EltsPerPiece do (\EDITSETA PCTB I (IPLUS (\EDITELT PCTB I)									     LEN]          [\TEXTSETEOF (fetch STREAMHINT of TEXTOBJ)		       (freplace TEXTLEN of TEXTOBJ with (SETQ TEXTLEN (IPLUS LEN TEXTLEN]          (replace \INSERTNEXTCH of TEXTOBJ with (IPLUS CH# LEN))          (replace \DIRTY of TEXTOBJ with T])(\INSERTCR  [LAMBDA (CH CH# TEXTOBJ)                                   (* jds "20-APR-83 13:24")                                                             (* Handle inserting a CR when we need to do para 							     formatting.)    (PROG (INPC)          (\INSERTCH CH CH# TEXTOBJ)                         (* Put the CR in)          (SETQ INPC (fetch \INSERTPC of TEXTOBJ))          (replace PPARALAST of INPC with T)                 (* Mark the end of the paragraph)          (replace \INSERTNEXTCH of TEXTOBJ with -1)         (* FORCE A NEW PIECE ON THE NEXT CHARACTER)      ])(\INSERTPIECE  [LAMBDA (NEW OLD TEXTOBJ DONTUPDATECH#S)                   (* jds " 3-AUG-83 19:07")                                                             (* Insert the piece NEW in front of the piece OLD;							     re-allocate PCTB if need be)    (PROG (PCNO OLIM (PLEN (fetch PLEN of NEW))		(PCTB (fetch PCTB of TEXTOBJ))		NPCTB)          (SETQ PCNO (\FINDPIECE OLD PCTB))                  (* Where in the pctb to look)          (SETQ OLIM (\EDITELT PCTB \PCTBLastPieceOffset))          (COND	    ((ILESSP PLEN 0)                                 (* This piece has a negative length.							     Bitch.)	      (ERROR "Negative Piece Length" NEW))	    [(EQ OLD (QUOTE LASTPIECE))                      (* We're inserting in front of the LASTPIECE.							     Try setting the NEXTPIECE link of the next earlier 							     piece, if there's one.)	      (replace NEXTPIECE of NEW with NIL)	      (replace PREVPIECE of NEW with NIL)	      (COND		((IGREATERP PCNO 3)		  (SETQ OLD (\EDITELT PCTB (SUB1 PCNO)))		  (replace NEXTPIECE of OLD with NEW)		  (replace PREVPIECE of NEW with OLD]	    (T (replace NEXTPIECE of NEW with OLD)	       (replace PREVPIECE of NEW with (fetch PREVPIECE of OLD))	       (COND		 ((fetch PREVPIECE of OLD)		   (replace NEXTPIECE of (fetch PREVPIECE of OLD) with NEW)))	       (replace PREVPIECE of OLD with NEW)))          [COND	    ((IEQP PCNO \FirstPieceOffset)	      (replace PREVPIECE of NEW with NIL))	    (T (replace PREVPIECE of NEW with (\EDITELT PCTB (SUB1 PCNO]          [COND	    ((ZEROP (\EDITELT PCTB \PCTBFreePieces))         (* Must allocate a new, larger table & copy the old 							     table's contents)	      (SETQ NPCTB (ARRAY (IPLUS (ARRAYSIZE PCTB)					32)				 (QUOTE POINTER)				 NIL 0))	      (for I from 0 to (SUB1 (ARRAYSIZE PCTB)) do (\EDITSETA NPCTB I (\EDITELT PCTB I)))	      (\EDITSETA NPCTB \PCTBFreePieces 16)	      (freplace PCTB of TEXTOBJ with (SETQ PCTB NPCTB]          (for I from OLIM to PCNO by -1 as J from (IPLUS OLIM \EltsPerPiece)	     to (IPLUS PCNO \EltsPerPiece) by -1 do (\EDITSETA PCTB J (\EDITELT PCTB I)))          (\EDITSETA PCTB (ADD1 PCNO)		     NEW)          (\EDITSETA PCTB \PCTBLastPieceOffset (IPLUS OLIM \EltsPerPiece))          (\EDITSETA PCTB \PCTBFreePieces (SUB1 (\EDITELT PCTB \PCTBFreePieces)))          [OR DONTUPDATECH#S (for I from (IPLUS PCNO \EltsPerPiece) to (IPLUS OLIM \EltsPerPiece)				by \EltsPerPiece do (\EDITSETA PCTB I (IPLUS (\EDITELT PCTB I)									     PLEN]          (RETURN PCNO])(\MAKEPCTB  [LAMBDA (PC1 MINLEN)                                       (* jds "13-JUL-83 15:12")          (* Create a new piece table, with PC1 as its first piece, and a dummy piece at the end, with 1st ch# of 1+ 	  (chlim of pc1))          (* A piece Table has the following format: It's an array, with 2 header words (1_# of pieces left in table unused)	  (2_offset of last used word in tbl), followed by 2-word entries: the first ch# in the piece, and a pointer to the 	  piece.)    (PROG (PCTB [LEN (IPLUS 4 (ITIMES \EltsPerPiece (OR MINLEN 14]		(FREE (OR MINLEN 14)))          (SETQ PCTB (ARRAY LEN (QUOTE POINTER)			    NIL 0))          (COND	    ((NOT PC1)	      (\EDITSETA PCTB \PCTBFreePieces FREE)	      (\EDITSETA PCTB \PCTBLastPieceOffset 3)	      (\EDITSETA PCTB \FirstPieceOffset 1)	      (\EDITSETA PCTB (ADD1 \FirstPieceOffset)			 (QUOTE LASTPIECE))	      (RETURN PCTB))	    (T (\EDITSETA PCTB \PCTBFreePieces (SUB1 FREE))	       (\EDITSETA PCTB \PCTBLastPieceOffset 5)	       (\EDITSETA PCTB \FirstPieceOffset 1)	       (\EDITSETA PCTB (ADD1 \FirstPieceOffset)			  PC1)	       (\EDITSETA PCTB \SecondPieceOffset (ADD1 (fetch PLEN of PC1)))	       (\EDITSETA PCTB (ADD1 \SecondPieceOffset)			  (QUOTE LASTPIECE))	       (RETURN PCTB])(\SETUPGETCH  [LAMBDA (CH# TEXTOBJ)                                      (* jds "21-JUL-83 13:27")                                                             (* Set up TEXTOBJ so that the next \GETCH will retrieve 							     character # CH#)                                                             (* NB that 1st char in the textobj is #1.)    (DECLARE (LOCALVARS . T))    (PROG (PC PCNO PS PF CHOFFSET CHARSLEFT (PCTB (fetch PCTB of TEXTOBJ))	      (STREAM (fetch STREAMHINT of TEXTOBJ)))          (COND	    ((ILEQ CH# (fetch TEXTLEN of TEXTOBJ))	      (SETQ PCNO (\CHTOPCNO CH# PCTB))	      (SETQ PC (\EDITELT PCTB (ADD1 PCNO)))	      (SETQ CHOFFSET (IDIFFERENCE CH# (\EDITELT PCTB PCNO)))	      (SETQ CHARSLEFT (IDIFFERENCE (fetch PLEN of PC)					   CHOFFSET))	      (COND		((SETQ PS (fetch PSTR of PC))                (* This piece resides in a STRING.)		  (replace CPPTR of STREAM with (OR (ADDBASE (fetch (STRINGP BASE) of PS)							     (LRSH (fetch (STRINGP OFFST)								      of PS)								   1))						    (PROGN 0)))		  (replace CPAGE of STREAM with 0)		  (replace COFFSET of STREAM with (IPLUS (LOGAND 1 (fetch (STRINGP OFFST)								      of PS))							 CHOFFSET))		  (replace FW6 of STREAM with 0)             (* Page # within the "file" where this piece starts)		  (replace FW7 of STREAM with (LOGAND 1 (fetch (STRINGP OFFST) of PS)))                                                             (* Char within "page" where the piece starts 							     (for BACKFILEPTR))		  (replace CBUFSIZE of STREAM with (IPLUS CHARSLEFT (fetch COFFSET of STREAM)))		  (replace EPAGE of STREAM with 1)		  (replace EOFFSET of STREAM with CHARSLEFT)		  (replace F2 of STREAM with 0)		  (replace F1 of STREAM with NIL))		((SETQ PF (fetch PFILE of PC))               (* This piece resides on a FILE)		  [COND		    ((IEQP (fetch ACCESSBITS of PF)			   NoBits)                           (* ASSURE THAT THE FILE IS OPEN)		      (replace PFILE of PC with (SETQ PF (\GETOFD (OPENFILE (fetch FULLNAME									       of PF)									    (QUOTE INPUT))								  (QUOTE INPUT]		  (replace FW6 of STREAM with (fetch (BYTEPTR PAGE) of (fetch PFPOS of PC)))                                                             (* Page within the file where the piece starts)		  (replace FW7 of STREAM with (fetch (BYTEPTR OFFSET) of (fetch PFPOS of PC)))                                                             (* Char within the page where it starts.)		  (SETFILEPTR PF (IPLUS (fetch PFPOS of PC)					CHOFFSET))		  (\PAGEDPEEKBIN PF)		  (replace CPPTR of STREAM with (fetch CPPTR of PF))		  (replace CPAGE of STREAM with (fetch CPAGE of PF))		  (replace COFFSET of STREAM with (fetch COFFSET of PF))		  (replace EPAGE of STREAM with 32767)		  (replace EOFFSET of STREAM with (fetch EOFFSET of PF))		  (replace CBUFSIZE of STREAM with (IMIN (fetch CBUFSIZE of PF)							 (IPLUS (fetch COFFSET of PF)								CHARSLEFT)))		  [replace F2 of STREAM with (IDIFFERENCE CHARSLEFT (IDIFFERENCE (fetch CBUFSIZE										    of STREAM)										 (fetch COFFSET										    of STREAM]		  (replace F1 of STREAM with PF))		((SETQ PF (fetch POBJ of PC))                (* This piece points to an object.							     set up so \TextBin will be called, and will return it.)		  (replace F2 of STREAM with 1)		  (replace COFFSET of STREAM with 1)		  (replace CBUFSIZE of STREAM with 1))		(T (ERROR "Piece is neither a file nor a string??" PC)))	      [SETQ TEDIT.CURRENT.FONT (fetch CLFONT of (SETQ TEDIT.CURRENT.CHARLOOKS							  (fetch PLOOKS							     of (replace F5 of STREAM with PC]                                                             (* Set the character looks and font caches.)	      )	    (T (ERROR "TRYING TO \SETUPGETCH BEYOND END OF TEXT"])(\SPLITPIECE  [LAMBDA (PC CH TEXTOBJ PC#)                                (* jds " 4-AUG-83 09:37")                                                             (* Split the piece PC before CH 							     (rel to start of text); return the new second piece.)                                                             (* PC#, if present, points at the CH# entry for the 							     piece being split.)    (PROG ([PCNO (OR PC# (\FINDPIECE PC (ffetch PCTB of TEXTOBJ]	   (NEWPC (create PIECE using PC))	   CHNO NEWLEN)          (SETQ CHNO (IDIFFERENCE CH (\EDITELT (ffetch PCTB of TEXTOBJ)					       PCNO)))       (* Offset within the piece before which to break)          (COND	    ((IGREATERP CHNO (fetch PLEN of PC))             (* He asked us to split this piece after its end!?)	      (ERROR "Trying to split a piece after end."))	    ((ILESSP CHNO 0)                                 (* Tryint to split the piece before it starts!)	      (ERROR "Trying to split a piece before it starts.")))          (replace PPARALAST of PC with NIL)                 (* There can be no para break before the split, as 							     things now work.)          (COND	    ((fetch PSTR of PC)                              (* This piece points to a string.							     Split it for the two new pieces)	      (replace PSTR of NEWPC with (SUBSTRING (fetch PSTR of PC)						     (ADD1 CHNO)))	      (replace PLEN of NEWPC with (IDIFFERENCE (fetch PLEN of PC)						       CHNO))	      (replace PSTR of PC with (SUBSTRING (fetch PSTR of PC)						  1 CHNO))	      (replace PLEN of PC with CHNO))	    ((fetch PFILE of PC)                             (* This piece points to a file.							     Set the fileptrs accordingly)	      (replace PFILE of NEWPC with (fetch PFILE of PC))	      (replace PFPOS of NEWPC with (IPLUS (fetch PFPOS of PC)						  CHNO))	      (replace PLEN of NEWPC with (IDIFFERENCE (fetch PLEN of PC)						       CHNO))	      (replace PLEN of PC with CHNO)))          (SETQ PCNO (\INSERTPIECE NEWPC (OR (fetch NEXTPIECE of PC)					     (QUOTE LASTPIECE))				   TEXTOBJ T))               (* Insert the new piece, and note its location in the 							     pctb)          (\EDITSETA (ffetch PCTB of TEXTOBJ)		     PCNO		     (IDIFFERENCE (\EDITELT (ffetch PCTB of TEXTOBJ)					    PCNO)				  (fetch PLEN of NEWPC)))    (* Now set its starting CH#)          (RETURN NEWPC])(\TEXTCLOSEF  [LAMBDA (STREAM)                                           (* jds "21-FEB-83 15:32")                                                             (* Close the files underlying a stream)    (PROG ((TEXTOBJ (fetch F3 of STREAM))	   PCTB PC)          (SETQ PCTB (fetch PCTB of TEXTOBJ))          (for I from (ADD1 \FirstPieceOffset) to (SUB1 (\EDITELT PCTB \PCTBLastPieceOffset))	     by \EltsPerPiece	     do (SETQ PC (\EDITELT PCTB I))		(COND		  ((fetch PFILE of PC)		    (CLOSEF? (fetch PFILE of PC])(\TEXTEOFP  [LAMBDA (STREAM)                                           (* jds " 8-JUL-82 13:59")                                                             (* Test for EOF on a text stream: At end of a piece, and							     there's no more pieces.)    (AND (IEQP (fetch COFFSET of STREAM)	       (fetch CBUFSIZE of STREAM))	 (ZEROP (fetch F2 of STREAM))	 (NOT (fetch NEXTPIECE of (fetch F5 of STREAM])(\TEXTGETEOFPTR  [LAMBDA (STREAM)                                           (* jds "30-JUL-82 10:01")    (fetch TEXTLEN of (fetch F3 of STREAM])(\TEXTGETFILEPTR  [LAMBDA (STREAM)                                           (* jds " 9-AUG-83 09:38")                                                             (* Do the GETFILEPTR operation for a text stream)    (PROG ((TEXTOBJ (fetch F3 of STREAM))	   (PC (fetch F5 of STREAM))	   PCNO)          (SETQ PCNO (\FINDPIECE PC (fetch PCTB of TEXTOBJ)))          (RETURN (SUB1 (IPLUS (\EDITELT (fetch PCTB of TEXTOBJ)					 PCNO)			       (IPLUS (IDIFFERENCE (fetch COFFSET of STREAM)						   (fetch FW7 of STREAM))				      (ITIMES 512 (IDIFFERENCE (fetch CPAGE of STREAM)							       (fetch FW6 of STREAM])(\TEXTINIT  [LAMBDA NIL                                                (* jds "21-FEB-83 14:56")                                                             (* Create the FDEV and STREAM prototypes for TEXT 							     streams.)          (* TEXT streams make use of the following STREAM fields: (DEVICE (* FDEV of this guy -- The TEXT device) F1 	  (* The STREAM for the PFILE of the current piece (or NIL)) F2 (* # chars left in piece at end of underlying file's	  page) F3 (* The TEXTOBJ for this stream) F4 F5 (* The PIECE we're currently inside) (FW6 WORD) 	  (* CPAGE for the start of the piece, for BACKFILEPTR) (FW7 WORD) (* COFFSET for the start of the piece, for 	  BACKFILEPTR) (FW8 WORD)))    (SETQ \TEXTFDEV (create FDEV using \STRINGFDEV DEVICENAME _(QUOTE TEXT)				       RANDOMACCESSP _ T PAGEMAPPED _ T GETFILENAME _(FUNCTION NILL)				       BIN _(FUNCTION \TEXTBIN)				       BOUT _(FUNCTION \TEXTBOUT)				       CLOSEFILE _(FUNCTION \TEXTCLOSEF)				       OPENFILE _(FUNCTION \TEXTOPENF)				       BACKFILEPTR _(FUNCTION \TEXTBACKFILEPTR)				       SETFILEPTR _(FUNCTION \TEXTSETFILEPTR)				       PEEKBIN _(FUNCTION \TEXTPEEKBIN)				       GETEOFPTR _(FUNCTION \TEXTGETEOFPTR)				       GETFILEPTR _(FUNCTION \TEXTGETFILEPTR)				       EOFP _(FUNCTION \TEXTEOFP)))    (SETQ \TEXTOFD (create STREAM			   BINABLE _ T			   BOUTABLE _ NIL			   ACCESS _(QUOTE BOTH)			   USERCLOSEABLE _ T			   USERVISIBLE _ T			   DEVICE _ \TEXTFDEV			   F1 _ NIL			   F2 _ 0			   F3 _ NIL			   F5 _ NIL			   FW6 _ 0			   FW7 _ 0))                         (* The prototypical Text stream)    ])(\TEXTOPENF  [LAMBDA (STREAM ACCESS ASDF QWER ZXCV)                     (* jds "22-FEB-83 11:58")                                                             (* Return the stream, opened for input)    (PROG ((TEXTOBJ (fetch F3 of STREAM))	   PCTB PC)          (SETQ PCTB (fetch PCTB of TEXTOBJ))          [for I from (ADD1 \FirstPieceOffset) to (SUB1 (\EDITELT PCTB \PCTBLastPieceOffset))	     by \EltsPerPiece	     do (SETQ PC (\EDITELT PCTB I))		(COND		  ((AND (fetch PFILE of PC)			(EQ (fetch ACCESSBITS of (fetch PFILE of PC))			    NoBits))		    (replace PFILE of PC with (\GETOFD (OPENFILE (fetch FULLNAME								    of (fetch PFILE of PC))								 (QUOTE INPUT))						       (QUOTE INPUT]          (RETURN STREAM])(\TEXTOUTCHARFN  [LAMBDA (CH STREAM)                                        (* jds "30-JUL-82 11:12")    (\INSERTCH CH (fetch TEXTLEN of (fetch F3 of STREAM))	       (fetch F3 of STREAM])(\TEXTPEEKBIN  [LAMBDA (STREAM)                                           (* jds "23-MAR-83 10:25")                                                             (* DO PEEKBIN for a text stream)    (PROG (CH FILE STR PF PS PC)          (COND	    ((fetch POBJ of (SETQ PC (fetch F5 of STREAM)))	      (RETURN (fetch POBJ of PC)))	    ((ILESSP (fetch COFFSET of STREAM)		     (fetch CBUFSIZE of STREAM))             (* Simple case -- just do the usual PEEKBIN)	      (RETURN (\PAGEDPEEKBIN STREAM)))	    (T                                               (* We've either hit a page bound in a file, or a piece 							     bound.)	       (RETURN (COND			 [(ZEROP (fetch F2 of STREAM))       (* Time for a new piece.)			   (SETQ PC (replace F5 of STREAM with (fetch NEXTPIECE of PC)))			   [SETQ TEDIT.CURRENT.FONT (fetch CLFONT of (SETQ TEDIT.CURRENT.CHARLOOKS								       (fetch PLOOKS of PC]                                                             (* Move to the next piece in the chain)			   (COND			     [PC (COND				   ((SETQ PS (fetch PSTR of PC))                                                             (* This piece lives in a string.)				     (replace CPPTR of STREAM					with (OR (ADDBASE (fetch (STRINGP BASE) of PS)							  (LRSH (fetch (STRINGP OFFST) of PS)								1))						 (PROGN 0)))				     (replace CPAGE of STREAM with 0)				     (replace COFFSET of STREAM with (LOGAND 1 (fetch (STRINGP OFFST)										  of PS)))				     (replace FW6 of STREAM with 0)                                                             (* Page # within the "file" where piece starts)				     (replace FW7 of STREAM with (fetch COFFSET of STREAM))                                                             (* Char # within the "page" where the piece starts 							     (for BACKFILEPTR))				     (replace EPAGE of STREAM with 1)				     (replace EOFFSET of STREAM with (fetch PLEN of PC))				     (replace CBUFSIZE of STREAM with (IPLUS (fetch COFFSET										of STREAM)									     (fetch PLEN										of PC)))				     (replace F2 of STREAM with 0)				     (replace F1 of STREAM with NIL)				     (\PEEKBIN STREAM))				   ((SETQ PF (fetch PFILE of PC))                                                             (* This piece lives on a file.)				     [AND (IEQP (fetch ACCESSBITS of PF)						NoBits)					  (SETQ PF (replace PFILE of PC						      with (\GETOFD (OPENFILE (fetch FULLNAME										 of PF)									      (QUOTE INPUT))								    (QUOTE INPUT]				     (replace FW6 of STREAM with (fetch (BYTEPTR PAGE)								    of (fetch PFPOS of PC)))                                                             (* Page in the file where the piece starts.)				     (replace FW7 of STREAM with (fetch (BYTEPTR OFFSET)								    of (fetch PFPOS of PC)))                                                             (* Char within the page where the piece starts.)				     (SETFILEPTR PF (fetch PFPOS of PC))				     (SETQ CH (\PAGEDPEEKBIN PF))				     (replace CPPTR of STREAM with (fetch CPPTR of PF))				     (replace CPAGE of STREAM with (fetch CPAGE of PF))				     (replace COFFSET of STREAM with (fetch COFFSET of PF))				     (replace EPAGE of STREAM with 32767)				     (replace EOFFSET of STREAM with (fetch EOFFSET of PF))				     [replace CBUFSIZE of STREAM					with (IMIN (fetch CBUFSIZE of PF)						   (SUB1 (IPLUS (fetch COFFSET of STREAM)								(fetch PLEN of PC]				     [replace F2 of STREAM					with (IDIFFERENCE (fetch PLEN of PC)							  (ADD1 (IDIFFERENCE (fetch CBUFSIZE										of STREAM)									     (fetch COFFSET										of STREAM]				     (replace F1 of STREAM with PF)				     CH)				   (T (ERROR "CAN'T GET TO NEXT PIECE"]			     (T                              (* There are no more pieces. Punt gracefully)				(RETURN NIL]			 (T                                  (* Need to move to the next page in a file.)			    (SETQ FILE (fetch F1 of STREAM))                                                             (* Get the STREAM which describes the file for real)			    (replace COFFSET of FILE with (fetch CBUFSIZE of FILE))                                                             (* Force it to do a page switch for us)			    (SETQ CH (\PAGEDPEEKBIN FILE))   (* Get the next character in the usual manner)			    (replace CPPTR of STREAM with (fetch CPPTR of FILE))                                                             (* Steal the fields we need to simulate that stream)			    (replace COFFSET of STREAM with (fetch COFFSET of FILE))			    (replace CPAGE of STREAM with (fetch CPAGE of FILE))			    (replace CBUFSIZE of STREAM with (IMIN (fetch F2 of STREAM)								   (fetch CBUFSIZE of FILE)))                                                             (* Can't read farther than end-of-piece, tho)			    (replace F2 of STREAM with (IDIFFERENCE (fetch F2 of STREAM)								    (fetch CBUFSIZE of STREAM)))			    (RETURN CH])(\TEXTTTYBOUT  [LAMBDA (STREAM BYTE)                                      (* jds " 1-JUN-83 10:48")                                                             (* Do BOUT to a text stream, which is an insertion at 							     the caret.)    (PROG ((TEXTOBJ (fetch F3 of STREAM)))          (COND	    ((EQ BYTE ERASECHARCODE)	      (\TEDIT.CHARDELETE TEXTOBJ "" (fetch SEL of TEXTOBJ)))	    ((EQ IGNORE.CCE (fetch CCECHO of (\SYNCODE (OR (fetch TXTTERMSA of TEXTOBJ)							   \PRIMTERMSA)						       BYTE)))                                                             (* Nothing, ignore it)	      )	    (T (SELCHARQ BYTE			 ((EOL CR LF)			   (\TEXTBOUT STREAM BYTE)			   (replace XPOSITION of STREAM with 0))			 (PROGN (\TEXTBOUT STREAM BYTE)				(add (fetch XPOSITION of STREAM)				     1])(\TEXTBACKFILEPTR  [LAMBDA (STREAM)                                           (* jds " 3-MAY-83 15:21")                                                             (* Use this to BACKFILEPTR a text stream.)    [PROG (PC PS PF)          (COND	    [(AND (IEQP (fetch CPAGE of STREAM)			(fetch FW6 of STREAM))		  (IEQP (fetch COFFSET of STREAM)			(fetch FW7 of STREAM)))              (* Hit start of piece; back to PREVPIECE & keep going.)	      [SETQ PC (replace F5 of STREAM with (fetch PREVPIECE of (fetch F5 of STREAM]                                                             (* Move to previous piece)	      (while (AND PC (ZEROP (fetch PLEN of PC)))		 do                                          (* Skip over any zero-length pieces as we back along.)		    (SETQ PC (fetch PREVPIECE of PC)))	      (COND		[PC [SETQ TEDIT.CURRENT.FONT (fetch CLFONT of (SETQ TEDIT.CURRENT.CHARLOOKS								(fetch PLOOKS of PC]		    (COND		      ((SETQ PS (fetch PSTR of PC))          (* This piece lives in a string.)			(replace CPPTR of STREAM with (OR (ADDBASE (fetch (STRINGP BASE)								      of PS)								   (LRSH (fetch (STRINGP OFFST)									    of PS)									 1))							  (PROGN 0)))			(replace CPAGE of STREAM with 0)			(replace FW6 of STREAM with 0)       (* Page # within the "file" where piece starts)			(replace FW7 of STREAM with (LOGAND 1 (fetch (STRINGP OFFST) of PS)))                                                             (* Char # within the "page" where the piece starts 							     (for BACKFILEPTR))			(replace EPAGE of STREAM with 1)			(replace EOFFSET of STREAM with (fetch PLEN of PC))			[replace COFFSET of STREAM with (SUB1 (replace CBUFSIZE of STREAM								 with (IPLUS (fetch FW7 of STREAM)									     (fetch PLEN										of PC]			(replace F2 of STREAM with 0)			(replace F1 of STREAM with NIL))		      ((SETQ PF (fetch PFILE of PC))         (* This piece lives on a file.)			[AND (IEQP (fetch ACCESSBITS of PF)				   NoBits)			     (SETQ PF (replace PFILE of PC					 with (\GETOFD (OPENFILE (fetch FULLNAME of PF)								 (QUOTE INPUT))						       (QUOTE INPUT]			(replace FW6 of STREAM with (fetch (BYTEPTR PAGE)						       of (fetch PFPOS of PC)))                                                             (* Page in the file where the piece starts.)			(replace FW7 of STREAM with (fetch (BYTEPTR OFFSET)						       of (fetch PFPOS of PC)))                                                             (* Char within the page where the piece starts.)			(SETFILEPTR PF (IPLUS (fetch PFPOS of PC)					      -1					      (fetch PLEN of PC)))			(\PEEKBIN PF)			(replace CPPTR of STREAM with (fetch CPPTR of PF))			(replace CPAGE of STREAM with (fetch CPAGE of PF))			(replace COFFSET of STREAM with (fetch COFFSET of PF))			(replace EPAGE of STREAM with 32767)			(replace EOFFSET of STREAM with (fetch EOFFSET of PF))			(replace CBUFSIZE of STREAM with (IMIN (ADD1 (fetch COFFSET of STREAM))							       (fetch CBUFSIZE of PF)))			(replace F2 of STREAM with 0)			(replace F1 of STREAM with PF))		      ((fetch POBJ of PC)			(replace F2 of STREAM with 0))		      (T (ERROR "CAN'T GET TO NEXT PIECE"]		(T (ERROR "Trying to BACKFILEPTR thru start of text."]	    [(ZEROP (fetch COFFSET of STREAM))               (* Move back 1 file page)	      (replace F2 of STREAM with (IPLUS (fetch F2 of STREAM)						(fetch CBUFSIZE of STREAM)))	      (replace COFFSET of (fetch F1 of STREAM) with 0)	      (\BACKFILEPTR (fetch F1 of STREAM))	      (\PEEKBIN (fetch F1 of STREAM))	      (replace CPAGE of STREAM with (fetch CPAGE of (fetch F1 of STREAM)))	      (replace COFFSET of STREAM with (fetch COFFSET of (fetch F1 of STREAM)))	      (replace CBUFSIZE of STREAM with (fetch CBUFSIZE of (fetch F1 of STREAM)))	      (replace CPPTR of STREAM with (fetch CPPTR of (fetch F1 of STREAM]	    (T                                               (* JUST ACT CASUAL & DO IT.)	       (\PAGEDBACKFILEPTR STREAM]    T])(\TEXTBIN  [LAMBDA (STREAM)                                           (* jds "19-APR-83 09:29")                                                             (* Do BIN slow case for a text stream)    (DECLARE (LOCALVARS . T))    (PROG (CH FILE STR PF PS PC PO)          (COND	    ((ILESSP (fetch COFFSET of STREAM)		     (fetch CBUFSIZE of STREAM))             (* Simple case -- just do the usual BIN)	      (RETURN (\PAGEDBIN STREAM)))	    (T                                               (* We've either hit a page bound in a file, or a piece 							     bound.)	       (RETURN (COND			 [(ZEROP (fetch F2 of STREAM))       (* Time for a new piece.)			   [SETQ PC (replace F5 of STREAM with (fetch NEXTPIECE								  of (fetch F5 of STREAM]                                                             (* Move to the next piece in the chain)			   (COND			     [PC (AND (fetch EXTRASTREAMOP of STREAM)				      (APPLY* (fetch EXTRASTREAMOP of STREAM)					      STREAM PC))    (* Take care of any piece-change uproar.)				 [SETQ TEDIT.CURRENT.FONT (fetch CLFONT							     of (SETQ TEDIT.CURRENT.CHARLOOKS								  (fetch PLOOKS of PC]				 (COND				   ((SETQ PS (fetch PSTR of PC))                                                             (* This piece lives in a string.)				     (replace CPPTR of STREAM					with (OR (ADDBASE (fetch (STRINGP BASE) of PS)							  (LRSH (fetch (STRINGP OFFST) of PS)								1))						 (PROGN 0)))				     (replace CPAGE of STREAM with 0)				     (replace COFFSET of STREAM with (LOGAND 1 (fetch (STRINGP OFFST)										  of PS)))				     (replace FW6 of STREAM with 0)                                                             (* Page # within the "file" where piece starts)				     (replace FW7 of STREAM with (fetch COFFSET of STREAM))                                                             (* Char # within the "page" where the piece starts 							     (for BACKFILEPTR))				     (replace EPAGE of STREAM with 1)				     (replace EOFFSET of STREAM with (fetch PLEN of PC))				     (replace CBUFSIZE of STREAM with (IPLUS (fetch COFFSET										of STREAM)									     (fetch PLEN										of PC)))				     (replace F2 of STREAM with 0)				     (replace F1 of STREAM with NIL)				     (\BIN STREAM))				   ((SETQ PF (fetch PFILE of PC))                                                             (* This piece lives on a file.)				     [AND (IEQP (fetch ACCESSBITS of PF)						NoBits)					  (SETQ PF (replace PFILE of PC						      with (\GETOFD (OPENFILE (fetch FULLNAME										 of PF)									      (QUOTE INPUT))								    (QUOTE INPUT]				     (replace FW6 of STREAM with (fetch (BYTEPTR PAGE)								    of (fetch PFPOS of PC)))                                                             (* Page in the file where the piece starts.)				     (replace FW7 of STREAM with (fetch (BYTEPTR OFFSET)								    of (fetch PFPOS of PC)))                                                             (* Char within the page where the piece starts.)				     (SETFILEPTR PF (fetch PFPOS of PC))				     (SETQ CH (\PAGEDBIN PF))				     (replace CPPTR of STREAM with (fetch CPPTR of PF))				     (replace CPAGE of STREAM with (fetch CPAGE of PF))				     (replace COFFSET of STREAM with (fetch COFFSET of PF))				     (replace EPAGE of STREAM with 32767)				     (replace EOFFSET of STREAM with (fetch EOFFSET of PF))				     [replace CBUFSIZE of STREAM					with (IMIN (fetch CBUFSIZE of PF)						   (SUB1 (IPLUS (fetch COFFSET of STREAM)								(fetch PLEN of PC]				     [replace F2 of STREAM					with (IDIFFERENCE (fetch PLEN of PC)							  (ADD1 (IDIFFERENCE (fetch CBUFSIZE										of STREAM)									     (fetch COFFSET										of STREAM]				     (replace F1 of STREAM with PF)				     CH)				   ((fetch POBJ of PC)				     (RETURN (fetch POBJ of PC)))				   (T (ERROR "CAN'T GET TO NEXT PIECE"]			     (T                              (* There are no more pieces. Punt gracefully)				(RETURN NIL]			 ((SETQ PO (fetch POBJ of (fetch F5 of STREAM)))                                                             (* This is an object)			   (replace F2 of STREAM with 0)			   (RETURN PO))			 (T                                  (* Need to move to the next page in a file.)			    (SETQ FILE (fetch F1 of STREAM))                                                             (* Get the STREAM which describes the file for real)			    [AND (IEQP (fetch ACCESSBITS of FILE)				       NoBits)				 (SETQ FILE (\GETOFD (OPENFILE (fetch FULLNAME of FILE)							       (QUOTE INPUT))						     (QUOTE INPUT]			    (replace COFFSET of FILE with (fetch CBUFSIZE of FILE))                                                             (* Force it to do a page switch for us)			    (SETQ CH (\PAGEDBIN FILE))       (* Get the next character in the usual manner)			    (replace CPPTR of STREAM with (fetch CPPTR of FILE))                                                             (* Steal the fields we need to simulate that stream)			    (replace COFFSET of STREAM with (fetch COFFSET of FILE))			    (replace CPAGE of STREAM with (fetch CPAGE of FILE))			    (replace CBUFSIZE of STREAM with (IMIN (fetch F2 of STREAM)								   (fetch CBUFSIZE of FILE)))                                                             (* Can't read farther than end-of-piece, tho)			    (replace F2 of STREAM with (IDIFFERENCE (fetch F2 of STREAM)								    (fetch CBUFSIZE of STREAM)))			    (RETURN CH])(\TEXTBOUT  [LAMBDA (STREAM BYTE)                                      (* jds "25-MAY-83 13:28")                                                             (* Do BOUT to a text stream, which is an insertion at 							     the caret.)    (PROG ((TEXTOBJ (fetch F3 of STREAM)))          (TEDIT.\INSERT BYTE (fetch SEL of TEXTOBJ)			 TEXTOBJ			 (EQ BYTE (CHARCODE SPACE))			 (EQ BYTE (CHARCODE CR])(\TEXTSETEOF  [LAMBDA (STREAM EOFPTR)                                    (* jds "30-JUL-82 10:01")                                                             (* Set the EPAGE/EOFFSET of the stream to be 							     (SUB1 of EOFPTR))    (replace EPAGE of STREAM with (fetch (BYTEPTR PAGE) of EOFPTR))    (replace EOFFSET of STREAM with (fetch (BYTEPTR OFFSET) of EOFPTR])(\TEXTSETFILEPTR  [LAMBDA (STREAM FILEPOS)                                   (* jds " 8-JUL-82 14:02")                                                             (* Sets the file ptr for a text stream.)    (PROG ((TEXTOBJ (fetch F3 of STREAM)))          (COND	    ((IEQP FILEPOS -1)                               (* Means end of file)	      (\SETUPGETCH (fetch TEXTLEN of TEXTOBJ)			   TEXTOBJ))	    ((OR (ILESSP FILEPOS 0)		 (IGREATERP FILEPOS (fetch TEXTLEN of TEXTOBJ)))                                                             (* If the fileptr is not within the text, punt.)	      (\ILLEGAL.ARG FILEPOS))	    (T (\SETUPGETCH (ADD1 FILEPOS)			    TEXTOBJ]))[DECLARE: EVAL@COMPILE (DATATYPE PIECE (                                            (* The piece describes either a string or part of a 							     file. , or a generalized OBJECT.)		 PSTR                                        (* The string where this piece's text resides, or NIL)		 PFILE                                       (* The file which contains this piece's text, or NIL)		 PFPOS                                       (* The FILEPTR of the start of the piece in the file)		 PLEN                                        (* Length of the piece, in characters.)		 NEXTPIECE                                   (* -> Next piece in this textobj.)		 (PREVPIECE XPOINTER)                        (* -> Prior piece in this text object.)		 PLOOKS                                      (* Formatting info and formatting events in this piece)		 POBJ                                        (* The OBJECT this piece describes)		 PPARALAST                                   (* This piece contains a paragraph break)		 PPARALOOKS                                  (* Paragraph looks for this piece)		 PDOC                                        (* Document descriptor for this piece, for interpreting 							     fonts &c)		 )		PSTR _ NIL PFILE _ NIL PFPOS _ 0 PLEN _ 0 PPARALOOKS _ TEDIT.DEFAULT.FMTSPEC)(DATATYPE TEXTOBJ (PCTB                                      (* The piece table)			\INSERTPC                            (* Piece to hold type-in)			\INSERTPCNO                          (* Piece # of the input piece)			\INSERTNEXTCH                        (* CH# of next char which is typed into that piece.)			\INSERTLEFT                          (* Space left in the type-in piece)			\INSERTLEN                           (* # of characters already in the piece.)			\INSERTSTRING                        (* The string which the piece describes.)			\INSERTFIRSTCH                       (* CH# of first char in the piece.)			\WINDOW                              (* The window where this textobj is displayed)			MOUSEREGION                          (* Section of the window the mouse is in.)			TEXTLEN                              (* # of chars in the text)			LINES                                (* -> to top of chain of line descriptors for displayed 							     text)			DS                                   (* Display stream where this textobj is displayed)			SEL                                  (* The current selection within the text)			SCRATCHSEL                           (* Scratch space for the selection code)			MOVESEL                              (* Source for the next MOVE of text)			SHIFTEDSEL                           (* Source for the next COPY)			DELETESEL                            (* Text to be deleted imminently)			WRIGHT                               (* Right edge of the window (or subregion) where this is							     displayed)			WTOP                                 (* Top of the window/region)			WBOTTOM                              (* Bottom of the window/region)			WLEFT                                (* Left edge of the window/region)			TXTFILE                              (* The original text file we're editing)			\DIRTY                               (* T => changed since last saved.)			(STREAMHINT XPOINTER)                (* -> the TEXTOFD stream which gives access to this 							     textobj)			EDITFINISHEDFLG                      (* T => The guy has asked the editor to go way)			CARET                                (* Describes the flashing caret for the editing window)			INSERTFONT                           (* Font to be used for inserted text.)			WINDOWTITLE                          (* Original title for this window, of there was one.)			THISLINE                             (* Cache of line-related info, to speed up selection &c)			MENUFLG                              (* T if this TEXTOBJ is a tedit-style menu)			FMTSPEC                              (* Default Formatting Spec to be used when formatting 							     paragraphs)			FORMATTEDP                           (* Flag for paragraph formatting.							     T if this document is to contain paragraph formatting 							     information.)			TXTREADONLY                          (* This is only available for shift selection.)			TXTTERMSA                            (* Special instructions for displaying characters on the							     screen)			EDITOPACTIVE                         (* T if there is another process performing edit ops on 							     this object. Locks out the command loop, and the menu 							     commands.)			)		  SEL _(create SELECTION)		  SCRATCHSEL _(create SELECTION)		  MOVESEL _(create SELECTION				   HOW _ EDITMOVESHADE				   HOWHEIGHT _ 32767				   HASCARET _ NIL)		  SHIFTEDSEL _(create SELECTION				      HOW _ COPYSELSHADE				      HASCARET _ NIL)		  DELETESEL _(create SELECTION				     HOW _ BLACKSHADE				     HOWHEIGHT _ 32767				     HASCARET _ NIL)		  \INSERTNEXTCH _ -1 \INSERTPC _ NIL \INSERTLEFT _ 0 \INSERTLEN _ 0 \INSERTSTRING _ 		  NIL \INSERTFIRSTCH _ 1000000 TEXTLEN _ 0 WRIGHT _ 0 WTOP _ 0 WLEFT _ 0 WBOTTOM _ 0 		  TXTFILE _ NIL \DIRTY _ NIL MOUSEREGION _(QUOTE TEXT)		  THISLINE _(create THISLINE				    LEN _ 0				    CHARS _(ARRAY 256 (QUOTE POINTER)						  0 0)				    WIDTHS _(ARRAY 256 (QUOTE SMALLP)						   0 0)				    LOOKS _(ARRAY 256 (QUOTE POINTER)						  NIL 0))		  MENUFLG _ NIL FMTSPEC _ TEDIT.DEFAULT.FMTSPEC FORMATTEDP _ NIL)](/DECLAREDATATYPE (QUOTE PIECE)		  (QUOTE (POINTER POINTER POINTER POINTER POINTER XPOINTER POINTER POINTER POINTER 				  POINTER POINTER)))(/DECLAREDATATYPE (QUOTE TEXTOBJ)		  (QUOTE (POINTER POINTER POINTER POINTER POINTER POINTER POINTER POINTER POINTER 				  POINTER POINTER POINTER POINTER POINTER POINTER POINTER POINTER 				  POINTER POINTER POINTER POINTER POINTER POINTER POINTER XPOINTER 				  POINTER POINTER POINTER POINTER POINTER POINTER POINTER POINTER 				  POINTER POINTER POINTER)))(ADDTOVAR GLOBALVARS \TEXTOFD \TEXTFDEV)(\TEXTINIT)(RPAQQ TEXTOFDMACROS (\EDITELT \GETCH \GETCHB \EDITSETA \WORDSETA))(DECLARE: EVAL@COMPILE (PUTPROPS \EDITELT DMACRO (OPENLAMBDA (ARR NO)				      (* This is equivalent to ELT, but bypasses the checking, since 					 we "know" that ARR is an array. Hence, much faster.)				      (GETBASEPTR (\ADDBASE2 (fetch (ARRAYP BASE)								    of ARR)							     NO)						  0)))(PUTPROPS \GETCH MACRO ((TEXTOBJ)                            (* jds "23-FEB-82 08:56")                                                             (* Get the next available character from the text being 							     edited.)			(\BIN (fetch STREAMHINT of TEXTOBJ))))(PUTPROPS \GETCHB MACRO ((TEXTOBJ)                           (* Get the next prior character in the text being 							     edited.)			 (\BACKBIN (fetch STREAMHINT of TEXTOBJ))))(PUTPROPS \EDITSETA DMACRO (OPENLAMBDA (ARR N VAL)				       (* Equivalent to SETA (for pointer-type arrays)					  , but bypasses the bounds and type checking. Hence MUCH 					  faster.)				       (\RPLPTR (\ADDBASE2 (fetch (ARRAYP BASE)								  of ARR)							   N)						0 VAL)))(PUTPROPS \WORDSETA DMACRO (OPENLAMBDA (A J V)				       [CHECK (AND (ARRAYP A)						   (ZEROP (fetch (ARRAYP ORIG)								 of A))						   (EQ \ST.POS16 (fetch (ARRAYP TYP)									of A]				       (CHECK (IGREATERP (fetch (ARRAYP LENGTH)								of A)							 J))				       (\PUTBASE (fetch (ARRAYP BASE)							of A)						 (IPLUS (fetch (ARRAYP OFFST)							       of A)							J)						 V))))(* Private data structures and constants)(DECLARE: EVAL@COMPILE DONTCOPY (DECLARE: EVAL@COMPILE (RPAQQ \EditEOFChar# 1000000)(RPAQQ \PCTBFreePieces 0)(RPAQQ \PCTBLastPieceOffset 1)(RPAQQ \FirstPieceOffset 2)(RPAQQ \SecondPieceOffset 4)(RPAQQ \EltsPerPiece 2)(CONSTANTS (\EditEOFChar# 1000000)	   (\PCTBFreePieces 0)	   (\PCTBLastPieceOffset 1)	   (\FirstPieceOffset 2)	   (\SecondPieceOffset 4)	   (\EltsPerPiece 2))))(* Debugging functions)(DEFINEQ(PPCHAIN  [LAMBDA (PC)                                               (* jds " 3-MAY-82 10:45")    (PROG ((SEEN NIL))          [COND	    ((NUMBERP PC)	      (SETQ PC (\EDITELT (fetch PCTB of TEXTOBJ)				 PC]          [COND	    ((FMEMB PC SEEN)	      (RETURN (QUOTE (LOOP SEEN]          (PRINTPIECE PC)          (SETQ SEEN (CONS PC SEEN))          (COND	    ((fetch NEXTPIECE of PC)	      (PPCHAIN (fetch NEXTPIECE of PC])(PRINTPIECE  [LAMBDA (PC)                                               (* jds "21-APR-83 11:37")    [COND      ((NUMBERP PC)	(SETQ PC (\EDITELT (fetch PCTB of TEXTOBJ)			   PC]    (printout T T "----------" T "PIECE " PC " 	Length " (fetch PLEN of PC)	      T)    (COND      ((fetch PSTR of PC)	(printout T "String:  %"" (SUBSTRING (fetch PSTR of PC)					     1					     (fetch PLEN of PC))		  "%"" T))      ((fetch PFILE of PC)	(printout T "File:  " (fetch PFILE of PC)		  "    FilePos:  "		  (fetch PFPOS of PC)		  T))      ((fetch POBJ of PC)	(printout T "Object:  " (fetch POBJ of PC)		  T)))    (printout T "ChLooks:  " (fetch CLFONT of (fetch PLOOKS of PC))	      " "	      (fetch CLSIZE of (fetch PLOOKS of PC))	      T)    (printout T "Para: " (fetch PPARALOOKS of PC)	      " "	      (COND		((fetch PPARALAST of PC)		  "PARALAST")		(T " "))	      T)    (printout T "Prev: " (fetch PREVPIECE of PC)	      T "Next: " (fetch NEXTPIECE of PC)	      T "----------" T])(SEEPCTB  [LAMBDA (N)                                                (* jds " 3-MAY-82 10:45")    (OR N (SETQ N 10))    (for I from 1 to N do (PRINT (\EDITELT (fetch PCTB of TEXTOBJ)					   I])(SEETEXT  [LAMBDA (LEN)                                              (* jds " 3-MAY-82 10:45")    [OR LEN (SETQ LEN (\EDITELT (fetch PCTB of TEXTOBJ)				(\FINDPIECE (QUOTE LASTPIECE)					    (fetch PCTB of TEXTOBJ]    (\SETUPGETCH 1 TEXTOBJ)    (for I from 1 to LEN       do (SETQ CH (\GETCH TEXTOBJ))	  (PRIN1 (CHARACTER CH])(SEETXT  [LAMBDA (START END TEXTOBJ)                                (* jds "16-APR-82 15:44")    (\SETUPGETCH START TEXTOBJ)    (for I from START to END do (PRIN1 (CHARACTER (\GETCH TEXTOBJ]))(DECLARE: DONTCOPY  (FILEMAP (NIL (1478 75434 (OPENTEXTSTREAM 1488 . 5768) (TXTFILE 5770 . 6082) (\CHTOPC 6084 . 7612) (\CHTOPCNO 7614 . 9210) (\CLEARPCTB 9212 . 10278) (\COPYTEXT 10280 . 16564) (\CREATEPIECE 16566 . 18578) (\DELETECH 18580 . 25435) (\DELETEPIECE 25437 . 27423) (\FINDPIECE 27425 . 27955) (\INSERTCH 27957 . 39374) (\INSERTCR 39376 . 40029) (\INSERTPIECE 40031 . 42873) (\MAKEPCTB 42875 . 44194) (\SETUPGETCH 44196 . 48602) (\SPLITPIECE 48604 . 51326) (\TEXTCLOSEF 51328 . 51916) (\TEXTEOFP 51918 . 52383) (\TEXTGETEOFPTR 52385 . 52555) (\TEXTGETFILEPTR 52557 . 53256) (\TEXTINIT 53258 . 54939) (\TEXTOPENF 54941 . 55779) (\TEXTOUTCHARFN 55781 . 56007) (\TEXTPEEKBIN 56009 . 61757) (\TEXTTTYBOUT 61759 . 62651) (\TEXTBACKFILEPTR 62653 . 67453) (\TEXTBIN 67455 . 73829) (\TEXTBOUT 73831 . 74267) (\TEXTSETEOF 74269 . 74701) (\TEXTSETFILEPTR 74703 . 75432)) (83834 86349 (PPCHAIN 83844 . 84318) (PRINTPIECE 84320 . 85508) (SEEPCTB 85510 . 85739) (SEETEXT 85741 . 86123) (SEETXT 86125 . 86347)))))STOP