PROC FSECMDS; BEGIN # *** FSECMDS -- SUPPLEMENTARY COMMANDS. * * COPYRIGHT CONTROL DATA SYSTEMS INC. 1992. * * FSECMDS CONTAINS CODE WHICH NORMALLY WOULD BE PART OF THE * LARGE "PROCESS" CASE STATEMENT, BUT WHICH WE HAVE MOVED * OUT TO CONSERVE FIELD LENGTH MOST OF THE TIME. CODE IN * FSECMDS IS A CANDIDATE FOR ANY OVERLAY STRUCTURING THAT MAY * BE PROVIDED IN THE FUTURE. CODE IN FSECMDS MUST BE STRICTLY * FOR THE SINGLE-USER VERSION ONLY. REENTRANT PROGRAMMING * IS NOT USED IN THIS MODULE. # DEF LISTCON #0#; CONTROL EJECT; # UNIVERSAL DECLARES # *IFCALL SINGLE,COMFSGL *IFCALL ONLY,COMFONL *IFCALL MULTI,COMFMLT *CALL COMFFSE # COMMON, DATA # *CALL COMFDS1 *CALL COMFVD2 *CALL COMFDS2 # COMMAND/SYNTAX TABLES # *CALL COMFTAB # EXTERNALS # XDEF BEGIN *CALL COMFXCM END XREF BEGIN *CALL COMFXFL *CALL COMFXSC *CALL COMFXED *CALL COMFXSB *CALL COMFXTI *CALL COMFXFO *CALL COMFXWK END XREF # SYMPLIB SUPPORT # BEGIN PROC REWIND; PROC WRITER; PROC READ; PROC RETERN; PROC RECALL; PROC PF; PROC WRITEC; PROC READC; PROC SKIPEI; PROC BKSP; END XREF # FSELIB # BEGIN FUNC FIXCTL B; FUNC LENGTH; PROC FLDLEN; END XREF # VIRTERM # BEGIN PROC VDTCHR; END XREF # BUFFER MAPPING # BEGIN ARRAY WORKBUF;; ARRAY BUILDBF;; ITEM MAXADDR; END PAGE # DATA LOCAL TO OVERLAY # ITEM RESULT,NWORDS, TMP1, INDEX, KILLUPLOW B, ZERO=0; ITEM SAVBLANKS, SAVLINENO; ARRAY STATUSMSGS [0:3] P(2); BEGIN ITEM YESORNO C(0,0,7)=[" NO ", " YES ", " ", " "]; ITEM CHARTYPE C(1,0,7)=["DISPLAY", "DISPLAY", " ASCII ", " 8/12 "]; END PAGE # USEFUL LITTLE ROUTINES # PROC XFRCMOUT; BEGIN # ** XFRCMOUT - OUTWARD LINE TRANSFER FOR COPY/MOVE. * * ENTRY LIN - INTERNAL LINE IMAGE. * FORCEFIELD, CHARRANGE - MODE SETTINGS. * CHRPTR1, CHRPTR2, FIRSTRANGE, LASTRANGE - DITTO. * MOVEFET - FET FOR SCRATCH FILE. * * EXIT IMAGE WRITTEN TO SCRATCH IN 6/12 CHARSET. * * MACROS SETCHAR. * * CALLS LSHIFT, CONVOUT, POSZ, WRITEC. # IF FORCEFIELD THEN BEGIN SETCHAR(LINE,CHRPTR2+1,CENDLINE); LSHIFT(LIN,CHRPTR1,CHRPTR1); CONVOUT(LIN,4); POSZ(CURRENT); # RE-FRESH LINE BUFFER # END ELSE IF CHARRANGE THEN BEGIN # TRUNCATE LAST, SHIFT FIRST # IF LASTRANGE THEN SETCHAR(LINE,CHRPTR2+1,CENDLINE); IF FIRSTRANGE THEN LSHIFT(LIN,CHRPTR1,CHRPTR1); CONVOUT(LIN,4); POSZ(CURRENT); # RE-FRESH LINE BUFFER # END ELSE CONVOUT(LIN,4); WRITEC(MOVEFET,TMPLIN); END # OF XFRCMOUT # PROC XFRCMIN; BEGIN # ** XFRCMIN - INWARD TRANSFER FOR COPY/MOVE. * * ENTRY MOVEFET - SCRATCH FILE FET. * * EXIT LIN - LINE IMAGE, INTERNAL CHARSET FROM 6/12. * * CALLS READC, CONVIN. # ITEM TMP1; READC(MOVEFET,TMPLIN,BUFWID2P1,TMP1); IF TMP1 NQ 0 THEN FATAL(" TRANSFER TO THE BUFFER IS INCOMPLETE.$"); CONVIN(LIN,2); END # OF XFRCMIN # PROC TTCHAR(CHAR,SYMBOL); BEGIN # ** TTCHAR - OUTPUT INTERNAL CHARACTER TO TERMINAL. * * TTCHAR OUTPUTS A SINGLE CHARACTER, USING SYMBOLIC KEYWORDS * FOR (BLANK) AND (NONE) IF REQUESTED. NOTE THAT SINCE THE * TERMINAL IS DRIVEN IN 6/12 WHILE IN LINE MODE SPECIAL * TRANSLATION MAY BE NEEDED. * * ENTRY CHAR = THE CHARACTER (INTERNAL CSET). * SYMBOL = USE SYMBOLIC NOTATION (TRUE/FALSE). * * CALLS TTST, TTSTR, VDTCHR. # ITEM CHAR I; # CHARACTER, AS INTEGER # ITEM SYMBOL B; # SYMBOLIC FLAG (TRUE/FALSE) # ITEM TMP1 I; # TEMPORARY # IF CHAR EQ CNOTHING THEN BEGIN # IF NO CHARACTER # IF SYMBOL THEN TTSTR("(NONE)$"); # IF SYMBOLIC REQUESTED # END ELSE BEGIN # IF CHARACTER OR BLANK # IF SYMBOL AND CHAR EQ CBLANK THEN TTSTR("(BLANK)$"); # IF SYMBOL # ELSE BEGIN # IF CHARACTER OR NORMAL BLANK # IF SCREENMODE THEN BEGIN # IF SCREEN MODE # TMP1 = XLTINTXP[CHAR]; # TRANSLATE, OUTPUT # VDTCHR(TMP1); END ELSE BEGIN # LINE MODE # TMP1=XLTINTDSP[CHAR]; # TRANSLATE TO DISPLAY # IF CHAR EQ CATSIGN OR CHAR EQ CUPARROW OR CHAR EQ CGRAVE THEN BEGIN # IF 74XX TRANSLATION NEEDED # TTCHR(O"74"); # OUTPUT ESCAPE CHARACTER # TMP1 = O"01"; # ASSUME AT SIGN # IF CHAR EQ CUPARROW THEN TMP1 = O"02"; IF CHAR EQ CGRAVE THEN TMP1 = O"07"; END ELSE BEGIN # NOT 74XX # IF CHAR EQ CLEFTCURL OR CHAR EQ CVERTICAL OR CHAR EQ CRITECURL OR CHAR EQ CTILDE THEN BEGIN # IF 76XX TRANSLATION NEEDED # TTCHR(O"76"); # OUTPUT ESCAPE CHARACTER # TMP1 = O"33"; # ASSUME LEFT BRACE # IF CHAR EQ CVERTICAL THEN TMP1 = O"34"; IF CHAR EQ CRITECURL THEN TMP1 = O"35"; IF CHAR EQ CTILDE THEN TMP1 = O"36"; END END TTCHR(TMP1); # OUTPUT (REST OF) CHARACTER # END END END END # TTCHAR # PROC UNDODECODE(POS,NUM); BEGIN # ** UNDODECODE - DECODE AN AUDIT TRAIL DESCRIPTOR. * * ENTRY POS - CHARACTER POSITION OF FIELD. * LIN - CONTAINS DESCRIPTOR. * * EXIT NUM - VALUE DECODED FROM FIELD. * * MACROS GETCHAR. # ITEM POS, NUM, TMP1, TMP2; NUM=0; TMP2=POS; GETCHAR(LINE,TMP2,TMP1); WHYLE TMP1 GQ CDIGIT0 AND TMP1 LQ CDIGIT9 DO BEGIN NUM=NUM*10+TMP1-CDIGIT0; TMP2=TMP2+1; GETCHAR(LINE,TMP2,TMP1); END END # OF UNDODECODE # PROC UNDOPOS(OFFSET); BEGIN # ** UNDOPOS - POSITION TO AUDITED DATA LINE. * * ENTRY OFFSET - DIFFERENCE BETWEEN LINNUM3 AND TARGET. * LINNUM1 - FILE BRACKET NUMBER. * LINNUM3 - LINE ORDINAL IN FILE BRACKET. * * EXIT CURFILE - EQUALS LINNUM1. * CURRENT - ABSOLUTE LINE ADDRESS. * LIN - THE TEXT OF THE LINE. * CURF(CURFILE) - EQUAL TO CURRENT. * P - POINTS TO LIN. * * CALLS POSZ. # ITEM OFFSET; P=0; # POSITION INVISIBLY # POSZ(TOPF(LINNUM1)+LINNUM3+OFFSET); P=LOC(LIN); # RESTORE # CURFILE=LINNUM1; # REMEMBER WHERE WE ARE # CURF(CURFILE)=CURRENT; END # OF UNDOPOS # PROC UNDOOPEN(BRACKET,DIRECTORY); BEGIN # ** UNDOOPEN - GET FILE IMAGE INTO ACTIVE BRACKET. * * ENTRY BRACKET - DESIRED BRACKET NUMBER. * DIRECTORY - WORKFILE ADDRESS OF FILE DIRECTORY LINE. * * EXIT FILE IS OPENED IN BRACKET. * THIS AFFECTS TOPF(), BOTF(), ETC. * * CALLS PUSH, POSZ, SCANFDL, OPENFILE, POP. * * USES READNAM, FILNUM, CHARPARM, GETPARM. # ITEM BRACKET, DIRECTORY; IF DIRECTORY EQ 0 OR DIRECTORY EQ FDLF(BRACKET) THEN RETURN; PUSH; POSZ(DIRECTORY); SCANFDL(READNAM); FILNUM=BRACKET; CHARPARM=0; GETPARM=0; OPENFILE; POP; END # OF UNDOOPEN # PROC DOFILL; BEGIN # ** DOFILL - MAIN ALGORITHM FOR PARAGRAPH FORMATTING. * * DOFILL IS THE MAIN PROCESSING ALGORITHM FOR THE WORD- * PROCESSING COMMAND, ".FILL". THE UNIVERSAL SYNTAX * SCANNER MUST BE CALLED BEFORE BEFORE DOFILL. DOFILL * ACCEPTS EXPLICIT RANGE BOUNDARIES, OR COMPUTE AN IMPLICIT * RANGE AS THE PARAGRAPH SURROUNDING ONE TARGET LINE. * MARGINS MAY BE COLUMN 1 THRU THE WIDTH SETTING, OR A * TAB FIELD. * * ENTRY SCANNER HAS BEEN CALLED. * LINPTR1 - FIRST LINE OF RANGE IF RANGE EXPLICIT. * ANY ADDRESS WITHIN PARAGRAPH FOR IMPLICIT. * LINPTR2 - LAST LINE OF RANGE IF RANGE EXPLICIT. * LIMIT - RANGE LENGTH LIMIT IF RANGE EXPLICIT. * NONDEFAULT - TELLS RANGE IMPLICIT OR EXPLICIT. * FILLLEFT, FILLRIGHT - DEFAULT MARGIN OBJECTIVES. * FILLFIRST - DEFAULT MARGIN OBJECTIVES. * CURFILE - WHICH FILE BRACKET. * NUMBERED[CURFILE] - REQUIRED TO BE FALSE. * TOPF(CURFILE), BOTF(CURFILE) - FILE BOUNDS. * SCREENMODE - CONTROLS FINAL POSITIONING/PRINTING. * * EXIT LINPTR1, LINPTR2, LIMIT - POSSIBLY DESTROYED. * CURRENT - FRONT OF RESULTANT RANGE IF SCREEN, * ELSE END OF RESULTANT RANGE. * LIN - TEXT OF CURRENT LINE. * BOTF(CURFILE) - POSSIBLY RELOCATED. * * MACROS GETCHAR, SETCHAR. * * CALLS TABFN, MIN, MAX, POSZ, LENGTH, BAKZ, FWDZ, TRIMPAD, * REPX, LSHIFT, RSHIFT, DOSPLIT, COPYLIN, DORANGE. * * USES TTYLIN. # ITEM FILLLOOP; # USED FOR LOOP TESTING # ITEM LMARGIN, RMARGIN; ITEM TMP1, TMP2, TMP3, TMP4, TMP5, TMP6; ITEM LEFTRIGHT B; # PROCESS A PARAGRAPH OF WORDS OF TEXT CENTERED AROUND # # THE CURRENT LINE (LINPTR1 INITIALLY). WE LOOK BACK # # AND FORWARDS FOR BOUNDARIES, THEN PROCESS THE BLOCK # # MERGING WORDS ONTO LINES TO MATCH "SET WIDTH". # IF NUMBERED[CURFILE] NQ 0 THEN BEGIN ERRJUMP("FILE MUST NOT CONTAIN SEQUENCE NUMBERS$"); END LMARGIN=FILLFIRST; RMARGIN=FILLRIGHT; LEFTRIGHT = FALSE; IF NONDEFAULT THEN # USE LINPTR1, LINPTR2 # BEGIN REGLINE[RNGTOPREG]=LINPTR1-1; REGLINE[RNGBOTREG]=MIN(LINPTR2+1,LINPTR1+LIMIT); END ELSE # SEARCH FOR PARAGRAPH # BEGIN POSZ(LINPTR1); IF NOTEXT THEN RETURN; # NO TEXT ON THIS LINE # WHYLE CURRENT GR TOPF(CURFILE) AND NOT NOTEXT DO BEGIN # LOOK BACK FOR BLANK # BAKZ; IF USRBRK NQ 0 THEN RETURN; END REGLINE[RNGTOPREG]=CURRENT; POSZ(LINPTR1); WHYLE CURRENT LS BOTF(CURFILE) AND NOT NOTEXT DO BEGIN # LOOK FORWARDS FOR BLANK # FWDZ; IF USRBRK NQ 0 THEN RETURN; END REGLINE[RNGBOTREG]=CURRENT; END POSZ(REGLINE[RNGTOPREG]+1); FOR FILLLOOP=FILLLOOP WHILE CURRENT LS REGLINE[RNGBOTREG] AND CURRENT GR REGLINE[RNGTOPREG] AND USRBRK EQ 0 DO BEGIN IF CURRENT GR REGLINE[RNGTOPREG]+1 THEN BEGIN # LOOK BACK FOR START PARA # BAKZ; IF NOTEXT THEN LMARGIN=FILLFIRST; ELSE LMARGIN=FILLLEFT; FWDZ; END IF LENGTH(LIN) GR EDITFIELD THEN # KILL PROTECTED # BEGIN SETCHAR(LINE,EDITFIELD,CENDLINE); TRIMPAD; REPX; END IF LENGTH(LIN) GR 0 THEN # NORMALIZE SPACING # BEGIN TMP1=0; # CURSOR # TMP2=LMARGIN; # NUMBER OF EXPECTED BLANKS # TMP3=0; # FLAG FOR CHANGES MADE # WHYLE TMP1 LS LENGTH(LIN) DO BEGIN # FIRST CHECK AND COMPRESS BLANKS BEFORE WORD # TMP4=TMP1; GETCHAR(LINE,TMP4,TMP5); WHYLE TMP5 EQ CBLANK DO # SPAN BLANKS BEFORE WORD # BEGIN TMP4=TMP4+1; GETCHAR(LINE,TMP4,TMP5); END TMP4=TMP4-TMP1; # NUMBER OF BLANKS # IF TMP4 GR TMP2 THEN # NEED LESS SPACING # BEGIN LSHIFT(LIN,TMP1+TMP4-TMP2,TMP4-TMP2); TMP3=1; # FLAG CHANGE # END IF TMP4 LS TMP2 THEN # NEED MORE SPACING # BEGIN RSHIFT(LIN,TMP1,TMP2-TMP4); FOR TMP3=1 STEP 1 UNTIL TMP2-TMP4 DO SETCHAR(LINE,TMP1+TMP3-1,CBLANK); TMP3=1; END # SECOND SCAN ACROSS WORD TO SET NEW BLANK EXPECTATION # TMP1=TMP1+TMP2; # POINT TO WORD # GETCHAR(LINE,TMP1,TMP5); WHYLE TMP5 NQ CBLANK AND TMP5 NQ CENDLINE DO BEGIN TMP4=TMP5; # NEED TO KNOW LAST CHARACTER OF WORD # TMP1=TMP1+1; GETCHAR(LINE,TMP1,TMP5); END IF TMP4 EQ CPERIOD OR TMP4 EQ CEXCLAM OR TMP4 EQ CQUESTION OR TMP4 EQ XLTDSPINT[CCOLON] THEN TMP2=2; ELSE TMP2=1; END IF TMP3 NQ 0 THEN BEGIN TRIMPAD; REPX; END END IF LENGTH(LIN) EQ RMARGIN OR NOTEXT THEN BEGIN # SKIP PERFECT OR BLANK LINE # FWDZ; TEST FILLLOOP; END IF LENGTH(LIN) GR RMARGIN THEN BEGIN # SPLIT THIS LINE TO SHORTEN # TMP1=RMARGIN; GETCHAR(LINE,TMP1,TMP2); WHYLE TMP2 NQ CBLANK AND TMP1 GR 0 DO BEGIN # LOOK BACK FOR BLANK # TMP1=TMP1-1; GETCHAR(LINE,TMP1,TMP2); END IF TMP1 GR LMARGIN THEN # SPLIT AND WORK ON SECOND HALF # BEGIN CHRPTR3=TMP1+1; DOSPLIT(1); IF RIGHTJUST[0] THEN GOTO JUSTIFY; # IF RIGHT JUSTIFY NEEDED # END ELSE FWDZ; # ALL ONE WORD - JUST MOVE ON # TEST FILLLOOP; END IF LENGTH(LIN) LS RMARGIN AND CURRENT EQ REGLINE[RNGBOTREG]-1 THEN BEGIN # CANNOT ENLARGE LAST SO SKIP # FWDZ; TEST FILLLOOP; # THIS ACTUALLY TERMINATES LOOP # END IF LENGTH(LIN) LS RMARGIN AND CURRENT LS REGLINE[RNGBOTREG]-1 THEN BEGIN # TRY TO ADD WORDS FROM NEXT # COPYLIN(LIN,TTYLIN); # TTYLIN = CURRENT LINE # FWDZ; # READ UP NEXT LINE # IF NOTEXT THEN TEST FILLLOOP; # NEXT PARAGRAPH # TMP1=0; GETCHAR(LINE,0,TMP2); WHYLE TMP2 EQ CBLANK DO BEGIN # SPAN LEADING BLANKS # TMP1=TMP1+1; GETCHAR(LINE,TMP1,TMP2); END TMP3=TMP1; # KEEP START OF WORD # WHYLE TMP2 NQ CBLANK AND TMP2 NQ CENDLINE DO BEGIN # SPAN WORD # TMP1=TMP1+1; GETCHAR(LINE,TMP1,TMP2); END TMP4=LENGTH(TTYLIN); GETCHAR(TTYLINE,TMP4-1,TMP5); # DETERMINE SPACING # IF TMP5 EQ CPERIOD OR TMP5 EQ CEXCLAM OR TMP5 EQ CQUESTION OR TMP5 EQ XLTDSPINT[CCOLON] THEN TMP5=2; ELSE TMP5=1; # ADD WORD IF ROOM FOR OLD LINE, BLANKS, AND WORD # IF (LENGTH(TTYLIN)) + (TMP5) + (TMP1-TMP3-1) LQ RMARGIN THEN BEGIN # CAN ADD ONE WORD # FOR TMP2=1 STEP 1 UNTIL TMP5 DO # ADD 1 OR 2 BLANK # BEGIN SETCHAR(TTYLINE,TMP4,CBLANK); TMP4=TMP4+1; END FOR TMP2=TMP3 STEP 1 UNTIL TMP1-1 DO # ADD ONE WORD # BEGIN GETCHAR(LINE,TMP2,TMP5); SETCHAR(TTYLINE,TMP4,TMP5); TMP4=TMP4+1; END SETCHAR(TTYLINE,TMP4,CENDLINE); BAKZ; # RETURN TO CURRENT LINE # COPYLIN(TTYLIN,LIN); TRIMPAD; REPX; # SAVE ENLARGED LINE # FWDZ; # EXTRACT FROM NEXT LINE # GETCHAR(LINE,TMP1,TMP2); WHYLE TMP2 EQ CBLANK DO # KILL LEADER, WORD, TRAILER # BEGIN TMP1=TMP1+1; GETCHAR(LINE,TMP1,TMP2); END LSHIFT(LIN,TMP1,TMP1); TRIMPAD; IF LENGTH(LIN) EQ 0 THEN DELX; # DEL AND BACKUP IF EMPTIED # ELSE # UPDATE IF STILL EXIST # BEGIN REPX; # UPDATE REMAINDER OF NEXT LINE # BAKZ; # TO ORIG TO TRY ANOTHER WORD # END END # NOTE - IF NO-OP-ED, WE ARE ALREADY ADVANCED ONE LINE # ELSE IF RIGHTJUST[0] THEN GOTO JUSTIFY; TEST FILLLOOP; END JUSTIFY: # ALIGN WORDS TO RIGHT MARGIN # BAKZ; COPYLIN(LIN,TTYLIN); TMP2 = 0; # NUMBER OF WORDS/BLANKS ADDED # TMP1 = RMARGIN - LENGTH(TTYLIN); FOR TMP3 = LMARGIN STEP 1 UNTIL LENGTH(TTYLIN) DO BEGIN GETCHAR(TTYLINE,TMP3,TMP5); IF TMP5 EQ CBLANK THEN TMP2 = TMP2 + 1; END IF TMP2 EQ 0 THEN BEGIN # IF NO SPACES DO NOT JUSTIFY # FWDZ; TEST FILLLOOP; END TMP3 = TMP1/TMP2; # COMPUTE NUMBER OF BLANKS # TMP4 = TMP1-TMP2*TMP3; # NUMBER TIMES INSERTED # LEFTRIGHT = NOT LEFTRIGHT; FOR TMP5 = LMARGIN STEP 1 UNTIL RMARGIN DO BEGIN SETCHAR(LINE,TMP5,CBLANK); END IF LEFTRIGHT THEN BEGIN # IF FROM LEFT TO RIGHT # TMP6 = LMARGIN; FOR TMP5 = LMARGIN STEP 1 UNTIL LENGTH(TTYLIN)-1 DO BEGIN GETCHAR(TTYLINE,TMP5,TMP2); SETCHAR(LINE,TMP6,TMP2); IF TMP2 EQ CBLANK AND TMP1 NQ 0 THEN BEGIN IF TMP4 EQ 0 THEN TMP3 = TMP3 - 1; TMP6 = TMP6 + TMP3 + 1; TMP4 = TMP4 - 1; TMP1 = TMP1 - TMP3; END TMP6 = TMP6 + 1; END END ELSE BEGIN # JUSTIFY FROM RIGHT TO LEFT # TMP6 = RMARGIN - 1; FOR TMP5 = LENGTH(TTYLIN)-1 STEP -1 UNTIL LMARGIN DO BEGIN GETCHAR(TTYLINE,TMP5,TMP2); SETCHAR(LINE,TMP6,TMP2); IF TMP2 EQ CBLANK AND TMP1 NQ 0 THEN BEGIN IF TMP4 EQ 0 THEN TMP3 = TMP3 - 1; TMP6 = TMP6 - TMP3 - 1; TMP4 = TMP4 - 1; TMP1 = TMP1 - TMP3; END TMP6 = TMP6 - 1; END END SETCHAR(LINE,RMARGIN,CENDLINE); REPX; FWDZ; END # OF LOOP # IF SCREENMODE THEN POSZ(REGLINE[RNGTOPREG]+1); ELSE BEGIN LINPTR1=REGLINE[RNGTOPREG]+1; LINPTR2=REGLINE[RNGBOTREG]-1; LIMIT=LARGENUM; EXECNDX=EXECST"TYPE"; DORANGE; END END # OF DOFILL # PAGE # MAIN CODE FOR FSECMDS # PROC SNGLMOV; BEGIN # ** SNGLMOV - COMMAND PROCESSOR FOR COPY AND MOVE. * * ENTRY COMMAND PROCESSOR HAS RECOGNIZED VERB. * TOKEN ADVANCED BUT NO OTHER SCANNING DONE. * TOKENTYPE, SCANPOS, TOKENPOS, ETC - AS ABOVE. * CURFILE, CURSPLIT, CURRENT - DEFAULT ADDRESS. * CHARRANGE - CHARACTER OR LINE RANGE BOUNDS. * SCREENMODE - FINAL POSITIONING/PRINTING. * WIDTH - THIS SETTING WILL BE IGNORED. * DONTPRINT - LINE MODE ECHO OF RESULTS. * BLANKS - THIS SETTING WILL BE IGNORED. * * EXIT CURFILE, CURRENT - FINAL RESTING PLACE. * (ANOTHER FILE MAY HAVE BEEN OPENED) * SMALLFIELD - TRUE. * * CALLS FLDLEN, SCANNER, FITNUM, MAKEFET, REWIND, RETERN, * PUSH, DORANGE, SPLICE, POP, WRITER, READ, TABFN, * DOSPLIT, BAKZ, XFRCMIN, SQUELCH, TRIMPAD, SETLNUM, * INSX, DOJOIN, POSZ, VFYLOCK. * * USES LINPTR1-3, CHRPTR1-3, FILPTR1-3, LINNUM1-3, * LINCTR, LIMIT, MOVEFET, FILEBUF. * * NOTE USES THEN RESTORES - LINENO. # ITEM LEN; SCANNER; IF FIELDTARGET NQ 0 THEN CHRPTR3=NUMWIDBLK+TABFN(FIELDTARGET-1); IF EXECNDX EQ EXECST"MOVE" THEN BEGIN # IF MOVE COMMAND # VFYLOCK; IF SCANMARK THEN KILLMARKS = TRUE; END CURFILE = = FILPTR3; VFYLOCK; CURFILE = = FILPTR3; IF NUMBERED[FILPTR3] NQ 0 AND CHARRANGE AND LINPTR1 NQ LINPTR2 AND LIMIT GR 1 THEN ERRJUMP("FILE MUST NOT CONTAIN SEQUENCE NUMBERS$"); CURFILE = = FILPTR3; POSZ(LINPTR3); # GET FAMILIAR WITH TARGET # FITNUM; # ASSURE NUMBERED MODE IS OK # CURFILE = = FILPTR3; IF CHARRANGE AND LINPTR1 EQ LINPTR2 AND LINPTR1 EQ LINPTR3 THEN BEGIN # PHRASE WITHIN LINE # POSZ(LINPTR1); IF LENGTH(LIN) EQ 0 THEN BEGIN SETCHAR(LINE,0,CBLANK); SETCHAR(LINE,1,CENDLINE); END COPYLIN(LIN,TTYLIN); CHRPTR1=MIN(CHRPTR1,LENGTH(LIN)-1); CHRPTR2=MIN(CHRPTR2,LENGTH(LIN)-1); LEN=CHRPTR2-CHRPTR1+1; RSHIFT(LIN,CHRPTR3,LEN); FOR LINCTR=0 STEP 1 UNTIL LEN-1 DO BEGIN GETCHAR(TTYLINE,CHRPTR1+LINCTR,LINPTR2); IF CHRPTR3+LINCTR LQ BUFCM1 THEN SETCHAR(LINE,CHRPTR3+LINCTR,LINPTR2); END # NO TRUNCATION AT EDITFIELD HERE SINCE THIS IS CONSIDERED TO # # BE AN IN-PLACE ALTERATION RATHER THAN A CREATION OF NEW TEXT. # SETCHAR(LINE,BUFCHAR,CENDLINE); NEWCURSOR=CHRPTR3; IF FILCMDNDX EQ FILCMDST"MOVE" THEN BEGIN IF CHRPTR3 LS CHRPTR1 THEN CHRPTR2=CHRPTR2+LEN; ELSE IF CHRPTR3 GR CHRPTR2 THEN NEWCURSOR=CHRPTR3-LEN; ELSE NEWCURSOR=CHRPTR1; LSHIFT(LIN,CHRPTR2+1,LEN); END TRIMPAD; REPX; IF FILCMDNDX EQ FILCMDST"COPY" THEN BEGIN # IF MARK MAY NEED TO BE MOVED # IF CHRPTR3 LQ MRKCHAR[1] THEN BEGIN # IF SECOND MARK MUST BE MOVED # MRKCHAR[1] = MRKCHAR[1]+LEN; IF CHRPTR3 LQ MRKCHAR[0] THEN BEGIN # IF FIRST MARK MUST BE MOVED # MRKCHAR[0] = MRKCHAR[0]+LEN; END END END IF NOT (SCREENMODE OR DONTPRINT) THEN PRINTL; RETURN; END FLDLEN(LOC(MAXADDR)+4); SMALLFIELD=FALSE; MAKEFET(MOVEFET,"ZZZMOVE",FILEBUF,INIDSKSIZ); REWIND(MOVEFET,1); SAVLINENO=LINENO; PUSH; # SAVE TARGET ADDRESS # IF FILCMDNDX EQ FILCMDST"MOVE" AND CHARRANGE THEN BEGIN IF LINPTR2 EQ LINPTR3 THEN CHRPTR3=MAX(0,CHRPTR3-(CHRPTR2-CHRPTR1+1)); DORANGE; # COPY RANGE TO ZZZMOVE # IF FOUND THEN SPLICE; # CLOSE BOUNDARIES TOGETHER # END ELSE DORANGE; # COPY RANGE TO ZZZMOVE # POP; # TO TARGET AREA # LINENO=SAVLINENO; WRITER(MOVEFET,1); REWIND(MOVEFET,1); IF NOT FOUND THEN RETURN; KILLUPLOW=FALSE; IF CURFILE NQ FILPTR3 AND ASCII[CURFILE] GQ 2 AND ASCII[FILPTR3] LQ 1 THEN BEGIN # IF CHARACTER SETS ARE INCOMPATIBLE, CHANGE CHARSET OF EMPTY # # TARGET FILE, OR FLAG CASE SUPPRESSION # IF BOTF(FILPTR3)-TOPF(FILPTR3)-1 EQ THISEXTEND AND ASCII[FILPTR3] EQ 0 THEN ASCII[FILPTR3]=ASCII[CURFILE]; ELSE KILLUPLOW=TRUE; END CURFILE=FILPTR3; READ(MOVEFET,0); # START FEEDING BUFFER # NUMWIDBLK=0; IF NUMBERED[CURFILE] NQ 0 THEN NUMWIDBLK=NUMWIDTH+BLANKS; SAVBLANKS=BLANKS; BLANKS=0; LINPTR3=CURRENT+1; # TAKE NOTE OF RELOCATED TARGET # IF BOTF(CURFILE)-TOPF(CURFILE)-1 EQ THISEXTEND THEN BEGIN # IF TARGET FILE IS EMPTY # CHARRANGE = FALSE; FIELDTARGET = 0; END IF CHARRANGE OR FIELDTARGET NQ 0 THEN BEGIN # FIRST SEGMENT INTO MIDDLE OF LINE # DOSPLIT(0); # SPLIT TARGET AT CHRPTR3 # BAKZ; # INSERTION AFTER FIRST HALF # LINPTR3=CURRENT; END FOR LINCTR=1 STEP 1 WHILE LINCTR LQ LCOUNT AND NOT (CANINTER AND USRBRK NQ 0) DO BEGIN IF USRBRK NQ 0 THEN DONTPRINT=TRUE; XFRCMIN; IF KILLUPLOW THEN SQUELCH(LIN); IF EDITFIELD LS LENGTH(LIN) THEN BEGIN SETCHAR(LINE,EDITFIELD,CENDLINE); # CLEAR TO END OF LINE # TRIMPAD; END LINENO=LINENO+INCR; SETLNUM; INSX; IF NOT (DONTPRINT OR SCREENMODE) THEN PRINTL; END IF CHARRANGE OR FIELDTARGET NQ 0 THEN BEGIN IF CHARRANGE AND FILCMDNDX EQ FILCMDST"COPY" THEN BEGIN # IF MARK MAY NEED TO BE MOVED # IF LINPTR3 EQ REGLINE[MARKREG] AND CHRPTR3 LQ MRKCHAR[0] THEN BEGIN # IF FIRST MARK MUST BE MOVED # REGLINE[MARKREG] = CURRENT; MRKCHAR[0] = MRKCHAR[0] - CHRPTR3 + LENGTH(LIN); END ELSE IF LINPTR3 EQ REGLINE[MARKREG+1] AND CHRPTR3 LQ MRKCHAR[1] THEN BEGIN # IF SECOND MARK MUST BE MOVED # REGLINE[MARKREG+1] = CURRENT; MRKCHAR[1] = MRKCHAR[1] - CHRPTR3 + LENGTH(LIN); END END CHRPTR3 == ZERO; # ASSURE NO EXTENSION IN MERGES # DOJOIN(0); # MERGE LAST INSERT WITH TRAILER # CHRPTR3 == ZERO; # RESTORE TARGET CHARACTER ADDRESS # PUSH; POSZ(LINPTR3); DOJOIN(0); # MERGE LEADER WITH FIRST INSERT # POP; NEWCURSOR = CHRPTR3; END IF SCREENMODE THEN POSZ(LINPTR3); # POSITION TO TOP OF BLOCK # BLANKS=SAVBLANKS; RETERN(MOVEFET,1); FLDLEN(LOC(WORKBUF)+DSKSIZ+4); SMALLFIELD=TRUE; END # OF SNGLMOV # PROC HELPCMD; BEGIN # ** HELPCMD - COMMAND PROCESSOR FOR HELP FACILITY. * * ENTRY PROCESSNDX - INDICATES HELP OR TEACH COMMAND. * NO SCANNING BEYOND COMMAND VERB YET. * TOKEN CALLED TO PREPARE NEXT SCAN. * SCANPOS, TOKENPOS, TOKENTYPE, ETC - AS ABOVE. * SCREENMODE - PRINTING/POSITIONING MODE. * * EXIT HELP FILE BECOMES CURRENT FILE. * CURRENT, CURFILE, CURSPLIT - AS ABOVE. * * MACROS SETCHAR. * * CALLS MAKEFET, GET, ATTACH, OPENFILE, SCNEQNAME, SCNEOC, * DORANGE, POSZ, SETUPSCREEN, HALT. * * USES LINPTR1-3, LINNUM1-3, FILPTR1-3, CHRPTR1-3, * PFMFET, FILEBUF, READNAM, FILNUM, CHARPARM, GETPARM, * LOCSTRING1, EXECNDX, WORDSEARCH, ELLIPSIS, DONTPRINT, * UPPERSEARCH, FOUND. # READNAM="FSEHELP"; IF PROCESSNDX EQ KEYST"TCMD" THEN READNAM="FSTEACH"; IF NOT ASSGNFILE(READNAM) THEN BEGIN IF READNAM EQ "FSEHELP" THEN BEGIN PF("ATTACH",READNAM,READNAM,"RC",PFMERROR,"M","R","UN", HELPUSERNUM,"NA","YES","SR","NF","PN","0",0); END ELSE BEGIN C<0,1>READNAM="T"; # LOOK FOR FILE FOR THIS MODEL # C<1,6>READNAM=C<0,6>TABMODNAME; PF("GET","FSTEACH",READNAM,"RC",PFMERROR,"UN",HELPUSERNUM, "PN","0",0); READNAM="FSTEACH"; IF PFMERROR NQ 0 THEN BEGIN # IF SPECIFIC FILE NOT FOUND # PF("GET",READNAM,READNAM,"RC",PFMERROR,"UN",HELPUSERNUM, "PN","0",0); END END END FILNUM=CURFILE; IF FILENAM[FILNUM] NQ READNAM THEN BEGIN FILNUM=1; IF SCREENMODE AND PROCESSNDX EQ KEYST"HCMD" THEN BEGIN # IF SCREEN MODE HELP # FILNUM = 2; # SPLIT SCREEN MODE # ERRSTRING = "USE 'EDIT' TO UNSPLIT SCREEN$"; END ELSE BEGIN # LINE MODE OR TEACH # ERRSTRING = "USE 'EDIT' TO RETURN TO INITIAL FILE$"; END CHARPARM=2; GETPARM=0; OPENFILE; END POSZ(TOPF(FILNUM)+1); # DEFAULT TO TOP OF FILE # IF SYNTAXCHAR[TOKENCHAR] THEN BEGIN # TOPIC SEARCH RATHER THAN DEFAULT # IF TOKENTYPE EQ TYPST"LETTER" THEN BEGIN # IF CHARACTER STRING # SCNEQNAM(READNAM); SCNEOC; SETCHAR(LOCSTR1,0,CLPAREN); LINPTR2=B<0,6>READNAM; FOR LINPTR1=0 STEP 1 WHILE LINPTR1 LQ 6 AND LINPTR2 NQ " " DO BEGIN SETCHAR(LOCSTR1,LINPTR1+1,LINPTR2); LINPTR2=B<6*LINPTR1+6,6>READNAM; END SETCHAR(LOCSTR1,LINPTR1+1,CRPAREN); END ELSE BEGIN # NOT ALPHABETIC # LINPTR2 = TOKENCHAR; SETCHAR(LOCSTR1,0,CLPAREN); SETCHAR(LOCSTR1,1,LINPTR2); SETCHAR(LOCSTR1,2,CRPAREN); LINPTR1 = 1; TOKEN; IF SYNTAXCHAR[TOKENCHAR] THEN ERRJUMP("PLEASE ENTER 'HELP DIRECTIVE'$"); END SETCHAR(LOCSTR1,LINPTR1+2,CENDLINE); LOCSTRLEN1=LINPTR1+2; LINPTR1=CURRENT; LINPTR3=CURRENT; LINPTR2=BOTF(FILNUM)-1; LIMIT=1; EXECNDX=EXECST"LOCATE"; WORDSEARCH=FALSE; ELLIPSIS=FALSE; DONTPRINT=TRUE; UPPERSEARCH=FALSE; CHRPTR1=0; CHRPTR2=BUFCM1; DORANGE; # SEARCH FOR (KEYWORD) # IF NOT FOUND THEN POSZ(LINPTR3); FOUND=TRUE; END IF NOT SCREENMODE THEN BEGIN LINPTR1=CURRENT; LINPTR2=BOTF(FILNUM)-1; LIMIT=HELPSIZE; # HELP FILE LINES TO DISPLAY # EXECNDX=EXECST"TYPE"; DONTPRINT=FALSE; DORANGE; END IF FILNUM EQ 2 THEN BEGIN IF SPLITFILE[2] NQ 2 THEN SETUPSCREEN(1,2,USRSPLTSZ); END END # OF HELPCMD # PROC GETSTATUS; BEGIN # ** GETSTATUS - COMMAND PROCESSOR FOR GET STATUS SUBCOMMAND. * * ENTRY COMMAND FULLY SCANNED EXCEPT TERMINATOR VERIFY. * ONE OR BOTH FILE BRACKETS OPENED SOMEWHERE. * * EXIT SCREENMODE SCHEDULED FOR TOTAL REPAINT. * COMMAND TERMINATOR SCANNED. * OPEN FILES UPDATED INTO DIRECTORY. (SIDE EFFECT) * * CALLS SCNEOC, BGNDSPLAY, TTSTR, EOLDSPLAY, PUSH, * PADNAME, CLOSEFILE, POSZ, SCANFDL, TTST, FWDZ, POP, * TTDEC, TTCHAR, ENDDSPLAY, TABFN. * * USES FILNUM, READNAM, LINPTR1, LINCTR. * * NOTE - * * THIS BLOCK OF CODE IS SUBJECT TO CERTAIN RESTRICTIONS IN * ORDER TO DRIVE THE TERMINAL IN BOTH LINE MODE AND SCREEN * MODE. TTLIN CANNOT BE USED. THE ONLY ALLOWABLE WAY TO * ADVANCE TO A NEW LINE OF OUTPUT IS TO CALL EOLDSPLAY AS * A LOGICAL REPLACEMENT FOR TTBRK. EOLDSPLAY WILL IN TURN * USE EITHER TTBRK (FOR LINE MODE) OR VDTPOS (SCREEN MODE) * TO CONTROL THE OUTPUT DEVICE. BGNDSPLAY IS USED TO INIT * THE DISPLAY AND ENDDSPLAY CLEANS UP AFTERWARD. EOLDSPLAY * INCLUDES SCREEN-OVERFLOW LOGIC. # ITEM TMP1, TMP2, TMP3, TMP4, TMP5; BASED ARRAY KEYLIN[0:99]; ITEM KEYLINE; PROC DSPLFKEY(WHICH); BEGIN ITEM WHICH; ITEM TMP1, TMP2; P=LOC(FKEYSTRING[WHICH]); IF WHICH LS 0 THEN TTSTR(" SHIFT F$"); ELSE TTSTR(" F$"); TTDEC(ABS(WHICH)); IF ABS(WHICH) LS 10 THEN TTSTR(" $"); TTSTR(" $"); TTST(FKEYNAME[WHICH],6); TTSTR(" $"); FOR TMP1=0 STEP 1 UNTIL 15 DO BEGIN IF TMP1 LS LENGTH(KEYLIN) THEN BEGIN GETCHAR(KEYLINE,TMP1,TMP2); TMP2=XLTINTDSP[TMP2]; C<0,1>TMP2=C<9,1>TMP2; TTST(TMP2,1); END ELSE TTSTR(" $"); END END # OF DSPLFKEY # # ACTUAL GETSTATUS CODE STARTS HERE # SCNEOC; BGNDSPLAY; TTSTR(" $"); TTSTR(" EDITOR STATUS INFORMATION:$"); EOLDSPLAY; EOLDSPLAY; TTSTR(" FILES: NAME LOCK CHANGE $"); TTSTR("CHARSET NUMBERED SIZE POSITION$"); EOLDSPLAY; PUSH; FOR FILNUM=1 STEP 1 UNTIL 2 DO BEGIN IF PADNAME(FILENAM[FILNUM]) NQ " " THEN CLOSEFILE; END POSZ(TOPC(FILECTL)+1); WHYLE CURRENT LS BOTC(FILECTL) DO BEGIN SCANFDL(READNAM); IF READNAM NQ "ZZZNULL" THEN BEGIN IF CURRENT EQ FDLF(CURFILE) THEN BEGIN # IF CURRENT FILE, INDICATE # TTSTR(" (CURRENT) $"); END ELSE BEGIN # JUST ANOTHER FILE # TTSTR(" $"); END FOR FILNUM=0 STEP 1 UNTIL 6 DO TTST(CREADNAM,1); TTST(YESORNO[SCNFDLOCK],7); TTST(YESORNO[SCNFDCHNG],7); TTST(CHARTYPE[SCNFDASCI],7); TTST(YESORNO[SCNFDNUMB],7); TTLPAD(SCNFDSIZE,7," "); TTLPAD(SCNFDCURF,7," "); EOLDSPLAY; END FWDZ; END POP; EOLDSPLAY; TTSTR(" SET VIEW IN: $"); TTDEC(DFINBGN); TTSTR(" $"); TTDEC(DFINEND); TTSTR(" $"); TTSTR(" TAB COLUMNS: $"); LINPTR1=TABFN(1); FOR LINCTR=1 STEP 1 WHILE LINCTR LQ USERTABS AND LINPTR1 NQ 0 DO BEGIN TTDEC(LINPTR1+1); TTSTR(" $"); LINPTR1=TABFN(LINCTR+1); END EOLDSPLAY; TTSTR(" SET VIEW WARN: $"); TTDEC(WIDTH); TTSTR(" $"); TTSTR("SET UNDO: $"); IF AUDITOFF THEN TTSTR(" NO$"); ELSE TTSTR("YES$"); TTSTR(" $"); TTSTR("TAB CHARACTER: $"); TTCHAR(TABCHAR,TRUE); TTSTR(" $"); TTSTR("CNTRL CHRS: $"); TTCHAR(UNPRINT,TRUE); EOLDSPLAY; TTSTR(" SET VIEW EDIT: $"); TTDEC(EDITFIELD); TTSTR(" $"); TTSTR("SET JUMP: $"); IF AUTOINDENT THEN TTSTR("YES$"); ELSE TTSTR(" NO$"); TTSTR(" $"); TTSTR("SET WORD FILL: $"); TTDEC(FILLLEFT+1); TTSTR(" $"); TTDEC(FILLRIGHT+1); TTSTR(" $"); TTDEC(FILLFIRST+1); TTSTR(" JUSTIFY:$"); IF RIGHTJUST[0] THEN TTSTR(" YES$"); ELSE TTSTR(" NO$"); EOLDSPLAY; TTSTR(" SEARCH STRING: '$"); FOR TMP1=0 STEP 1 UNTIL LOCSTRLEN1-1 DO BEGIN GETCHAR(LOCSTR1,TMP1,TMP2); TTCHAR(TMP2,FALSE); END IF ELLIPSIS THEN BEGIN TTSTR("'..'$"); FOR TMP1=0 STEP 1 UNTIL LOCSTRLEN2-1 DO BEGIN GETCHAR(LOCSTR2,TMP1,TMP2); TTCHAR(TMP2,FALSE); END END TTSTR("'$"); EOLDSPLAY; IF SCREENMODE THEN BEGIN EOLDSPLAY; TTSTR(" FUNCTIONS: KEY$"); TTSTR(" LABEL DIRECTIVES $"); TTSTR(" KEY LABEL DIRECTIVES$"); FOR TMP1=1 STEP 1 UNTIL POSFKEYS DO BEGIN TMP2=0; P=LOC(FKEYSTRING[TMP1]); FOR TMP4=0 STEP 1 UNTIL LENGTH(KEYLIN)-1 DO BEGIN GETCHAR(KEYLINE,TMP4,TMP5); IF TMP5 NQ CBLANK THEN TMP2=1; END TMP3=0; P=LOC(FKEYSTRING[-TMP1]); FOR TMP4=0 STEP 1 UNTIL LENGTH(KEYLIN)-1 DO BEGIN GETCHAR(KEYLINE,TMP4,TMP5); IF TMP5 NQ CBLANK THEN TMP3=1; END IF TMP2 NQ 0 OR FKEYNAME[TMP1] NQ " " OR TMP3 NQ 0 OR FKEYNAME[-TMP1] NQ " " THEN BEGIN EOLDSPLAY; TTSTR(" $"); DSPLFKEY(TMP1); IF TMP3 NQ 0 OR FKEYNAME[-TMP1] NQ " " THEN DSPLFKEY(-TMP1); END END END ENDDSPLAY; END # OF GETSTATUS # PROC UNDOCMD; BEGIN # ** UNDOCMD - COMMAND PROCESSOR FOR UNDO FACILITY. * * ENTRY COMMAND SCANNED EXCEPT TERMINATOR VERIFY. * CURA(AUDITCTL) AT MOST RECENT CHANGE RECORD. * TOPA(AUDITCTL) BOUNDS AUDIT TRAIL. * NUMMARKS - WHETHER MARKS ARE CURRENTLY ON. * * EXIT COMMAND TERMINATOR VERIFIED. * SELECTION OF OPENED FILES MAY CHANGE. * CURA(AUDITCTL) BACKED UP. * NUMMARKS - ZEROED. * * MACROS GETCHAR. * * CALLS ERRJUMP, AUDITSYNCH, POSZ, UNDODECODE, UNDOOPEN, * BAKZ, FATAL, PUSH, UNDOPOS, INSX, POP, DELX, REPX, * PAINTMARKS. * * USES AUDITOFF, AUDITUSED, LINPTR1, LINNUM1, LINNUM2, * LINNUM3, USRBRK. # IF SYNTAXCHAR[TOKENCHAR] THEN BEGIN # IF MORE SYNTAX # TOKEN; IF NUMMARKS NQ 0 THEN BEGIN # IF MARKS ACTIVE # PAINTMARKS(3); NUMMARKS=0; ERRSTRING="MARKS CANCELLED$"; END ELSE BEGIN # NO MARKS ACTIVE # ERRSTRING="NO MARK(S) ACTIVE$"; END SCNEOC; # SCAN FOR END OF COMMAND # RETURN; END SCNEOC; # SCAN FOR END OF COMMAND # IF AUDITOFF THEN ERRJUMP("SET UNDO YES - TO ENABLE UNDO$"); AUDITOFF=TRUE; AUDITSYNCH; # CLEAR STAGING BUFFER # AUDITUSED=FALSE; # NO CHKPT TRANSACT CANCELLED IN MIDDLE # POSZ(CURA(AUDITCTL)); GETCHAR(LINE,0,LINPTR1); IF LINPTR1 EQ CLETTERC THEN # ACCESS PREVIOUS FILES # BEGIN UNDODECODE(1,LINNUM1); # FIRST FILE # UNDODECODE(12,LINNUM2); # SECOND FILE # UNDODECODE(23,LINNUM3); # SCREEN SPLIT # UNDOOPEN(1,LINNUM1); UNDODECODE(12,LINNUM1); UNDOOPEN(2,LINNUM1); BAKZ; END GETCHAR(LINE,0,LINPTR1); WHYLE CURRENT GR TOPA(AUDITCTL) AND LINPTR1 NQ CLETTERC AND LINPTR1 NQ CLETTERE AND USRBRK EQ 0 DO BEGIN UNDODECODE(1,LINNUM1); UNDODECODE(12,LINNUM2); UNDODECODE(23,LINNUM3); IF LINNUM2 NQ FDLF(LINNUM1) THEN UNDOOPEN(LINNUM1,LINNUM2); IF LINPTR1 EQ CLETTERD THEN BEGIN BAKZ; PUSH; UNDOPOS(-1); INSX; POP; END ELSE IF LINPTR1 EQ CLETTERI THEN BEGIN PUSH; UNDOPOS(+1); DELX; POP; END ELSE IF LINPTR1 EQ CLETTERR THEN BEGIN BAKZ; PUSH; UNDOPOS(0); REPX; CURF(CURFILE)=CURF(CURFILE)-1; POP; END BAKZ; GETCHAR(LINE,0,LINPTR1); END CURA(AUDITCTL)=CURRENT; CURF(CURFILE)=MAX(MIN(CURF(CURFILE)+1,BOTF(CURFILE)-1),TOPF(CURFILE)); POSZ(CURF(CURFILE)); AUDITOFF=FALSE; NEWCURSOR = 0; END # OF UNDOCMD # PROC WORDCMD; BEGIN # ** WORDCMD - COMMAND PROCESSOR FOR WORD PROCESSING. * * ENTRY COMMAND VERB SCANNED, TOKEN ADVANCED FOR NEXT. * USUAL DEFAULTS AVAILABLE. (CURRENT, ETC.) * * EXIT COMMAND PROCESSED. * * CALLS VFYLOCK, TOKEN, ERRJUMP, SCANNER, * DOFILL. * * USES LCOUNT, SCANPOS, KEYWDTYPE. # IF TOKENTYPE NQ TYPST"LETTER" OR KEYWDNDX LS 0 THEN ERRJUMP("CHARACTER SEQUENCE NOT RECOGNIZED$"); LCOUNT=KEYWDNDX; TOKEN; # ADVANCE TO NEXT SYNTAX # SCANNER; VFYLOCK; IF NOT FOUND THEN RETURN; # OUT OF BOUNDS # IF LCOUNT EQ KEYST"WFIL" THEN BEGIN DOFILL; NEWCURSOR=0; RETURN; END ELSE IF LCOUNT EQ KEYST"WCEN" THEN BEGIN EXECNDX=EXECST"CENTER"; DORANGE; RETURN; END END # OF WORDCMD # END TERM