(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