PROGRAM SPELL C C+ C This is a spelling checker program for the DEC RSX-11M operating C system. C C C USE: >SPELL filename[/switches] or C >SPE C SPE>filename[/switches] C SPE>^Z C > C C C TO BUILD: C @SPELL (please use the command file) C C RESTRICTIONS: C DICTIONARY on SP: (reset in tskbld file for your system) C Random access file will take about 900 blocks C FORTRAN-77 used for compilation (uses character routines) C Task image size will be about 105 blocks C Short error messages will be included in task image C /NOCK/NOTR is used to increase speed C Virtual arrays are used for letter index blocks(=6500words) C thus a partition of at least 39k C Hard coded to use [7,7] for the dictionary C RSX Executive calls are made C C Author: Jeff Hamilton C E-Systems C P. O. Box 1056 C Greenville, Texas 75401 C (214)454-4175 C C Date: January 13,1982 C C Revisions: C 1.1 Include quick check (/Q) C 1.2 Include debug capability C 1.3 Include FORTRAN comment checking (/F) C 1.4 Include hyphenated words that end line C 2.0 Letter index block into virtual memory C 2.1 Recoded sections where most of the time C is spent to increase the speed. C 2.2 Include terse comments to screen (/T) C 2.3 Include numbers in tokens as valid words (/N) C 2.4 Include switch for short words (/S:x) C 2.5 Include switch for auto load of words (/L) C 2.6 Include filename for auto load switch C 2.7 Change uic from [2,2] to [3,3] to avoid C interference with some TECO library. C 2.8 Include VT100 as default with change to VT52 (/V) C 2.9 Include CR as screen refresh command in interactive C 3.0 Open new file with old file size so no extends C 3.1 Display more than 80 char; blank lines are ok C 3.2 Bugfix (replace can have space imbedded) C 3.3 Improve Dict. compare method C 4.0 Include provisions for look up using ...DCT C 4.1 Include switch for words must have vowels C 4.2 Include command for skip n lines (+n) C 4.3 Debug/Optimize - Macro routines (27% improvement) C 4.4 Reformat displays / skip lines switch (/N:x) C 4.5 Bite the bullet - now uses overlays PARAMETER (VERSN=4.5) C C This program is written in FORTRAN-77 and was developed C on a PDP-11/t55 with 6-RK05, running RSX. It's applicability C to other systems is unknown. Some of the later ideas C were stolen from the RT-11 speller from the Spring 81 RT-tape C (give credit where credit is due). This program came C from a desire on my part to have a program that could be C used to check my copy for the DECUS North Texas Local Users C Group Newsletter. The only spelling checker I could find C was the one included in the Software Tools section of C the Spring 81 RSXSIG tape. As I didn't want to build software C tools, I used the data base as a starting point for C program development. As sequential reads were too slow for the C upwards of 42,000 words in the data base, I used Marge Knox's C analysis of the file access speeds of FORTRAN-IV+ (now FORTRAN-77). C Random Access - block i/o was decided on to minimize the C time for disk io. Using Ralph Stammerjohn's Index to the C past RSXSIG tapes, I was able to come up with Phil Cannon's C routines for FCS file access to the FDB. This enabled C me to build the dictionary (using DICTMK) using random access C block io, set the size, and truncate to last block used C on exit. (see DICTMK.FTN) C To help speed file writes on interactive checking C the routine GETSIZ is used to open the new file with the same C size as the old file to eliminate extends. This routine is C from the Copious library from GR Johnson of Battelle Northwest. C There are a lot of good routines in this collection, if you C haven't looked into them, you should. GETVER which returns C the version of an open file is used in DICTMK. Wild card C file specs are possible in GETSIZ as well as in a routine from C Copious which will delete files. C As this was written when I was not nearly familiar with C F77 as I should be, it is not efficient in space. It probably C can be rewritten to speed it up too. The Spelling Checker C is written to be run from a VT100 type terminal unless the C VT52 switch is used (/V) or the quick check is used. (see DISPLA C subroutine). It uses standard RSX utility type prompts and C GETMCR command. The file name to be checked is entered. C Each line is read, parsed for each word and each word is checked C for spelling. The order of operation is as follows: C C Get next line C End of file on input? C If so C Sort output list C Output list to file C Exit C If not C End of current line? C If so, get next line C If not C Get next word C Is word shorter than the smallest word we need to check? C If so, get next word C If not C Is the word a normal standard word (is, and, the...)? C If so get next word. C If not C Is word in misspelled previously list? C If so, correct line and get next word. C If not C Is word in previously denoted as correct list? C If so, get next word. C If not C Is word in previously denoted as correct and add to dictionary? C If so, get next word. C If not C Is word in dictionary? C If so, get next word. C If not C Is quick check being used? C If so, add word to addlist, get next word C If not C Display word and line C Get command C Is command redraw screen ()? C If so, redraw screen, get command C If not C Is command add to dictionary (a)? C If so, add to addlist, get next word C If not C Is command next word (n)? C If so, get next word C If not C Is command skip n lines (+n)? C If so, skip n lines, get first word in line C If not C Is command exit (x)? C If so, process file as if end of document C If not C Is command quit (q)? C If so C Copy input lines to output making changes as needed, exit C If not C Is command exchange word (e)? C If so C Get right word C Make correction in line C Get next word C If not C Is command new line (l)? C If so C Get new line C Get first word in line C If not C Is command ignore short words (#)? C If so, set length to check to # C If not C Is command correct but do not add (c)? C If so, add to correct-list, get next word. C If not C Is command wrong spelling (w)? C If so C Get right spelling C Make correction in line C Add words to lists C Get next word C If not C Is command terse screen display (t)? C If so, from now on display less C If not C Is command verbose screen display (v)? C If so, from now on display more C If not C Is command look up in dictionary (d)? C If so, send packet to ...DCT C Get packet from ...DCT C Redo screen C Get command again C If not, sytax error C C In non quick mode, as the document is checked a new C file (same name, version+1) is written with the line read, C corrections made. When a misspelled word is designated C and correction made, every occurrence of that misspelling from C then on in that document will be corrected, but not reported C to the terminal. C C To minimize reads of the disk, the structure of the random C access file (RAF) is: C Block 1 - table of contents C starting block number (N) and number of blocks (M) C for each starting letter for each word C Block N - starting block for each letter pointed to C by the table of contents C Block N-1 - index for each starting letter C first five letters of the first word in each C block used to minimize reads C C Therefore one read is done at the beginning to read the table C of contents. The index blocks for all the letters are read C and stored in virtual memory to reduce the number of reads C while processing the document. C The index block contains the first five letters of the C first word of each block that follows that has only C words with the same first letter. This is cross-referenced C to the block numbers. That block is read and depending on boundary C conditions, the previous block or next block is read. This C continues until the correct block is read and checked. C C With the addition of the Dictionary look up C routine (...DCT) certain permutations of the misspelled word C can be checked. Four types of common misspellings are C checked for. Each of the letters are deleted in turn in case C there is one too many letters. Pairs of letters are transposed C incase a transposition has occured. A through Z are added C to the word between each of the letters in case a letter C was left out. Each of letters are replaced with A through Z C in case a wrong letter was used. During these four C checks if the resultant word is in the dictionary raf file C it is included in an internal list. This list can hold C twenty words (seems big enough for normal words). C Timing tests show it should take less than 30 seconds to do C all of this on a quiet system. The test for the word C "electrocardiograk" took 32.8 seconds and only "electrocardiogram" C was found. The user is then prompted for which one to return C to the SPELL program. "0" returns the original word. C If the original word is returned SPELL will redraw the C screen and prompt again for a command. C C The prototype of this program would read the document C to be checked and put each different word in a list C to be checked by the dictionary and those misspelled C written out to a file. This worked somewhat C allright for small files, but the larger the file the more C time that was spent checking against the list for each word C to insure the word was not already included. C Even small files yielded 500 different words to be checked. C This was before the index for each letter was included and C therefore checking consisted on the average of 30 reads for C each word. C C Thanks go to Conrad Schlundt of Mostek for his steering me C to 'Computer Programs for Detecting and Correcting Spelling C Errors' by James Petterson of U. T. Austin from "Communications C of the ACM" Dec, 1980. This document confirmed many of my C assumptions and helped to validate many of the strategies involved C in the document processing. C C Note: For the quick check the list lengths are adjusted C so that the ALIST essentially becomes four times as long C as its normal size. This can be done because CLIST, WLIST, C and WLIST2 are not used and the length of ALIST will just C overlay this memory space. Thus 4*LISTLN words can be C stored. THIS IS NOT GOOD FORTRAN PROGRAMMING PRACTICE C AND SHOULD NOT BE USED AS A GENERAL RULE. C- C PARAMETER (IBUFSZ=512) !NUMBER OF BYTES IN BLOCK PARAMETER (LISTLN=100) !MAX WORDS IN LIST C LOGICAL*1 PROMPT, EOL, INLIST, INDICT, DEBUG, QUICK LOGICAL*1 FOUND, FORTRN, VOWEL LOGICAL*1 TERSE, NUMBER, LOAD, VT52, VT100, GOTWRD BYTE MCRLIN(80), LINE(255), FILE(40), DFILE(32) BYTE CONTNS(IBUFSZ), LUNDAT(12), INDXS, RDLINE(255) BYTE FDB(128), IN(2), COMMND, LFILE(40) BYTE BRWORD(25) VIRTUAL INDXS(512,26) INTEGER*2 START, SIZE, IDFILE, UNIT, DIRDEV, GETSIZ INTEGER*2 WHERE, WLISTL, CLISTL, ALISTL, IFDB, INTSIZ INTEGER*2 PLINE, LINSKP, NUMSKP INTEGER*2 IMCR, ILINE, IFILE, IRDLIN INTEGER*2 IBRWOR, IIN, ILFILE INTEGER*4 LOCAT(2,26), NWORDS, TOTLIN, LINRED CHARACTER*5 NLIST(90) !ADJUST THIS IF WORDS ARE ADDED CHARACTER*25 WORD, RWORD C C THE NEXT TWO LINES MUST APPEAR AS WRITTEN BECAUSE THE C LENGTH OF ALIST MAY BE ADJUSTED TO COVER THE OTHER 4 ARRAYS C CHARACTER*25 ALIST(LISTLN), CLIST(LISTLN) CHARACTER*25 WLIST(LISTLN), WLIST2(LISTLN) C C EQUIVALENCES C EQUIVALENCE (LOCAT(1,1),CONTNS(1)) EQUIVALENCE (FDB(1),IFDB) !MUST BE ON EVEN BOUNDRY EQUIVALENCE (DFILE(1),IDFILE) !MUST BE ON EVEN BOUNDRY EQUIVALENCE (BRWORD(1),RWORD) !BYTE AND CHAR LINEUP EQUIVALENCE (LUNDAT(3),UNIT) EQUIVALENCE (LUNDAT(5),DIRDEV) EQUIVALENCE (IMCR,MCRLIN(1)) EQUIVALENCE (ILINE,LINE(1)) EQUIVALENCE (IFILE,FILE(1)) EQUIVALENCE (IRDLIN,RDLINE(1)) EQUIVALENCE (IBRWOR,BRWORD(1)) EQUIVALENCE (IIN,IN(1)) EQUIVALENCE (ILFILE,LFILE(1)) C C DATA STATEMENTS C DATA START/1/SIZE/2/ DATA DFILE/'S','P','0',':','[','7',',','7',']','D','I','C','T' 1,'.','R','A','F',15*0/ DATA LFILE/40*0/ C C PROGRAM FOLLOWS C CALL ERRSET(29,.TRUE.,.FALSE.,.TRUE.,.FALSE.,15) !NO SUCH FILE DEBUG=.FALSE. PROMPT=.FALSE. FOUND=.FALSE. QUICK=.FALSE. LOADLN=0 CALL GETMCR(MCRLIN,IDS) IF(IDS.GT.0)CALL GETFIL(MCRLIN, FILE, FOUND, QUICK 1, FORTRN, TERSE, NUMBER, LOWEST, LOAD, LFILE 2, VT52, VT100, VOWEL, LINSKP) IF(FOUND)GO TO 20 10 WRITE(3,1070) READ(3,1000,END=210)IDS,(MCRLIN(I),I=5,IDS+5) PROMPT=.TRUE. MCRLIN(1)='S' MCRLIN(2)='P' MCRLIN(3)='E' MCRLIN(4)=' ' CALL GETFIL(MCRLIN, FILE, FOUND, QUICK, FORTRN 1, TERSE, NUMBER, LOWEST, LOAD, LFILE, VT52, VT100 2, VOWEL, LINSKP) IF(.NOT.FOUND)GO TO 10 20 CONTINUE C C ADJUST LENGTH OF ALIST SINCE WE WILL BE USING ONLY THIS C LIST. ** NOT GOOD PROGRAMMING PRACTICE ** C LISTLL=LISTLN IF(QUICK)LISTLL=LISTLN*4 ALISTL=0 WLISTL=0 CLISTL=0 CALL FNDNOR(NLIST,NLISTL,LNLIST) !LOAD THE NORMAL LIST CALL ASNLUN(4,'SY',0) !USE CURRENT SY: CALL ASNLUN(3,'TI',0) !USE CURRENT TERMINAL CALL ASNLUN(1,'SY',0) !USE CURRENT SY: C C IF AUTO LOAD SWITCH THEN OPEN LOAD FILE AND PUT WORDS C FROM FILE INTO ADD LIST. IF NO FILE CONTINUE. IF NUMBER C OF WORDS IN LOAD FILE GREATER THAN LISTLN GO TO QUICK MODE. C IF(LOAD)THEN OPEN(UNIT=1,FILE=LFILE,STATUS='OLD' 1 ,CARRIAGECONTROL='LIST',READONLY,ERR=40) 30 READ(1,1010,END=50)WORD IF(ALISTL.GT.LISTLL)THEN IF(ALISTL.GT.4*LISTLN)THEN WRITE(3,1160) CALL EXIT END IF LISTLL=LISTLN*4 QUICK=.TRUE. WRITE(3,1140) END IF CALL ADDLST(ALIST,ALISTL,WORD,LISTLL) GO TO 30 40 WRITE(3,1150)LFILE GO TO 60 50 CLOSE(UNIT=1) LOADLN=ALISTL 60 CONTINUE END IF C C FILL IN THE DEVICE ATTACHED TO LUN=2 INTO THE C FILE NAME OF THE DICTIONARY FILE. THIS IS SET IN C THE TASKBUILD FILE. IT MUST BE DONE SINCE THE PARSE C ROUTINE BELOW WILL FILL IN SY0: FOR THE DEVICE IF THE C DEVICE IS NOT GIVEN. C CALL GETLUN(2,LUNDAT,IDS) DFILE(1)=LUNDAT(1) DFILE(2)=LUNDAT(2) UNIT=IAND(UNIT,7) DIRDEV=IAND(DIRDEV,8) IF(DIRDEV.EQ.0)THEN WRITE(3,1130) CALL EXIT END IF ENCODE(1,1020,DFILE(3))UNIT C C IF THERE IS AN ERROR IN THE EXECUTION OF THIS PROGRAM THE C NEW FILE WILL BE DELETED AND THE OLD ONE KEPT, IF THERE C IS NO ERROR THEN THE NEW ONE KEPT. C INTSIZ=-GETSIZ(4,FILE) !GET SIZE OF FILE OPEN(UNIT=4,FILE=FILE,STATUS='OLD',CARRIAGECONTROL='LIST' 1,ERR=220,READONLY,RECL=255,RECORDTYPE='VARIABLE') IF(.NOT.QUICK)THEN TOTLIN=0 70 READ(4,1000,END=80)NN,(LINE(I),I=1,NN) IF(NN.GT.250)THEN !ONLY ALLOW 250 CHAR/LINE WRITE(3,1170) CALL EXIT END IF TOTLIN=TOTLIN+1 GO TO 70 80 REWIND(4) END IF CALL CLEAR(LINE,255) IF(.NOT.QUICK)OPEN(UNIT=1,FILE=FILE,STATUS='NEW' 1,CARRIAGECONTROL='LIST',DISPOSE='DELETE',RECL=255 2,RECORDTYPE='VARIABLE',INITIALSIZE=INTSIZ) CALL INIT(FDB) !CLEAR FDB FOR RAF IN(1)='41'O !READONLY,SHARED READING IN(2)=1 !BLOCK MODE CALL PARSE(FDB,DFILE,2) !PUT NAME AND LUN=2 INTO FDB IER=0 !MAKE SURE NO ERROR CALL FIND(FDB,IER) !FILE EXIST? IF(IER.LT.0)GO TO 190 !NO CALL OFID(FDB,IN,2,IER) !OPEN BY FILE ID IF(IER.LT.0)GO TO 200 !ERROR DURING OPEN CALL DABRD(FDB,CONTNS,IBUFSZ,1,NBT,IER) !READ INDEX CALL INDXFL(INDXS,LOCAT,FDB) !FILL THE INDEX BLOCKS IN VM LINRED=0 !NUMBER OF LINES READ NWORDS=0 !NUMBER OF WORDS PROCESSED DO 85,NUMSKP=1,LINSKP LINRED=LINRED + 1 READ(4,1000,END=170)NL,(LINE(I),I=1,NL) !SKIP DOWN TO WHERE WE ARE IF(.NOT.QUICK)WRITE(1,1000)NL,(LINE(I),I=1,NL)!YES, WRITE OUT 85 CONTINUE IF(NL.GT.0)CALL CLEAR(LINE,NL) !CLEAR OUT BUFFER C C**** GET NEXT LINE C PLINE=1 90 CONTINUE PLINE=PLINE-1 READ(4,1000,END=170)NL,(LINE(I),I=1,NL) !GET NEW LINE EOL=.TRUE. IF(NL.GT.250)THEN WRITE(3,1170) CALL EXIT END IF LINRED=LINRED+1 !HOW MANY LINES WE READ DO 100,I=1,NL !COPY LINE FOR USE LATER ON 100 RDLINE(I)=LINE(I) NLR=NL IF(NL.GT.0)CALL LOWER(LINE,NL) !MAKE LOWER CASE FOR CHECKING IPNTR=1 !BEGINING OF LINE C C**** GET NEXT WORD C 110 IF((LINE(1).EQ.'c'.AND.FORTRN).OR.((.NOT.FORTRN) 1.AND.(PLINE.LE.0)))CALL GETWRD(LINE, NL, WORD 2, NW, IPNTR, EOL, DEBUG, FORTRN, NUMBER, VOWEL) IF(EOL)THEN !END-OF-LINE? IF(.NOT.QUICK)WRITE(1,1000)NLR,(RDLINE(I),I=1,NLR)!YES, WRITE OUT IF(NL.GT.0)CALL CLEAR(LINE,NL) !CLEAR OUT BUFFER IF(NLR.GT.0)CALL CLEAR(RDLINE,NLR) !CLEAR OUT BUFFER GO TO 90 !GET NEXT LINE END IF NWORDS=NWORDS+1 !HOW MANY WORDS PROCESSED IF(NW.LE.LOWEST)GO TO 110 !IGNORE THE SMALLER WORDS IF(DEBUG)WRITE(3,1030)LOWEST,NW C C IS WORD IN THE NORMAL LIST? C IF(NW.LE.LNLIST)THEN !IF WORD>LONGEST WORD, NOT IN DO 120,I=1,90 IF(WORD(1:5).EQ.NLIST(I))GO TO 110 120 CONTINUE END IF C C IS WORD IN THE WRONG LIST? C IF(WLISTL.GT.0)THEN CALL CKLIST(WLIST,WLISTL,WORD,INLIST,WHERE) IF(INLIST)THEN CALL CRCTLN(RDLINE,NLR,WORD,WLIST2,WHERE 1 ,DEBUG) !CORRECT LINE GO TO 110 !GET NEXT WORD END IF END IF C C IS WORD IN THE CORRECT BUT DON'T ADD TO DICT LIST? C 130 IF(CLISTL.GT.0)THEN CALL CKLIST(CLIST,CLISTL,WORD,INLIST,WHERE) IF(INLIST)GO TO 110 !GET NEXT WORD END IF C C IS THE WORD IN THE CORRECT AND ADD TO THE DICT LIST? C IF(ALISTL.GT.0)THEN CALL CKLIST(ALIST,ALISTL,WORD,INLIST,WHERE) IF(INLIST)GO TO 110 !GET NEXT WORD END IF C C WORD IS NOT IN ANY LISTS, THEREFORE CHECK THE DICTIONARY. C CALL CKDICT(FDB,LOCAT,WORD,INDICT,DEBUG,INDXS) IF(INDICT)GO TO 110 !GET NEXT WORD C C OK, WORD IS NOT FOUND C IF(QUICK)THEN CALL ADDLST(ALIST,ALISTL,WORD,LISTLL) GO TO 110 !GET NEXT WORD END IF C C DISPLAY SCREEN INFO IN EITHER TERSE OR VERBOSE MODES C AND GET THE COMMAND. C 140 CALL DISPLA(RDLINE,NLR,WORD,COMMND,LINRED,TOTLIN 1,NWORDS,ALISTL,CLISTL,WLISTL,DEBUG,VERSN,TERSE 2,VT52,VT100,NUMBER, PLINE, LOWEST, VOWEL) IF(PLINE.GT.0)GO TO 90 C C PROCESS COMMAND C IF(COMMND.EQ.'a')THEN !WORD IS RIGHT AND ADD TO DICT CALL ADDLST(ALIST,ALISTL,WORD,LISTLL)!ADD TO LIST GO TO 110 !NEXT WORD ELSE IF(COMMND.EQ.'n')THEN !NEXT WORD GO TO 110 ELSE IF(COMMND.EQ.'x')THEN !EXIT GO TO 170 ELSE IF(COMMND.EQ.'e')THEN !EXCHANGE WORD WRITE(3,1050) CALL CLEAR(BRWORD,25) READ(3,1000,END=170)NBRW,(BRWORD(I),I=1,NBRW)!GET CORRECT WORD CALL CRCTLN(RDLINE,NLR,WORD,BRWORD,1,DEBUG)!CORRECT LINE WORD=RWORD !CHECK THIS WORD GO TO 130 ELSE IF(COMMND.EQ.'l')THEN !NEW LINE 150 WRITE(3,1060) !PROMPT READ(3,1000,END=170)NL,(LINE(I),I=1,NL) !GET NEW LINE IF(NL.GT.250)THEN WRITE(3,1170) CALL EXIT END IF IF(NL.EQ.0)GO TO 150 !AT LEAST SOMETHING DO 160,I=1,NL !MAKE COPY 160 RDLINE(I)=LINE(I) NLR=NL CALL LOWER(LINE,NL) !MAKE ALL LOWER CASE IPNTR=1 !RESET POINTER TO START GO TO 110 !GET NEXT WORD ELSE IF(COMMND.EQ.'c')THEN !CORRECT BUT DON'T ADD CALL ADDLST(CLIST,CLISTL,WORD,LISTLL) !ADD TO LIST GO TO 110 !NEXT WORD ELSE IF(COMMND.EQ.'w')THEN !WRONG SPELLING WRITE(3,1040) !PROMPT FOR RIGHT WORD CALL BLANK(BRWORD,25) !GET RID OF LAST ONE READ(3,1000,END=170)NBRW,(BRWORD(I),I=1,NBRW)!GET CORRECT SPELLING CALL ADDLST(WLIST,WLISTL,WORD,LISTLL) !ADD TO WRONG LIST N=WLISTL-1 !WLISTL WAS CHANGED CALL ADDLST(WLIST2,N,RWORD,LISTLL) !ADD TO RIGHT LIST CALL CRCTLN(RDLINE,NLR,WORD,WLIST2,WLISTL,DEBUG) III=INDEX(RWORD,' ') WORD=RWORD(1:III-1) !CHECK NEW WORD GO TO 130 !TEST NEW WORD ELSE IF(COMMND.GE.'1'.AND.COMMND.LT.'9')THEN DECODE(1,1020,COMMND)LOWEST !SET SMALLEST WORD GO TO 130 !GET NOTHER COMMAND ELSE WRITE(3,1100) !SYNTAX ERROR CALL MARK(6,2,2) !SET EFN=6 AFTER 2 SECONDS CALL STOPFR(6) !WAIT FOR EFN=6 GO TO 140 !GET RIGHT COMMAND END IF C C FINISHED WITH THE DOCUMENT C 170 CONTINUE CALL CLOS(FDB) !CLOSE RAF IF(.NOT.QUICK)CLOSE(UNIT=1,ERR=190,DISPOSE='KEEP') IF(QUICK)CLOSE(UNIT=1,DISPOSE='DELETE') CLOSE(UNIT=4,DISPOSE='KEEP') !KEEP ORIGINAL IF(VT52)WRITE(3,1180)'33'O,'33'O !CLR SCRN IF(VT100)WRITE(3,1190)'33'O,'33'O !CLR SCRN C C THE NEXT TWO STATEMENTS WILL CAUSE ...DCT TO EXIT IF IT IS ALIVE C CALL CLEAR(WORD,25) CALL GETDCT(WORD,GOTWRD,VT52,VT100,TERSE,NUMBER) IF(ALISTL-LOADLN.GT.0)THEN !WRITE WORDS TO BE ADDED CALL SORT(ALIST(LOADLN+1),ALISTL-LOADLN)!SORT IN ALPHA ORDER IF(QUICK)OPEN(UNIT=4,FILE='SPELL.WRD',STATUS='NEW' 1 ,CARRIAGECONTROL='LIST') IF(.NOT.QUICK)OPEN(UNIT=4,FILE='DICT.ADD',STATUS='NEW' 1 ,CARRIAGECONTROL='LIST') DO 180,I=1+LOADLN,ALISTL 180 WRITE(4,1010)ALIST(I) CLOSE(UNIT=4) IF(QUICK)WRITE(3,1110) !TELL WHICH ONE IF(.NOT.QUICK)WRITE(3,1120) !...WAS WRITTEN END IF IF(PROMPT)GO TO 10 !GET NOTHER FILENAME CALL EXIT 190 WRITE(3,1080) CALL EXIT 200 WRITE(3,1090)IER 210 CALL EXIT 220 WRITE(3,1150)FILE CALL EXIT 1000 FORMAT(Q,255A1) 1010 FORMAT(A25) 1020 FORMAT(I1) 1030 FORMAT(1X,'LWST=',I2,/,1X,'NW=',I2) 1040 FORMAT('$Correction>>') 1050 FORMAT('$Exchange>>') 1060 FORMAT('$New line>>') 1070 FORMAT(/,'$SPE>') 1080 FORMAT(' SPE - DICTIONARY FILE NOT FOUND') 1090 FORMAT(' SPE - ERROR OPENING DICT = ',I6) 1100 FORMAT(' SPE - SYNTAX ERROR') 1110 FORMAT(' SPE - Not found words saved in SPELL.WRD') 1120 FORMAT(' SPE - Add words saved in DICT.ADD') 1130 FORMAT(' SPE - LUN=2 NOT DIRECTORY DEVICE') 1140 FORMAT(' SPE - SPELL.DCT > LISTLN; QUICK WILL BE USED.') 1150 FORMAT(' SPE - ',40A1,' NOT FOUND') 1160 FORMAT(' SPE - SPELL.DCT > LISTLL. SPELL EXITING') 1170 FORMAT(' SPE - RECORD > 250 BYTES') 1180 FORMAT(1X,A1,'H',A1,'J',/,' SPE - End of document') 1190 FORMAT(1X,A1,'[0;0H',A1,'[0J',/,' SPE - End of document') END