10 ! ----- SPELL_DIR:SPELL.BAS ----- ! ----- SPELLING CORRECTION PROGRAM ----- ! ----- Last Change 01/14/93 by Brian Lomasky ----- ! ! ----- Note: SPELL.EXE must NOT be installed with BYPASS or ----- ! ----- SYSPRV. The SPELL_DIR:SPELL.DAT general dictionary ----- ! ----- must have W:RE protection and SPELL_DIR:SPELL.EXE ----- ! ----- must have W:E protection. ----- ! OPTION TYPE = EXPLICIT ! FORCE DECLARATIONS ON ERROR GOTO ERROR_ROUTINE ! ENABLE ERROR TRAPPING %INCLUDE "$DVIDEF" %FROM %LIBRARY "SYS$LIBRARY:BASIC$STARLET" ! ----- SYSTEM SERVICE ERROR CODES AND FUNCTION VALUES ----- EXTERNAL LONG CONSTANT SS$_NORMAL ! NORMAL STATUS DECLARE WORD CONSTANT TRUE = (1% = 1%) DECLARE WORD CONSTANT FALSE = NOT TRUE ! ----- TO RETURN ERROR (0) OR SUCCESS (1) IN $STATUS BUT HAVE ----- ! ----- NO VMS MESSAGE DISPLAYED ON THE SCREEN, ALSO SET BIT 28 ----- ! ----- (HEX 10000000) IN THE VALUE YOU PASS TO SYS$EXIT ----- DECLARE LONG CONSTANT ERROR_WITH_NO_MSG = X"10000000"L DECLARE LONG CONSTANT SUCCESS_WITH_NO_MSG = X"10000001"L DECLARE STRING CONSTANT VALID_LETTERS = & "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'" ! ----- BASIC ERROR CODES ----- DECLARE WORD CONSTANT BUCKET_LOCKED = 154% DECLARE WORD CONSTANT CONTROL_C_TRAP = 28% DECLARE WORD CONSTANT DUPLICATE_KEY = 134% DECLARE WORD CONSTANT END_OF_FILE = 11% DECLARE WORD CONSTANT FILE_ATTRS_NOT_MATCHED = 160% DECLARE WORD CONSTANT ILLEGAL_FILE_NAME = 2% DECLARE WORD CONSTANT NO_SUCH_FILE = 5% DECLARE WORD CONSTANT REC_NOT_FOUND = 155% DECLARE WORD CONSTANT RECORD_ATTRS_NOT_MATCHED = 228% RECORD DVIBUF ! $GETDVIW RECORD WORD BUFFER_LENGTH1 WORD ITEM_CODE1 LONG BUFFER_ADDRESS1 LONG RETURN_LENGTH_ADDRESS1 LONG LIST_TERMINATOR END RECORD DVIBUF DECLARE WORD ALL_UPPERCASE ! TRUE IF WORD IS ALL UPPERCASE DECLARE STRING BOLD_VIDEO ! ESCAPE SEQUENCE FOR BOLD VIDEO DECLARE STRING CHARACTER ! CHARACTER READ FROM INPUT_LINE DECLARE STRING CLEAR_SCREEN ! ESCAPE SEQUENCE TO CLEAR SCRN DECLARE LONG COL ! SCREEN COLUMN NUMBER DECLARE STRING COMMAND_STRING ! FOREIGN DCL COMMAND STRING DECLARE WORD COMMAND_STRING_LENGTH ! LENGTH OF FOREIGN DCL COMMAND DECLARE WORD CORRECTED_WORD_INDEX ! INDEX INTO CORRECTED_WORDS() DIM STRING CORRECTED_WORDS(500%, 1%) ! USER-CORRECTED WORDS DECLARE WORD CORRECTED_WORD_TOT ! NUMBER OF CORRECTED WORDS DECLARE WORD CORRECTIONS_MADE ! TRUE IF ANY CORRECTIONS MADE DECLARE WORD CURSOR_POSITION ! CURSOR POSITION ON PRINT LINE DECLARE LONG DEVICE_TYPE_LENGTH ! LENGTH OF DEVICE_TYPE DECLARE WORD DICT_CHANNEL ! DICTIONARY CHANNEL NUMBER DECLARE WORD DICTIONARY_CHANNEL ! DICTIONARY CHANNEL NUMBER DIM STRING DICTIONARY_NAME(1%) ! DICTIONARY NAMES DIM STRING DICT_WORDS(50%) ! DICTIONARY SEARCH WORDS DECLARE WORD DISPLAY_MENU_OPTIONS ! TRUE TO DISPLAY MENU OPTIONS DECLARE WORD DONE_CHECKING_WORD ! TRUE IF DONE CHECKING WORD DECLARE DVIBUF DVIITEM ! EQUATE GETDVIW RECORD DECLARE WORD EOF_FLAG ! TRUE IF END-OF-FILE REACHED DECLARE STRING ERROR_LINE ! ERROR LINE DESCRIPTION DECLARE WORD EVE_SPELL ! TRUE IF SPELL CHECKING EVE DOC DECLARE WORD FIRST_LETTER_LOCATION ! POSITION OF WORD'S 1ST LETTER DECLARE WORD FIRST_CAPITAL ! TRUE IF FIRST LETTER CAPITAL DECLARE STRING FIRST_WORD ! FIRST WORD TO BE PRINTED DECLARE WORD FOUND_MATCH ! TRUE IF FOUND MATCHING WORD DECLARE STRING HYPHENATED_CHARACTERS ! HYPHENATED CHARACTERS DECLARE WORD HYPHEN_FLAG ! TRUE IF HYPHENATED WORD FOUND DECLARE STRING INCORE_WORDS ! LIST OF INCORE WORDS DECLARE STRING INCORRECT_WORDS ! LIST OF PREVIOUSLY-WRONG WORDS DECLARE STRING INCORRECT_WORD_RESPONSE ! USER RESPONSE FOR BAD WORD DECLARE STRING INPUT_FILE ! INPUT FILESPEC DECLARE STRING INPUT_LINE ! INPUT LINE READ FROM FILE DECLARE STRING INPUT_LINE_PREV1 ! PREVIOUS INPUT LINE DECLARE STRING INPUT_LINE_PREV2 ! PREVIOUS INPUT LINE DECLARE WORD LAST_LETTER_LOCATION ! POSITION OF WORD'S LAST LETTER DECLARE STRING LAST_NON_BLANK_CHARACTER ! LAST NON-BLANK CHARACTER READ DECLARE STRING LAST_WORD ! LAST WORD TO BE PRINTED DECLARE WORD LETTER_FOUND ! TRUE IF A LETTER WAS FOUND DECLARE LONG LIB_STATUS ! SYSTEM SERVICE EXIT STATUS DECLARE LONG LINE_COUNTER ! COUNT OF LINES READ FROM FILE DECLARE WORD LOWEST_QUICK_WORD_INDEX ! INDEX OF LOWEST QUICK WORD DECLARE WORD LOWEST_QUICK_WORD_MATCH ! COUNT OF LOWEST QUICK MATCHES DECLARE WORD LOWEST_RECENT_WORD_INDEX ! INDEX OF LOWEST RECENT WORD DECLARE WORD LOWEST_RECENT_WORD_MATCH ! COUNT OF LOWEST RECENT MATCHES DECLARE LONG MAX_CHOICES ! NUMBER OF WORD CHOICES IN MEM DECLARE STRING NEW_WORD_SPELLING ! NEW SPELLING FOR BAD WORD DECLARE STRING NORMAL_VIDEO ! ESCAPE SEQUENCE FOR NORM VIDEO DECLARE STRING NUMERIC_EDIT ! EDIT VARIABLE FOR NUMERIC FUNC DECLARE WORD NUMERIC_TEMP ! TEMPORARY FOR NUMERIC FUNCTION DECLARE STRING OKAY_WORDS ! LIST OF WORDS THAT ARE OKAY DECLARE STRING OUTPUT_FILE ! USER-SPECIFIED OUTPUT FILESPEC DECLARE WORD POSITION_INDEX ! CHARACTER POSITION WITHIN LINE DECLARE WORD PREVIOUS_LINE_FLAG ! TRUE IF PREVIOUS LINE TO PRINT DECLARE WORD PRINT_ONLY_FIRST_BAD_WORD ! TRUE TO PRINT ONLY FIRST ERROR DECLARE WORD PRIV_FLAG ! TRUE IF PRIVILEGED USER DECLARE STRING PRIVATE_DICTIONARY ! OPENED PRIVATE DICTIONARY NAME DECLARE STRING PROGRAM_FUNCTION ! USER-SELECTED PROGRAM FUNCTION DECLARE WORD QUICK_WORD_COUNTER ! # OF ITEMS IN QUICK_WORDS() DECLARE WORD QUICK_WORD_INDEX ! INDEX INTO QUICK_WORD_STATUS() DIM STRING QUICK_WORDS(20%) ! LIST OF QUICK-MATCHED WORDS DIM WORD QUICK_WORD_STATUS(20%, 1%) ! STATUS OF QUICK-MATCHED WORDS ! ----- QUICK_WORD_STATUS( ,0) = COUNT OF MATCHES ----- ! ----- QUICK_WORD_STATUS( ,1) = -1 IF CORRECTLY SPELLED ----- ! ----- 0 IF INCORRECTLY SPELLED ----- ! ----- 1 IF SPELLED WAS FIXED ----- DECLARE WORD READ_NEXT_DICT_RECORD ! TRUE TO READ NEXT DICT RECORD DECLARE WORD RECENT_WORD_COUNTER ! # OF RECENT WORDS IN MEMORY DECLARE WORD RECENT_WORD_INDEX ! INDEX INTO RECENT_WORDS() DIM STRING RECENT_WORDS(30%) ! RECENTLY-FOUND WORDS DIM WORD RECENT_WORD_STATUS(30%, 1%) ! STATUS OF RECENTLY-FOUND WORDS ! ----- RECENT_WORD_STATUS( ,0) = COUNT OF MATCHES ----- ! ----- RECENT_WORD_STATUS( ,1) = 1 IF NOT YET VERIFIED, ----- ! ----- -1 IF CORRECTLY SPELLED, ----- ! ----- 0 IF INCORRECTLY SPELLED ----- DECLARE LONG RECORD_COUNTER ! COUNT OF PRINTED WORDS DECLARE LONG ROW ! SCREEN ROW NUMBER DECLARE WORD TEMP ! TEMPORARY WORD VARIABLE DECLARE LONG TEMP_LONG ! TEMPORARY LONG VARIABLE DECLARE LONG TEMP_LONG2 ! TEMPORARY LONG VARIABLE DECLARE STRING TEMP_STRING ! TEMPORARY STRING VARIABLE DECLARE LONG TEN_COUNTER ! COUNT OF 10 LINES READ DECLARE STRING TOTALS_ONLY_FLAG ! "T" TO PRINT ONLY TOTAL DECLARE STRING USER_ENTRY ! USER RESPONSE DECLARE STRING USER_OPTION ! USER RESPONSE DECLARE STRING WORD_FOUND ! ACTUAL EXTRACTED WORD DECLARE WORD WORD_FOUND_FLAG ! TRUE IF A WORD WAS FOUND DECLARE WORD WORD_LENGTH ! LENGTH OF WORD TO BE CHECKED DECLARE WORD WORD_STATUS ! -1=WORD CORRECTLY SPELLED ! 0=WORD INCORRECTLY SPELLED ! 1=UNKNOWN SPELLING DECLARE STRING WORD_TO_BE_CHECKED ! EXTRACTED WORD TO BE CHECKED DECLARE STRING WORD_TO_CHECK ! SPELL / CHECK WORD TO CHECK DECLARE STRING WORD_WITH_APOSTROPHE ! EXTRACTED WORD (INCL ANY ') MAP (GETDVI) LONG DEVICE_TYPE ! DEVICE TYPE FROM $GETDVIW MAP (SPL) STRING DICTIONARY_RECORD = 32%! DICTIONARY FILE MAP MAP (SPL) BYTE DICTIONARY_BYTES(31%) ! DICTIONARY FILE MAP EXTERNAL LONG FUNCTION LIB$GET_FOREIGN ! GET FOREIGN DCL COMMAND LINE EXTERNAL LONG FUNCTION SYS$EXIT ! EXIT PROGRAM WITH STATUS EXTERNAL LONG FUNCTION SYS$GETDVIW ! GET DEVICE INFORMATION / WAIT ! ----- LOCAL FUNCTION TO CHECK FOR NUMERIC DATA ----- ! ----- (RETURNS TRUE IF PASSED STRING CONTAINS ONLY NUMERIC DATA) ----- DEF WORD NUMERIC(STRING VALUE_TO_TEST) ! ----- REMOVE ANY SPACES ----- NUMERIC_EDIT = EDIT$(VALUE_TO_TEST, 136%) IF LEN(NUMERIC_EDIT) > 0% THEN NUMERIC = TRUE FOR NUMERIC_TEMP = 1% TO LEN(NUMERIC_EDIT) NUMERIC = FALSE IF POS("0123456789", & MID(NUMERIC_EDIT, NUMERIC_TEMP, & 1%), 1%) = 0% NEXT NUMERIC_TEMP ELSE NUMERIC = FALSE END IF END DEF ! ----- LOCAL FUNCTION TO SEARCH THE DICTIONARY FOR MATCHING WORDS ----- DEF WORD SEARCH_THE_DICTIONARY SEARCH_THE_DICTIONARY = FALSE ! ASSUME NO WORD CORRECTION WHILE TRUE PRINT PRINT "Enter starting characters to begin" + & " searching the dictionary with:" PRINT " (Press to start with the" + & " first word)" PRINT " (Or enter E if done searching dictionary) "; WHEN ERROR IN LINPUT FIRST_WORD USE FIRST_WORD = "~%(" CONTINUE END WHEN EXIT DEF IF FIRST_WORD = "~%(" ! ----- UPPERCASE AND DISCARD GARBAGE ----- FIRST_WORD = EDIT$(FIRST_WORD, 38%) FIRST_WORD = " " IF LEN(FIRST_WORD) = 0% FIRST_WORD = LEFT(FIRST_WORD, 32%) EXIT DEF IF FIRST_WORD = "E" PRINT PRINT "Enter ending characters to stop" + & " searching the dictionary at:" PRINT " (Or press to end with" + & " the last word) "; WHEN ERROR IN LINPUT LAST_WORD USE LAST_WORD = "~%(" CONTINUE END WHEN EXIT DEF IF LAST_WORD = "~%(" ! ----- UPPERCASE AND DISCARD GARBAGE ----- LAST_WORD = EDIT$(LAST_WORD, 38%) LAST_WORD = " " IF LEN(LAST_WORD) = 0% RECORD_COUNTER = 0% ! INIT COUNT OF WORDS ! ----- ACCESS BOTH DICTIONARIES ----- FOR DICT_CHANNEL = 3% TO 4% ! ----- SET FLAG SO AS TO SEQUENTIALLY ----- ! ----- READ THE DICTIONARY ----- READ_NEXT_DICT_RECORD = TRUE ITERATE IF RECORD_COUNTER >= 50% ! ----- LOCATE FIRST WORD TO BE DISPLAYED ----- WHEN ERROR IN FIND #DICT_CHANNEL, KEY #0% GE & FIRST_WORD USE IF ERR = BUCKET_LOCKED THEN SLEEP 1% RETRY END IF EXIT HANDLER IF ERR <> & REC_NOT_FOUND AND ERR & <> END_OF_FILE ! ----- SET FLAG SO AS TO SKIP ----- ! ----- READING DICTIONARY ----- READ_NEXT_DICT_RECORD = FALSE CONTINUE END WHEN ! ----- READ NEXT DICTIONARY RECORD ----- WHILE READ_NEXT_DICT_RECORD AND & RECORD_COUNTER < 50% WHEN ERROR IN ! ----- GET NEXT ----- ! ----- DICTIONARY RECORD ----- GET #DICT_CHANNEL USE IF ERR = BUCKET_LOCKED THEN SLEEP 1% RETRY END IF EXIT HANDLER IF ERR <> & END_OF_FILE ! ----- SET FLAG SO AS TO ----- ! ----- EXIT LOOP ----- READ_NEXT_DICT_RECORD = FALSE CONTINUE END WHEN ITERATE IF NOT READ_NEXT_DICT_RECORD ! ----- SKIP IF BLANK RECORD ----- ITERATE IF DICTIONARY_RECORD = " " IF LAST_WORD <> " " AND & DICTIONARY_RECORD > LAST_WORD THEN ! ----- SET FLAG SO AS TO ----- ! ----- EXIT LOOP ----- READ_NEXT_DICT_RECORD = FALSE ITERATE END IF RECORD_COUNTER = RECORD_COUNTER + 1% ! ----- SEE IF LOWERCASE ----- ! ----- CONVERSION REQD ----- IF ALL_UPPERCASE THEN TEMP = 99% ELSE TEMP = -1% END IF WHILE TEMP < & LEN(TRM$(DICTIONARY_RECORD)) & - 1% TEMP = TEMP + 1% ! ----- SEE IF FIRST ----- ! ----- LETTER SHOULD BE ----- ! ----- CAPITALIZED ----- ITERATE IF FIRST_CAPITAL& AND TEMP = 0% ! ----- LOWERCASE LETTER ----- SELECT DICTIONARY_BYTES(TEMP) CASE 65% TO 90% DICTIONARY_BYTES& (TEMP) =& DICTIONARY_BYTES& (TEMP) + 32% END SELECT NEXT ! ----- STORE WORD WITH CASE ----- ! ----- CHANGED (POSSIBLY) ----- DICT_WORDS(RECORD_COUNTER) = & TRM$(DICTIONARY_RECORD) NEXT NEXT DICT_CHANNEL IF RECORD_COUNTER = 0% THEN FIRST_WORD = "first" IF FIRST_WORD = "" LAST_WORD = "last" IF LAST_WORD = "" PRINT PRINT "*** No words found between " + & FIRST_WORD + " and " + LAST_WORD PRINT ITERATE END IF ! ----- DISPLAY ALL OF THE MATCHING WORDS ----- PRINT CLEAR_SCREEN ROW = 1% COL = 1% TEMP_LONG = RECORD_COUNTER TEMP = 0% WHILE TEMP < RECORD_COUNTER TEMP = TEMP + 1% IF CLEAR_SCREEN = "" THEN IF TEMP < 10% THEN PRINT " " + NUM1$(TEMP) & + ") " + & DICT_WORDS(TEMP) ELSE PRINT NUM1$(TEMP) + & ") " + & DICT_WORDS(TEMP) END IF ELSE ! ----- POSITION CURSOR TO ROW/COL ----- PRINT ESC + "[" + NUM1$(ROW) + & ";" + NUM1$(COL) + "H"; IF TEMP < 10% THEN PRINT " " + NUM1$(TEMP) & + ") " + & DICT_WORDS(TEMP) ELSE PRINT NUM1$(TEMP) + & ") " + & DICT_WORDS(TEMP) END IF TEMP_LONG = TEMP ROW = ROW + 1% IF ROW > 20% THEN ROW = 1% COL = COL + 40% IF COL > 70% THEN TEMP = 999% END IF END IF END IF NEXT FOUND_MATCH = TRUE WHILE FOUND_MATCH FOUND_MATCH = FALSE ! ----- SEE IF THE WORD CAN BE ----- ! ----- AUTO-CORRECTED FROM LIST ----- IF OUTPUT_FILE = "NL:" OR HYPHEN_FLAG THEN PRINT "Press to continue" ELSE PRINT "Press to" + & " continue, OR enter" + & " the number of the" + & " correct word" END IF WHEN ERROR IN LINPUT TEMP_STRING USE TEMP_STRING = "~%(" CONTINUE END WHEN EXIT DEF IF TEMP_STRING = "~%(" ! ----- UPPERCASE AND DISCARD GARBAGE ----- TEMP_STRING = EDIT$(TEMP_STRING, 38%) ITERATE IF TEMP_STRING = "" FOUND_MATCH = TRUE ITERATE IF LEN(TEMP_STRING) < 1% OR & LEN(TEMP_STRING) > 5% ITERATE IF NOT NUMERIC(TEMP_STRING) TEMP_LONG2 = INTEGER(TEMP_STRING, LONG) ITERATE IF TEMP_LONG2 < 1% OR & TEMP_LONG2 > TEMP_LONG FOUND_MATCH = FALSE ! ----- SET FLAG FOR WORD CORRECTION ----- SEARCH_THE_DICTIONARY = TRUE ! ----- STORE CORRECTED WORD ----- NEW_WORD_SPELLING = DICT_WORDS(TEMP_LONG2) EXIT DEF NEXT NEXT END DEF ! ----- DISPLAYS POSSIBLE SPELLINGS FOR A MISSPELLED WORD ----- ! ----- (WORD_WITH_APOSTROPHE) (RETURNS THE NUMBER OF POSSIBLE ----- ! ----- WORD CHOICES) ----- DEF LONG DISPLAY_POSSIBLE_SPELLINGS DISPLAY_POSSIBLE_SPELLINGS = 0% ! ASSUME NO WORD CHOICES ERROR_LINE = "DISPLAY POSSIBLE" RECORD_COUNTER = 0% ! INIT COUNT OF WORDS WORD_LENGTH = LEN(WORD_TO_BE_CHECKED) + 1% EXIT DEF IF WORD_LENGTH > 32% ! DONE IF KEY TOO LONG WHILE WORD_LENGTH > 0% WORD_LENGTH = WORD_LENGTH - 1% FIRST_WORD = LEFT(WORD_TO_BE_CHECKED, WORD_LENGTH) + "A" LAST_WORD = LEFT(WORD_TO_BE_CHECKED, WORD_LENGTH) + "Z" ! ----- ACCESS BOTH DICTIONARIES ----- FOR DICT_CHANNEL = 3% TO 4% ! ----- SET FLAG SO AS TO SEQUENTIALLY ----- ! ----- READ THE DICTIONARY ----- READ_NEXT_DICT_RECORD = TRUE ITERATE IF RECORD_COUNTER >= 10% ! ----- LOCATE FIRST WORD TO BE DISPLAYED ----- WHEN ERROR IN FIND #DICT_CHANNEL, KEY #0% GE & FIRST_WORD USE IF ERR = BUCKET_LOCKED THEN SLEEP 1% RETRY END IF EXIT HANDLER IF ERR <> & REC_NOT_FOUND AND ERR & <> END_OF_FILE ! ----- SET FLAG SO AS TO SKIP ----- ! ----- READING DICTIONARY ----- READ_NEXT_DICT_RECORD = FALSE CONTINUE END WHEN ! ----- READ NEXT DICTIONARY RECORD ----- WHILE READ_NEXT_DICT_RECORD AND & RECORD_COUNTER < 10% WHEN ERROR IN ! ----- GET NEXT ----- ! ----- DICTIONARY RECORD ----- GET #DICT_CHANNEL USE IF ERR = BUCKET_LOCKED THEN SLEEP 1% RETRY END IF EXIT HANDLER IF ERR <> & END_OF_FILE ! ----- SET FLAG SO AS TO ----- ! ----- EXIT LOOP ----- READ_NEXT_DICT_RECORD = FALSE CONTINUE END WHEN ITERATE IF NOT READ_NEXT_DICT_RECORD ! ----- SKIP IF BLANK RECORD ----- ITERATE IF DICTIONARY_RECORD = " " IF LAST_WORD <> " " AND & DICTIONARY_RECORD > LAST_WORD THEN ! ----- SET FLAG SO AS TO ----- ! ----- EXIT LOOP ----- READ_NEXT_DICT_RECORD = FALSE ITERATE END IF ! ----- LIMIT SEARCH TO ONE LETTER ----- ! ----- LONGER THAN BAD WORD ----- ITERATE IF LEN(TRM$( & DICTIONARY_RECORD)) > & LEN(WORD_TO_BE_CHECKED) + 1% RECORD_COUNTER = RECORD_COUNTER + 1% ! ----- SEE IF LOWERCASE ----- ! ----- CONVERSION REQD ----- IF ALL_UPPERCASE THEN TEMP = 99% ELSE TEMP = -1% END IF WHILE TEMP < & LEN(TRM$(DICTIONARY_RECORD)) & - 1% TEMP = TEMP + 1% ! ----- SEE IF FIRST ----- ! ----- LETTER SHOULD BE ----- ! ----- CAPITALIZED ----- ITERATE IF FIRST_CAPITAL& AND TEMP = 0% ! ----- LOWERCASE LETTER ----- SELECT DICTIONARY_BYTES(TEMP) CASE 65% TO 90% DICTIONARY_BYTES& (TEMP) =& DICTIONARY_BYTES& (TEMP) + 32% END SELECT NEXT ! ----- STORE WORD WITH CASE ----- ! ----- CHANGED (POSSIBLY) ----- ! ----- APPEND "'S" IF IT WAS IN ----- ! ----- THE ORIGINAL WORD ----- IF WORD_WITH_APOSTROPHE = & WORD_TO_BE_CHECKED THEN DICT_WORDS( & RECORD_COUNTER) & = TRM$( & DICTIONARY_RECORD) ELSE DICT_WORDS( & RECORD_COUNTER) & = TRM$( & DICTIONARY_RECORD) + & "'s" END IF ! ----- SKIP IF WE FOUND SAME WORD ----- ! ----- THAT WAS PREVIOUSLY FOUND ----- TEMP = 0% TEMP_LONG2 = 0% WHILE TEMP < RECORD_COUNTER - 1% TEMP = TEMP + 1% IF DICT_WORDS(TEMP) = & DICT_WORDS( & RECORD_COUNTER) THEN TEMP = RECORD_COUNTER TEMP_LONG2 = 1% END IF NEXT IF TEMP_LONG2 = 1% THEN RECORD_COUNTER = & RECORD_COUNTER - 1% END IF NEXT NEXT DICT_CHANNEL NEXT EXIT DEF IF RECORD_COUNTER = 0% ! DONE IF NO WORDS FOUND ! ----- RETURN THE NUMBER OF WORD CHOICES ----- DISPLAY_POSSIBLE_SPELLINGS = RECORD_COUNTER ! ----- DISPLAY ALL OF THE WORDS FOUND ----- PRINT TEMP = 0% TEMP_LONG = 0% WHILE TEMP < RECORD_COUNTER TEMP = TEMP + 1% TEMP_LONG = TEMP_LONG + 1% PRINT TAB(40%); IF TEMP_LONG = 2% IF TEMP < 10% THEN PRINT " " + NUM1$(TEMP) + ") " + & DICT_WORDS(TEMP); ELSE PRINT NUM1$(TEMP) + ") " + & DICT_WORDS(TEMP); END IF IF TEMP_LONG = 2% THEN PRINT TEMP_LONG = 0% END IF NEXT END DEF TEMP = CTRLC ! ENABLE CONTROL/C TRAP DVIITEM::BUFFER_LENGTH1 = 4% ! STORE DATA FOR $GETDVI DVIITEM::ITEM_CODE1 = DVI$_DEVTYPE DVIITEM::BUFFER_ADDRESS1 = LOC(DEVICE_TYPE) DVIITEM::RETURN_LENGTH_ADDRESS1 = LOC(DEVICE_TYPE_LENGTH) DVIITEM::LIST_TERMINATOR = 0% ! ----- SEE WHAT TYPE OF TERMINAL DEVICE WE'RE USING ----- LIB_STATUS = SYS$GETDVIW(, , "TT:", DVIITEM, , , , ) ! ----- SEE IF VT1xx/VT2xx/VT3xx/VT4xx TERMINAL TYPE ----- DEVICE_TYPE = 0% IF LIB_STATUS <> SS$_NORMAL IF DEVICE_TYPE < 96% OR DEVICE_TYPE > 113% THEN CLEAR_SCREEN = "" ! NO CLEAR SCREEN ESCAPE SEQ BOLD_VIDEO = "" ! NO BOLD VIDEO ESCAPE SEQ NORMAL_VIDEO = "" ! NO NORMAL VIDEO ESCAPE SEQ ELSE ! ----- TERMINAL IS CAPABLE OF HANDLING THE ----- ! ----- VT1XX/VT2XX/VT3XX/VT4XX ESCAPE SEQUENCES TO CLEAR ----- ! ----- THE SCREEN AND SPECIFY VIDEO ATTRIBUTES ----- CLEAR_SCREEN = ESC + "[2J" + ESC + "[H" ! CLEAR SCREEN / HOME BOLD_VIDEO = ESC + "[1m" ! STORE BOLD VIDEO ESCAPE SEQ NORMAL_VIDEO = ESC + "[m" ! STORE NORMAL VIDEO ESCAPE SEQ END IF DICTIONARY_CHANNEL = 4% ! DEFAULT OF PRIVATE DICTIONARY DICTIONARY_NAME(0%) = "general" ! DESC OF GENERAL DICTIONARY DICTIONARY_NAME(1%) = "private" ! DESC OF PRIVATE DICTIONARY ERROR_LINE = "START SPELL" ! INIT ERROR LINE DESCRIPTION EVE_SPELL = FALSE ! ASSUME NOT EVE SPELL-CHECKING ! ----- STORE THE MOST COMMON WORDS IN AN INCORE STRING ----- INCORE_WORDS = CR+LF+"THE"+CR+LF+"TO"+CR+LF+"IS"+CR+LF+ & "IN"+CR+LF+"OF"+CR+LF+"AND"+CR+LF+"AN"+CR+LF+ & "FOR"+CR+LF+"BE"+CR+LF+"BY"+CR+LF+"OR"+CR+LF+ & "ON"+CR+LF+"THIS"+CR+LF+"IT"+CR+LF+ & "WITH"+CR+LF+"LINE"+CR+LF+"NOW"+CR+LF+ & "NOT"+CR+LF+"YOURS"+CR+LF+"ARE"+CR+LF+ & "ABOUT"+CR+LF+"ACT"+CR+LF+"AFTER"+CR+LF+ & "ALL"+CR+LF+"AT"+CR+LF+"ADD"+CR+LF+ & "ANY"+CR+LF+"AS"+CR+LF+"BUT"+CR+LF+"BY"+CR+LF+ & "CAN"+CR+LF+"COME"+CR+LF+"DID"+CR+LF+ & "DO"+CR+LF+"DONE"+CR+LF+"EACH"+CR+LF+ & "FIRST"+CR+LF+"FROM"+CR+LF+"HAD"+CR+LF+ & "HAS"+CR+LF+"HAVE"+CR+LF+"HE"+CR+LF+ & "HER"+CR+LF+"IF"+CR+LF+"INTO"+CR+LF+ & "LIKE"+CR+LF+"MAN"+CR+LF+"MANY"+CR+LF+ & "MAY"+CR+LF+"MORE"+CR+LF+"ONE"+CR+LF+ & "OUR"+CR+LF+"PAGE"+CR+LF+"SAID"+CR+LF+ & "SET"+CR+LF+"SHE"+CR+LF+"SHOULD"+CR+LF+ & "SOME"+CR+LF+"THAT"+CR+LF+"THEM"+CR+LF+ & "THERE"+CR+LF+"THEY"+CR+LF+"TWO"+CR+LF+ & "US"+CR+LF+"VERY"+CR+LF+"WALK"+CR+LF+ & "WAS"+CR+LF+"WE"+CR+LF+"WERE"+CR+LF+ & "WHAT"+CR+LF+"WHEN"+CR+LF+"WHERE"+CR+LF+ & "WHICH"+CR+LF+"WHILE"+CR+LF+"WHO"+CR+LF+ & "WILL"+CR+LF+"WOULD"+CR+LF+"WITH"+CR+LF+ & "YES"+CR+LF+"YOU"+CR+LF+"YOUR"+CR+LF+ & "A"+CR+LF+"I"+CR+LF ! STORE COMMON WORDS LINE_COUNTER = 0% ! COUNT OF LINES READ FROM FILE TEN_COUNTER = 0% ! COUNT OF 10 LINES READ OUTPUT_FILE = "NL:" ! ASSUME NO OUTPUT FILE CREATED PRIV_FLAG = FALSE ! ASSUME NON-PRIVILEGED USER ! ----- GET ANY COMMAND LINE THAT THE USER MAY HAVE TYPED ----- LIB_STATUS = LIB$GET_FOREIGN(COMMAND_STRING,, COMMAND_STRING_LENGTH) IF LIB_STATUS <> SS$_NORMAL THEN PRINT PRINT "UNEXPECTED LIB$GET_FOREIGN ERROR IN SPELL: "; LIB_STATUS PRINT COMMAND_STRING_LENGTH = 0% ELSE IF COMMAND_STRING_LENGTH > 0% THEN ! ----- UPPERCASE COMMAND_STRING AND REMOVE ALL ----- ! ----- SPACES ----- COMMAND_STRING = EDIT$(LEFT(COMMAND_STRING, & COMMAND_STRING_LENGTH), 34%) ELSE PRINT CLEAR_SCREEN END IF END IF ! ----- SEE IF ANY PARAMETER IN DCL COMMAND LINE ----- WORD_TO_CHECK = "" IF COMMAND_STRING_LENGTH > 0% THEN ! ----- SEE IF "SPELL file.ext/EVE" COMMAND LINE ----- TEMP = POS(COMMAND_STRING, "/", 1%) IF TEMP > 1% AND RIGHT(COMMAND_STRING, TEMP) = "/EVE" THEN PRINT CLEAR_SCREEN EVE_SPELL = TRUE COMMAND_STRING = LEFT(COMMAND_STRING, TEMP - 1%) END IF IF LEFT(COMMAND_STRING, 1%) = "/" THEN ! ----- SEE IF "$SPELL /CHECK word" COMMAND LINE ----- IF LEFT(COMMAND_STRING, 6%) = "/CHECK" THEN IF COMMAND_STRING_LENGTH < 7% THEN PRINT "ERROR - no word to be"; & " checked" + BEL ! ----- EXIT WITH ERROR STATUS, ----- ! ----- BUT WITH NO VMS MESSAGE ----- ! ----- DISPLAYED ----- LIB_STATUS = SYS$EXIT( & ERROR_WITH_NO_MSG BY VALUE) END IF ! ----- CHECK TO SEE IF THIS WORD IS IN ----- ! ----- THE GENERAL DICTIONARY ----- WORD_TO_CHECK = RIGHT(COMMAND_STRING, 7%) IF LEN(WORD_TO_CHECK) > 32% THEN PRINT "ERROR - word too long"; & " to be checked" + BEL ! ----- EXIT WITH ERROR STATUS, ----- ! ----- BUT WITH NO VMS MESSAGE ----- ! ----- DISPLAYED ----- LIB_STATUS = SYS$EXIT( & ERROR_WITH_NO_MSG BY VALUE) END IF DICTIONARY_CHANNEL = 3% ELSE PRINT "ERROR - invalid DCL command line" + BEL ! ----- EXIT WITH ERROR STATUS, BUT WITH ----- ! ----- NO VMS MESSAGE DISPLAYED ----- LIB_STATUS = SYS$EXIT(ERROR_WITH_NO_MSG & BY VALUE) END IF END IF END IF FUNCTION_MENU: ! ----- GET MAIN MENU FUNCTION IF NOT CHECKING TO SEE IF ONE WORD ----- ! ----- IS IN THE GENERAL DICTIONARY ----- IF WORD_TO_CHECK = "" THEN FOUND_MATCH = TRUE ! SET FLAG TO GET MENU OPTION ELSE FOUND_MATCH = FALSE ! SET FLAG TO SKIP LOOP PROGRAM_FUNCTION = "*" ! USER-SELECTED PROGRAM FUNCTION END IF WHILE FOUND_MATCH PRINT PRINT "Spelling Error Correction Program V2.1" PRINT "by Brian Lomasky" PRINT IF COMMAND_STRING_LENGTH <> 0% THEN PRINT "" IF NOT EVE_SPELL PROGRAM_FUNCTION = "C" FOUND_MATCH = FALSE ELSE PRINT "Enter N for a list of NEW FEATURES" PRINT "Enter C to check a text file" PRINT "Enter A to assemble a list of misspelled words" PRINT "Enter P to print a dictionary" IF PRIV_FLAG THEN PRINT "Enter U to automatically" + & " store all new words in a dictionary" PRINT "Enter G to store the contents" + & " of your private" PRINT " dictionary in the" + & " general dictionary" END IF PRINT "Enter F for dictionary file maintenance" PRINT "Enter E to end this program" WHEN ERROR IN LINPUT " "; PROGRAM_FUNCTION USE CONTINUE END_PROGRAM END WHEN ! ----- UPPERCASE AND DISCARD GARBAGE ----- PROGRAM_FUNCTION = EDIT$(PROGRAM_FUNCTION, 38%) GOTO END_PROGRAM IF PROGRAM_FUNCTION = "E" ! ----- STORE DEFAULT RESPONSE, IF REQUIRED ----- PROGRAM_FUNCTION = "C" IF LEN(PROGRAM_FUNCTION) = 0% IF PROGRAM_FUNCTION = "LOMASKY" THEN PRIV_FLAG = TRUE PRINT CLEAR_SCREEN ITERATE END IF ! ----- BLANK RESPONSE IF INVALID ----- PROGRAM_FUNCTION = "" IF LEN(PROGRAM_FUNCTION) <> 1% IF PROGRAM_FUNCTION = "N" THEN PRINT CLEAR_SCREEN PRINT "SPELL has the following new features:" PRINT PRINT "1) One-letter words will be skipped" PRINT PRINT "2) You can check a text file" + & " for errors by typing the" + & " following command at the" PRINT " DCL $ prompt:" PRINT PRINT " SPELL filename" PRINT " (where filename is the" + & " name of the file to be checked)" PRINT PRINT "3) SPELL first looks in your" + & " current default directory" + & " for your private" PRINT " dictionary. If one is not" + & " found, SPELL will try to" + & " open an existing private" PRINT " dictionary in your" + & " SYS$LOGIN: directory. If" + & " one does not exist there, SPELL" PRINT " will create a new private" + & " dictionary in your current" + & " default directory." PRINT PRINT "4) Non-stream ASCII files can" + & " be spell-checked" PRINT PRINT "5) Pressing CONTROL/Z at any" + & " user prompt will abort the" + & " current operation." PRINT PRINT "6) Typing: SPELL /CHECK word" PRINT " will check to see if the" + & " word is in the general dictionary." PRINT PRINT " " + & "(Press to continue)"; WHEN ERROR IN LINPUT TEMP_STRING USE CONTINUE END_PROGRAM END WHEN PRINT CLEAR_SCREEN PRINT "7) When trying to correct a" + & " misspelled word, you can" + & " search the dictionary for" PRINT " a range of spellings to be" + & " displayed, and can correct" + & " the misspelled word" PRINT " with any of the words" + & " which are displayed." PRINT PRINT "8) When terminating this" + & " program in the middle of" + & " spell-checking a text file," PRINT " you can select whether you" + & " want to save or cancel all" + & " changes you've made." PRINT PRINT " " + & "(Press to continue)"; WHEN ERROR IN LINPUT TEMP_STRING USE CONTINUE END_PROGRAM END WHEN PRINT CLEAR_SCREEN ITERATE END IF ! ----- BLANK RESPONSE IF INVALID ----- IF NOT PRIV_FLAG THEN PROGRAM_FUNCTION = "" IF POS("CAPF", & PROGRAM_FUNCTION, 1%) = 0% ELSE PROGRAM_FUNCTION = "" IF POS("CAPUFG", & PROGRAM_FUNCTION, 1%) = 0% END IF ! ----- PROCESS INVALID RESPONSES ----- IF PROGRAM_FUNCTION = "" THEN PRINT PRINT "Invalid Entry - Please Try Again!" + BEL PRINT ELSE FOUND_MATCH = FALSE END IF END IF NEXT ! ----- GET DICTIONARY SELECTION IF PRINTING A DICTIONARY, ----- ! ----- AUTOMATICALLY STORING ALL NEW WORDS IN A DICTIONARY, OR ----- ! ----- IF PERFORMING DICTIONARY FILE MAINTENANCE ----- IF POS("PUF", PROGRAM_FUNCTION, 1%) <> 0% THEN ! ----- SELECT DICTIONARY ----- IF NOT PRIV_FLAG THEN ! SEE IF NON-PRIV ACCESS USER_ENTRY = "2" ELSE USER_ENTRY = "" END IF WHILE USER_ENTRY <> "1" AND USER_ENTRY <> "2" PRINT PRINT "Type in 1 to use the General Dictionary OR" PRINT "Type in 2 to use your Private Dictionary <2> "; WHEN ERROR IN LINPUT USER_ENTRY USE CONTINUE END_PROGRAM END WHEN ! ----- STORE DEFAULT RESPONSE ----- USER_ENTRY = "2" IF LEN(USER_ENTRY) = 0% NEXT DICTIONARY_CHANNEL = VAL(USER_ENTRY) + 2% END IF ! ----- SELECT INPUT FILE IF CHECKING A TEXT FILE, ASSEMBLING A ----- ! ----- LIST OF MISSPELLED WORDS, OR AUTOMATICALLY STORING ALL NEW ----- ! ----- WORDS IN A DICTIONARY ----- IF POS("CAU", PROGRAM_FUNCTION, 1%) = 0% THEN FOUND_MATCH = FALSE ELSE FOUND_MATCH = TRUE END IF WHILE FOUND_MATCH IF COMMAND_STRING_LENGTH = 0% THEN PRINT WHEN ERROR IN LINPUT & "Enter the input text file (name.ext) "; & INPUT_FILE USE CONTINUE END_PROGRAM END WHEN ! ----- UPPERCASE AND DISCARD GARBAGE ----- INPUT_FILE = EDIT$(INPUT_FILE, 38%) ELSE INPUT_FILE = COMMAND_STRING END IF IF INPUT_FILE = "" THEN PRINT PRINT "Illegal File Name. Try Again" + BEL COMMAND_STRING_LENGTH = 0% ITERATE END IF WHEN ERROR IN ! ----- TRY TO OPEN INPUT FILE ----- OPEN INPUT_FILE FOR INPUT AS FILE #1%, & SEQUENTIAL VARIABLE, RECORDTYPE ANY FOUND_MATCH = FALSE ! SET SO AS TO EXIT LOOP USE SELECT ERR CASE NO_SUCH_FILE PRINT PRINT "Can't find " + INPUT_FILE + & " Try Again" + BEL COMMAND_STRING_LENGTH = 0% CONTINUE CASE ILLEGAL_FILE_NAME PRINT PRINT "Illegal File Name. Try Again" + BEL COMMAND_STRING_LENGTH = 0% CONTINUE CASE FILE_ATTRS_NOT_MATCHED, RECORD_ATTRS_NOT_MATCHED PRINT PRINT "Can not spell check this file" + & " due to mismatched file/" + & "record attributes" + BEL PRINT CONTINUE END_PROGRAM CASE ELSE EXIT HANDLER END SELECT END WHEN NEXT SELECT PROGRAM_FUNCTION CASE "A" ! ----- GET MISSPELLED WORD OPTION IF ASSEMBLING A LIST OF ----- ! ----- MISSPELLED WORDS ----- TEMP_STRING = "" WHILE TEMP_STRING = "" PRINT PRINT "Enter 1 to print all misspelled words" + & " (including duplicates) OR" PRINT "Enter 2 to print only the first" + & " occurence of a misspelled word <1> "; WHEN ERROR IN LINPUT TEMP_STRING USE CONTINUE END_PROGRAM END WHEN TEMP_STRING = "1" IF LEN(TEMP_STRING) = 0% SELECT TEMP_STRING CASE "1" PRINT_ONLY_FIRST_BAD_WORD = FALSE CASE "2" PRINT_ONLY_FIRST_BAD_WORD = TRUE CASE ELSE TEMP_STRING = "" END SELECT NEXT ! ----- ASSEMBLE LIST OF MISSPELLED WORDS ----- OPEN "SPELL.LIS" FOR OUTPUT AS FILE #2%, SEQUENTIAL PRINT "Creating SPELL.LIS" PRINT #2%, "Spelling Check of " + INPUT_FILE + " on " + & DATE$(0%) PRINT #2% PRINT #2%, "Line # Word" CASE "C", "U" ! ----- GET OUTPUT FILESPEC ----- FOUND_MATCH = TRUE WHILE FOUND_MATCH IF COMMAND_STRING_LENGTH > 0% THEN IF EVE_SPELL THEN ! ----- LOCATE "." IN FILE TYPE ----- TEMP = POS(INPUT_FILE, "]", 1%) TEMP = POS(INPUT_FILE, ":", 1%) & IF TEMP = 0% IF TEMP = 0% THEN TEMP = POS(INPUT_FILE, ".", 1%) ELSE TEMP = POS(RIGHT( & INPUT_FILE, & TEMP), ".", 1%) & + TEMP - 1% END IF ! ----- CREATE .SPL FILE OUTPUT ----- IF TEMP = 0% THEN TEMP = POS(INPUT_FILE, ";", 1%) IF TEMP = 0% THEN OUTPUT_FILE = & INPUT_FILE & + ".SPL" ELSE OUTPUT_FILE = & LEFT( & INPUT_FILE, & TEMP - & 1%) + ".SPL" END IF ELSE OUTPUT_FILE = LEFT( & INPUT_FILE, & TEMP) + "SPL" END IF ELSE PRINT "" OUTPUT_FILE = INPUT_FILE ! ----- REMOVE ANY VERSION NUMBER ----- ! ----- FOR THE OUTPUT FILE ----- TEMP = POS(OUTPUT_FILE, ";", 1%) IF TEMP <> 0% THEN OUTPUT_FILE = LEFT( & OUTPUT_FILE, TEMP - 1%) END IF END IF ELSE PRINT PRINT "Enter the output text" + & " (filename.ext) (NL: if" + & " none) <" + INPUT_FILE + "> "; WHEN ERROR IN LINPUT OUTPUT_FILE USE CONTINUE END_PROGRAM END WHEN OUTPUT_FILE = INPUT_FILE & IF LEN(OUTPUT_FILE) = 0% ! ----- UPPERCASE AND DISCARD GARBAGE ----- OUTPUT_FILE = EDIT$(OUTPUT_FILE, 38%) END IF WHEN ERROR IN OPEN OUTPUT_FILE FOR OUTPUT AS FILE #2%,& SEQUENTIAL FOUND_MATCH = FALSE USE OUTPUT_FILE = "NL:" IF ERR = ILLEGAL_FILE_NAME THEN PRINT PRINT "Illegal File Name." + & " Try Again" + BEL COMMAND_STRING_LENGTH = 0% CONTINUE ELSE EXIT HANDLER END IF END WHEN NEXT END SELECT ! ----- OPEN DICTIONARIES ----- ERROR_LINE = "OPEN_DICTIONARIES" ! ----- OPEN GENERAL DICTIONARY ----- IF NOT PRIV_FLAG THEN OPEN "SPELL_DIR:SPELL.DAT" AS FILE #3%, & INDEXED FIXED, ACCESS READ, & ALLOW READ, & PRIMARY DICTIONARY_RECORD, & MAP SPL ELSE OPEN "SPELL_DIR:SPELL.DAT" AS FILE #3%, & INDEXED FIXED, ACCESS MODIFY, & ALLOW MODIFY, & PRIMARY DICTIONARY_RECORD, & MAP SPL END IF ! ----- OPEN PRIVATE DICTIONARY (UNLESS "/CHECK word" SPECIFIED) ----- IF WORD_TO_CHECK = "" THEN ! IF NOT "/CHECK word" OPTION: FOUND_MATCH = TRUE ELSE FOUND_MATCH = FALSE ! SKIP PRIVATE DICTIONARY OPEN USER_ENTRY = WORD_TO_CHECK ! STORE WORD TO BE CHECKED END IF PRIVATE_DICTIONARY = "SPELL.DIC" ! ASSUME DEFAULT PRIVATE DICT WHILE FOUND_MATCH ERROR_LINE = "OPEN " + PRIVATE_DICTIONARY WHEN ERROR IN OPEN PRIVATE_DICTIONARY FOR INPUT AS FILE #4%, & INDEXED FIXED, & ACCESS READ, ALLOW MODIFY, & PRIMARY DICTIONARY_RECORD, & MAP SPL ! OPEN PRIVATE DICTIONARY CLOSE #4% ! CLOSE PRIVATE DICTIONARY FOUND_MATCH = FALSE USE SELECT ERR CASE NO_SUCH_FILE SELECT PRIVATE_DICTIONARY CASE "SPELL.DIC" ! ----- TRY SYS$LOGIN PRIVATE DICT ----- ! ----- IF NO DEFAULT PRIVATE DICT ----- PRIVATE_DICTIONARY = & "SYS$LOGIN:SPELL.DIC" CASE "SYS$LOGIN:SPELL.DIC" ! ----- CREATE NEW PRIVATE DICT IF ----- ! ----- IF NO PRIVATE DICT FOUND ----- PRINT PRINT "Creating SPELL.DIC as" + & " your private dictionary" FOUND_MATCH = FALSE PRIVATE_DICTIONARY = "" END SELECT CONTINUE CASE FILE_ATTRS_NOT_MATCHED, RECORD_ATTRS_NOT_MATCHED ! ----- INVALID [default]SPELL.DIC ----- PRINT PRINT "ERROR - Invalid " + & PRIVATE_DICTIONARY + " data file" + BEL PRINT CONTINUE END_PROGRAM CASE ELSE EXIT HANDLER END SELECT END WHEN NEXT IF WORD_TO_CHECK = "" THEN PRIVATE_DICTIONARY = "SPELL.DIC" IF PRIVATE_DICTIONARY = "" ERROR_LINE = "RE-OPEN " + PRIVATE_DICTIONARY OPEN PRIVATE_DICTIONARY AS FILE #4%, & INDEXED FIXED, & ACCESS MODIFY, ALLOW MODIFY, & PRIMARY DICTIONARY_RECORD, & MAP SPL ! OPEN PRIVATE DICTIONARY END IF ! ----- ASSUME DICTIONARY FILE WILL NOT BE SEQUENTIALLY READ ----- READ_NEXT_DICT_RECORD = FALSE ERROR_LINE = "MAIN PROCESSING" SELECT PROGRAM_FUNCTION CASE "P" ! PRINT A DICTIONARY ! ----- OPEN REPORT OUTPUT ----- OPEN "DICT.LIS" FOR OUTPUT AS FILE #2%, SEQUENTIAL PRINT "Creating DICT.LIS" ! ----- SET FLAG SO AS TO SEQUENTIALLY READ THE DICTIONARY ----- READ_NEXT_DICT_RECORD = TRUE TOTALS_ONLY_FLAG = " " PRINT "Starting Word Key to Print ( for first one) "; WHEN ERROR IN LINPUT FIRST_WORD USE CONTINUE END_PROGRAM END WHEN ! ----- UPPERCASE AND DISCARD GARBAGE ----- FIRST_WORD = EDIT$(FIRST_WORD, 38%) FIRST_WORD = " " IF LEN(FIRST_WORD) = 0% FIRST_WORD = LEFT(FIRST_WORD, 32%) PRINT "Ending Word Key to Print ( for last one) "; WHEN ERROR IN LINPUT LAST_WORD USE CONTINUE END_PROGRAM END WHEN ! ----- UPPERCASE AND DISCARD GARBAGE ----- LAST_WORD = EDIT$(LAST_WORD, 38%) LAST_WORD = " " IF LEN(LAST_WORD) = 0% PRINT "(Press for normal list OR type T" + & " for totals only) "; WHEN ERROR IN LINPUT TOTALS_ONLY_FLAG USE CONTINUE END_PROGRAM END WHEN ! ----- UPPERCASE AND DISCARD GARBAGE ----- TOTALS_ONLY_FLAG = EDIT$(TOTALS_ONLY_FLAG, 38%) TOTALS_ONLY_FLAG = " " IF LEN(TOTALS_ONLY_FLAG) = 0% ! ----- PRINT DICTIONARY REPORT HEADINGS ----- IF TOTALS_ONLY_FLAG <> "T" THEN PRINT #2%, "List"; ELSE PRINT #2%, "Count"; END IF PRINT #2%, " of Words in the " + DICTIONARY_NAME( & DICTIONARY_CHANNEL - 3%) + " dictionary from "; IF FIRST_WORD <> " " THEN PRINT #2%, FIRST_WORD; ELSE PRINT #2%, "first"; END IF PRINT #2%, " to "; IF LAST_WORD <> " " THEN PRINT #2%, LAST_WORD; ELSE PRINT #2%, "last"; END IF PRINT #2%, " " + DATE$(0%) PRINT #2%, STRING$(80%, 61%) ! UNDERLINE PRINT #2% ! ----- LOCATE FIRST WORD TO PRINT ----- ERROR_LINE = "LOCATE FIRST WORD" WHEN ERROR IN FIND #DICTIONARY_CHANNEL, KEY #0% GE FIRST_WORD USE IF ERR = BUCKET_LOCKED THEN SLEEP 1% RETRY END IF EXIT HANDLER IF ERR <> REC_NOT_FOUND AND & ERR <> END_OF_FILE ! ----- SET FLAG SO AS TO SKIP READING ----- ! ----- DICTIONARY ----- READ_NEXT_DICT_RECORD = FALSE CONTINUE END WHEN CASE "F", "*" ! DICTIONARY FILE MAINTENANCE ! SPELL /CHECK word ! ----- CLEAR ENTRY IF WORD PROMPT SHOULD OCCUR ----- USER_ENTRY = "" IF PROGRAM_FUNCTION = "F" WHILE TRUE WHILE USER_ENTRY = "" PRINT PRINT "Enter a Word to check (OR" + & " just press to end) "; WHEN ERROR IN ! ----- GET A WORD TO BE CHECKED ----- LINPUT USER_ENTRY USE PRINT CLEAR_SCREEN CONTINUE FUNCTION_MENU END WHEN ! ----- UPPERCASE AND DISCARD GARBAGE ----- USER_ENTRY = EDIT$(USER_ENTRY, 38%) IF USER_ENTRY = "" THEN PRINT CLEAR_SCREEN GOTO FUNCTION_MENU END IF IF LEN(USER_ENTRY) > 32% THEN USER_ENTRY = "" PRINT PRINT "Error - Too many" + & " characters - Try Again" + BEL PRINT ITERATE END IF NEXT ! ----- SEARCH FOR THIS WORD IN THE DICTIONARY ----- ERROR_LINE = "SEARCH FOR THIS WORD" WHEN ERROR IN GET #DICTIONARY_CHANNEL, KEY #0% GE USER_ENTRY USE IF ERR = BUCKET_LOCKED THEN SLEEP 1% RETRY END IF EXIT HANDLER IF ERR <> REC_NOT_FOUND & AND ERR <> END_OF_FILE ! ----- WORD NOT IN DICTIONARY ----- DICTIONARY_RECORD = "" CONTINUE END WHEN IF USER_ENTRY = DICTIONARY_RECORD THEN PRINT IF WORD_TO_CHECK = "" PRINT USER_ENTRY + " is in the " + & DICTIONARY_NAME( & DICTIONARY_CHANNEL - 3%) + & " dictionary." ! ----- EXIT IF /CHECK word OPTION ----- IF WORD_TO_CHECK <> "" THEN ! ----- CLOSE ALL OPEN FILES ----- CLOSE #TEMP FOR TEMP = 1% TO 12% ! ----- EXIT WITH SUCCESS STATUS, ----- ! ----- BUT WITH NO VMS MESSAGE ----- ! ----- DISPLAYED ----- LIB_STATUS = SYS$EXIT( & SUCCESS_WITH_NO_MSG BY VALUE) END IF PRINT "(Enter D to delete this word" + & " OR press to enter" + & " another word) "; WHEN ERROR IN LINPUT USER_OPTION ! ----- UPPERCASE AND DISCARD ----- ! ----- GARBAGE ----- USER_OPTION = EDIT$(USER_OPTION, 38%) USE USER_OPTION = "" CONTINUE END WHEN IF USER_OPTION = "D" THEN DELETE #DICTIONARY_CHANNEL PRINT PRINT "Deleted " + USER_ENTRY END IF ELSE ! ----- CAN NOT FIND THE WORD IN THE ----- ! ----- DICTIONARY ----- PRINT IF WORD_TO_CHECK = "" PRINT USER_ENTRY + " is NOT in the " + & DICTIONARY_NAME( & DICTIONARY_CHANNEL - 3%) + & " dictionary." PRINT "(" + TRM$(DICTIONARY_RECORD) + & " is the next word)" ! ----- EXIT IF /CHECK word OPTION ----- IF WORD_TO_CHECK <> "" THEN ! ----- CLOSE ALL OPEN FILES ----- CLOSE #TEMP FOR TEMP = 1% TO 12% ! ----- EXIT WITH ERROR STATUS, ----- ! ----- BUT WITH NO VMS MESSAGE ----- ! ----- DISPLAYED ----- LIB_STATUS = SYS$EXIT( & ERROR_WITH_NO_MSG BY VALUE) END IF PRINT PRINT "(Enter A to add this word OR" + & " press to enter" + & " another word) "; WHEN ERROR IN LINPUT USER_OPTION ! ----- UPPERCASE AND DISCARD ----- ! ----- GARBAGE ----- USER_OPTION = EDIT$(USER_OPTION, 38%) USE USER_OPTION = "" CONTINUE END WHEN IF USER_OPTION = "A" THEN ! ----- MOVE THE KEY FIELD TO MAP ----- DICTIONARY_RECORD = USER_ENTRY ! ----- STORE THIS WORD ----- PUT #DICTIONARY_CHANNEL PRINT PRINT "Added " + USER_ENTRY END IF END IF USER_ENTRY = "" ! CLEAR ENTRY TO PROMPT FOR NEXT NEXT END SELECT ! ----- READ NEXT DICTIONARY RECORD (WHILE PRINTING A DICTIONARY ----- ! ----- OR STORING THE CONTENTS OF A PRIVATE DICTIONARY IN THE ----- ! ----- GENERAL DICTIONARY) ----- RECORD_COUNTER = 0% ! INIT COUNT OF WORDS ERROR_LINE = "READ NEXT DICT REC" WHILE READ_NEXT_DICT_RECORD ! ----- READ AND THEN PROCESS A DICTIONARY RECORD ----- WHEN ERROR IN GET #DICTIONARY_CHANNEL ! GET A DICTIONARY REC USE IF ERR = BUCKET_LOCKED THEN SLEEP 1% RETRY END IF EXIT HANDLER IF ERR <> END_OF_FILE ! ----- SET FLAG SO AS TO EXIT LOOP ----- READ_NEXT_DICT_RECORD = FALSE CONTINUE END WHEN ITERATE IF NOT READ_NEXT_DICT_RECORD ! ----- SKIP IF BLANK RECORD ----- ITERATE IF DICTIONARY_RECORD = " " IF LAST_WORD <> " " AND DICTIONARY_RECORD > LAST_WORD THEN ! ----- SET FLAG SO AS TO EXIT LOOP ----- READ_NEXT_DICT_RECORD = FALSE ITERATE END IF RECORD_COUNTER = RECORD_COUNTER + 1% ! ----- READ NEXT RECORD IF ONLY TOTALS WANTED ----- ITERATE IF TOTALS_ONLY_FLAG = "T" SELECT PROGRAM_FUNCTION CASE "P" ! PRINT CONTENTS OF DICTIONARY PRINT #2%, DICTIONARY_RECORD CASE "G" PUT #3% ! STORE IN GENERAL DICTIONARY DELETE #4% ! DELETE FROM PRIV DICTIONARY END SELECT NEXT ! ----- EOF ON DICTIONARY INPUT FILE ----- SELECT PROGRAM_FUNCTION CASE "P" ! PRINT A DICTIONARY PRINT #2% PRINT #2%, "There are " + NUM1$(RECORD_COUNTER) + " words"; IF TOTALS_ONLY_FLAG <> "T" THEN PRINT #2%, " printed" ELSE PRINT #2%, " on file" END IF END SELECT ! ----- ALL DONE IF MENU OPTION "P" OR "G" ----- SELECT PROGRAM_FUNCTION CASE "P", "G" ! PRINT DICTIONARY - STORE PRIV CLOSE #2%, 3%, 4% ! CLOSE OUTPUT FILES PRINT CLEAR_SCREEN GOTO FUNCTION_MENU END SELECT ! ----- CONTINUE ON WITH MENU OPTIONS "C", "A", AND "U" ----- ! ----- (CHECK A TEXT FILE, ASSEMBLE A LIST OF MISSPELLED WORDS, ----- ! ----- AND AUTO-STORE ALL NEW WORDS IN A DICTIONARY) ----- ERROR_LINE = "CHECK LINE" PRINT "Checking Line "; CURSOR_POSITION = 14% ! INIT CURRENT CURSOR POSITION CORRECTED_WORD_TOT = 0% ! INIT COUNT OF CORRECTED WORDS CORRECTIONS_MADE = FALSE ! ASSUME NO CORRECTIONS MADE DISPLAY_MENU_OPTIONS = TRUE ! SET FLAG TO DISPLAY MENU OPTS EOF_FLAG = FALSE ! ASSUME FILE NOT AT EOF HYPHENATED_CHARACTERS = "" ! ASSUME NO HYPHENATED CHARS HYPHEN_FLAG = FALSE ! ASSUME NO HYPHENATED WORD INCORRECT_WORDS = CR+LF ! INIT PREV-WRONG WORD LIST INPUT_LINE = "~%(" ! CLEAR CURRENT INPUT LINE INPUT_LINE_PREV1 = "~%(" ! CLEAR PREVIOUS INPUT LINE INPUT_LINE_PREV2 = "~%(" ! CLEAR PREVIOUS INPUT LINE OKAY_WORDS = CR+LF ! INIT LIST OF OKAY WORDS PREVIOUS_LINE_FLAG = FALSE ! NO PREVIOUS LINE TO PRINT POSITION_INDEX = 0% ! INIT POSITION WITHIN LINE QUICK_WORD_COUNTER = 0% ! INIT NUMBER OF QUICK WORDS MAT QUICK_WORD_STATUS = ZER ! INIT ARRAY MAT QUICK_WORDS = NUL$ ! INIT ARRAY RECENT_WORD_COUNTER = 0% ! INIT NUMBER OF RECENT WORDS MAT RECENT_WORD_STATUS = ZER ! INIT ARRAY MAT RECENT_WORDS = NUL$ ! INIT ARRAY GOSUB READ_NEXT_INPUT_LINE ! READ FIRST LINE FROM FILE IF EOF_FLAG THEN PRINT PRINT "Finished Checking Spelling - (No data found to check)" PRINT GOTO END_PROGRAM END IF ! ----- PROCESS EACH WORD WHICH IS FOUND IN INPUT_LINE ----- WHILE TRUE ! ----- FIND THE NEXT WORD ----- WORD_FOUND_FLAG = FALSE WHILE NOT WORD_FOUND_FLAG ! EXECUTE UNTIL WORD IS FOUND ! ----- FIND THE FIRST LETTER ----- LETTER_FOUND = FALSE WHILE NOT LETTER_FOUND ! EXECUTE UNTIL LETTER IS FOUND ! ----- READ NEXT LINE IF NO MORE ----- ! ----- CHARACTERS IN THIS LINE ----- IF POSITION_INDEX > LEN(INPUT_LINE) THEN ! ----- READ THE NEXT LINE ----- GOSUB READ_NEXT_INPUT_LINE ITERATE END IF CHARACTER = MID(INPUT_LINE, POSITION_INDEX, 1%) ! ----- SET POSITION POINTER TO SCAN NEXT ----- ! ----- CHARACTER POSITION ----- POSITION_INDEX = POSITION_INDEX + 1% ! ----- SEE IF A VALID LETTER WAS FOUND ----- IF POS(VALID_LETTERS, CHARACTER, 1%) > 0% THEN LETTER_FOUND = TRUE LAST_NON_BLANK_CHARACTER = CHARACTER ITERATE END IF NEXT ! ----- A VALID LETTER HAS BEEN FOUND ----- WORD_FOUND = CHARACTER FIRST_LETTER_LOCATION = POSITION_INDEX - 1% ! ----- ASSEMBLE A WORD OF CONSECUTIVE LETTERS ----- WHILE NOT WORD_FOUND_FLAG IF POSITION_INDEX <= LEN(INPUT_LINE) THEN CHARACTER = MID(INPUT_LINE, & POSITION_INDEX, 1%) ! ----- SET POSITION POINTER TO ----- ! ----- SCAN NEXT CHARACTER ----- ! ----- POSITION ----- POSITION_INDEX = POSITION_INDEX + 1% IF POS(VALID_LETTERS, CHARACTER,& 1%) = 0% THEN ! ----- SET FLAG TO EXIT ----- ! ----- LOOP ----- WORD_FOUND_FLAG = TRUE ELSE WORD_FOUND = WORD_FOUND & + CHARACTER END IF IF CHARACTER <> " " AND ASCII( & CHARACTER) <> 9% THEN LAST_NON_BLANK_CHARACTER& = CHARACTER END IF ELSE ! ----- SET POSITION POINTER TO ----- ! ----- SCAN TWO CHARACTERS AFTER ----- ! ----- THE END OF THE LINE ----- POSITION_INDEX = POSITION_INDEX + 1% ! ----- SET FLAG TO EXIT LOOP ----- WORD_FOUND_FLAG = TRUE END IF NEXT ! ----- SKIP ONE-LETTER WORDS ----- IF LEN(WORD_FOUND) = 1% THEN WORD_FOUND_FLAG = FALSE END IF NEXT ! ----- A WORD HAS BEEN FOUND ----- ERROR_LINE = "FOUND WORD: " + WORD_FOUND LAST_LETTER_LOCATION = POSITION_INDEX - 2% WORD_STATUS = 1% ! ASSUME UNKNOWN WORD STATUS QUICK_WORD_INDEX = 0% ! SET QUICK WORD ARRAY INDEX ! ----- PROCESS PREVIOUSLY HYPHENATED WORD ----- IF LEN(HYPHENATED_CHARACTERS) > 0% THEN WORD_FOUND = HYPHENATED_CHARACTERS + WORD_FOUND HYPHENATED_CHARACTERS = "" HYPHEN_FLAG = TRUE ELSE HYPHEN_FLAG = FALSE END IF ! ----- STORE THIS WORD IF THIS WORD IS HYPHENATED AT ----- ! ----- END OF LINE ----- IF LAST_NON_BLANK_CHARACTER = "-" AND POSITION_INDEX > & LEN(INPUT_LINE) THEN HYPHENATED_CHARACTERS = WORD_FOUND ITERATE ! CONTINUE WITH NEXT LINE END IF ! ----- SEE IF WORD TOO LONG FOR KEY ----- ! IF LEN(WORD_FOUND) > 32% THEN ! PRINT IF CURSOR_POSITION > 0% ! PRINT "Skipping word which is too long: " + WORD_FOUND ! CURSOR_POSITION = 33% + LEN(WORD_FOUND) ! END IF ! ----- STORE UPPERCASED WORD TO BE CHECKED ----- WORD_TO_BE_CHECKED = EDIT$(WORD_FOUND, 32%) ! ----- REMOVE ANY LEADING SINGLE APOSTROPHE ----- IF LEFT(WORD_TO_BE_CHECKED, 1%) = "'" THEN WORD_TO_BE_CHECKED = RIGHT(WORD_TO_BE_CHECKED, 2%) FIRST_LETTER_LOCATION = FIRST_LETTER_LOCATION + 1% END IF ! ----- REMOVE ANY TRAILING SINGLE APOSTROPHE ----- IF RIGHT(WORD_TO_BE_CHECKED, LEN(WORD_TO_BE_CHECKED)) = "'" THEN WORD_TO_BE_CHECKED = LEFT(WORD_TO_BE_CHECKED, & LEN(WORD_TO_BE_CHECKED) - 1%) LAST_LETTER_LOCATION = LAST_LETTER_LOCATION - 1% END IF ! ----- REMOVE ANY TRAILING "'S" ----- WORD_WITH_APOSTROPHE = WORD_TO_BE_CHECKED IF RIGHT(WORD_TO_BE_CHECKED, LEN(WORD_TO_BE_CHECKED) - & 1%) = "'S" THEN WORD_TO_BE_CHECKED = LEFT(WORD_TO_BE_CHECKED, & LEN(WORD_TO_BE_CHECKED) - 2%) END IF DONE_CHECKING_WORD = FALSE ! SO LOOP WILL EXECUTE WHILE NOT DONE_CHECKING_WORD ! ----- CHECK THE INCORE LIST OF WORDS (THE INCORE ----- ! ----- ARRAY CONTAINS THE MOST COMMON WORDS) ----- ERROR_LINE = "INCORE" IF POS(INCORE_WORDS, CR+LF + WORD_TO_BE_CHECKED & + CR+LF, 1%) > 0% THEN WORD_STATUS = -1% DONE_CHECKING_WORD = TRUE ITERATE END IF ! ----- CHECK FOR MATCHING WORD IN QUICK WORD ----- ! ----- ARRAY (CONTAINS THE LAST TWENTY WORDS THAT ----- ! ----- HAVE BEEN READ IN AND WHICH ARE NOT STORED ----- ! ----- IN THE INCORE ARRAY) ----- ! ----- INIT LOWEST COUNT ----- LOWEST_QUICK_WORD_MATCH = 32767% LOWEST_QUICK_WORD_INDEX = 1% QUICK_WORD_INDEX = 0% WHILE QUICK_WORD_INDEX < QUICK_WORD_COUNTER AND & NOT DONE_CHECKING_WORD QUICK_WORD_INDEX = QUICK_WORD_INDEX + 1% ! ----- SEE IF THIS IS A PREVIOUSLY-KNOWN ----- ! ----- QUICK WORD ----- IF WORD_TO_BE_CHECKED = & QUICK_WORDS(QUICK_WORD_INDEX) THEN ! ----- RECALL PREVIOUS WORD ----- ! ----- STATUS ----- WORD_STATUS = & QUICK_WORD_STATUS( & QUICK_WORD_INDEX, 1%) ! ----- INCREMENT NUMBER OF WORD ----- ! ----- MATCHES ----- QUICK_WORD_STATUS( & QUICK_WORD_INDEX, 0%) = & QUICK_WORD_STATUS( & QUICK_WORD_INDEX, 0%) + 10% DONE_CHECKING_WORD = TRUE ELSE ! ----- THIS IS NOT A MATCHING ----- ! ----- QUICK WORD ----- ! ----- DECREMENT COUNTER IF NO ----- ! ----- MATCH ----- QUICK_WORD_STATUS( & QUICK_WORD_INDEX, 0%) = & QUICK_WORD_STATUS( & QUICK_WORD_INDEX, 0%) - 1% ! ----- SKIP IF WE DID NOT FOUND A ----- ! ----- LOWER COUNT RATE ----- ITERATE IF QUICK_WORD_STATUS( & QUICK_WORD_INDEX, 0%) & >= LOWEST_QUICK_WORD_MATCH ! ----- STORE NUMBER OF LOWEST ----- ! ----- MATCHES ----- LOWEST_QUICK_WORD_MATCH = & QUICK_WORD_STATUS( & QUICK_WORD_INDEX, 0%) ! ----- STORE INDEX OF ELEMENT ----- ! ----- WITH LOWEST MATCHES ----- LOWEST_QUICK_WORD_INDEX = & QUICK_WORD_INDEX END IF NEXT ! ----- DONE IF WORD WAS FOUND IN QUICK_WORD ARRAY ----- ITERATE IF DONE_CHECKING_WORD IF QUICK_WORD_COUNTER < 20% THEN ! ----- INCR SIZE OF LIST ----- QUICK_WORD_COUNTER = QUICK_WORD_COUNTER + 1% ! ----- STORE ARRAY INDEX TO STORE THIS ----- ! ----- WORD ----- QUICK_WORD_INDEX = QUICK_WORD_COUNTER ELSE ! ----- STORE ARRAY INDEX TO BE REUSED ----- QUICK_WORD_INDEX = LOWEST_QUICK_WORD_INDEX END IF ! ----- STORE THIS WORD IN THE QUICK WORD ARRAY ----- QUICK_WORDS(QUICK_WORD_INDEX) = WORD_TO_BE_CHECKED ! ----- STORE INITIAL COUNT FOR THIS WORD ----- QUICK_WORD_STATUS(QUICK_WORD_INDEX, 0%) = 10% ! ----- STORE INITIAL SPELLING STATUS FOR THIS ----- ! ----- WORD AS BEING INCORRECTLY SPELLED ----- QUICK_WORD_STATUS(QUICK_WORD_INDEX, 1%) = 0% ! ----- SEARCH THE LIST OF OKAY WORDS (WHICH ARE ----- ! ----- THE WORDS THAT ARE NEW WORDS THAT HAVE ----- ! ----- BEEN SELECTED BY THE USER AS BEING ----- ! ----- CORRECT) ----- IF POS(OKAY_WORDS, CR+LF + WORD_TO_BE_CHECKED + & CR+LF, 1%) > 0% THEN WORD_STATUS = -1% DONE_CHECKING_WORD = TRUE ITERATE END IF ! ----- CHECK THE LAST THIRTY MOST FREQUENT ----- ! ----- WORDS FOR A MATCH ----- ERROR_LINE = "CHECK 30" FOUND_MATCH = FALSE RECENT_WORD_INDEX = 0% WHILE RECENT_WORD_INDEX < RECENT_WORD_COUNTER & AND NOT FOUND_MATCH RECENT_WORD_INDEX = RECENT_WORD_INDEX + 1% IF WORD_TO_BE_CHECKED = & RECENT_WORDS(RECENT_WORD_INDEX) THEN ! ----- A RECENT WORD MATCH HAS ----- ! ----- BEEN FOUND ----- FOUND_MATCH = TRUE ! ----- INCREMENT NUMBER OF ----- ! ----- MATCHES ----- RECENT_WORD_STATUS( & RECENT_WORD_INDEX, 0%) & = RECENT_WORD_STATUS( & RECENT_WORD_INDEX, 0%) + 1% ! ----- CHECK STATUS OF THIS WORD ----- SELECT RECENT_WORD_STATUS( & RECENT_WORD_INDEX, 1%) CASE -1% WORD_STATUS = -1% DONE_CHECKING_WORD = TRUE CASE 0% WORD_STATUS = 0% DONE_CHECKING_WORD = TRUE END SELECT END IF NEXT ! ----- DONE IF WORD WAS FOUND IN RECENT_WORDS ----- ! ----- ARRAY ----- ITERATE IF DONE_CHECKING_WORD IF NOT FOUND_MATCH THEN ! ----- NO MATCHING RECENT WORD HAS BEEN ----- ! ----- FOUND ----- IF RECENT_WORD_COUNTER < 30% THEN ! ----- ADD THIS WORD TO THE END ----- ! ----- OF THE ARRAY ----- RECENT_WORD_COUNTER = & RECENT_WORD_COUNTER + 1% ! ----- STORE ARRAY INDEX TO STORE ----- ! ----- THIS RECENT WORD ----- RECENT_WORD_INDEX = RECENT_WORD_COUNTER ELSE ! ----- FIND LOCATION OF LEAST ----- ! ----- MATCHED WORD IN ARRAY ----- LOWEST_RECENT_WORD_MATCH = 32767% FOR RECENT_WORD_INDEX = 1% TO & RECENT_WORD_COUNTER ITERATE IF & RECENT_WORD_STATUS( & RECENT_WORD_INDEX, & 0%) >= & LOWEST_RECENT_WORD_MATCH LOWEST_RECENT_WORD_MATCH& = RECENT_WORD_STATUS & (RECENT_WORD_INDEX, 0%) LOWEST_RECENT_WORD_INDEX& = RECENT_WORD_INDEX NEXT RECENT_WORD_INDEX END IF RECENT_WORD_INDEX = LOWEST_RECENT_WORD_INDEX ! ----- STORE THIS WORD IN THE LOCATION ----- ! ----- OF THE LEAST MATCHED WORD ----- RECENT_WORDS(RECENT_WORD_INDEX) = & WORD_TO_BE_CHECKED RECENT_WORD_STATUS(RECENT_WORD_INDEX, & 0%) = 1%! INIT MATCH COUNTER ! ----- STORE 1 IN THE STATUS FIELD TO ----- ! ----- INDICATE THAT THIS WORD HAS NOT ----- ! ----- YET BEEN CHECKED IN THE DICTIONARY ----- RECENT_WORD_STATUS(RECENT_WORD_INDEX, 1%) = 1% END IF ! ----- CHECK GENERAL DICTIONARY FOR THIS WORD ----- ! ----- (UNLESS WORD IS TOO LONG) ----- ERROR_LINE = "CHECK GENERAL" IF LEN(WORD_TO_BE_CHECKED) <= 32% THEN ERROR_LINE = "CHECK GENERAL DICT" WHEN ERROR IN GET #3%, KEY #0% GE WORD_TO_BE_CHECKED IF WORD_TO_BE_CHECKED = & DICTIONARY_RECORD THEN WORD_STATUS = -1% END IF USE IF ERR = BUCKET_LOCKED THEN SLEEP 1% RETRY END IF EXIT HANDLER IF ERR <> & END_OF_FILE AND ERR <> & REC_NOT_FOUND CONTINUE END WHEN IF WORD_STATUS <> -1% THEN ! ----- CHECK PRIVATE DICTIONARY ----- ! ----- IF NOT IN GENERAL ----- ! ----- DICTIONARY ----- ERROR_LINE = "CHECK PRIVATE" WHEN ERROR IN GET #4%, KEY #0% GE & WORD_TO_BE_CHECKED IF WORD_TO_BE_CHECKED = & DICTIONARY_RECORD THEN WORD_STATUS = -1% END IF USE IF ERR = BUCKET_LOCKED THEN SLEEP 1% RETRY END IF EXIT HANDLER IF ERR <> & END_OF_FILE AND & ERR <> REC_NOT_FOUND CONTINUE END WHEN END IF END IF ! ----- IF THIS RECENT WORD HAS AN UNKNOWN ----- ! ----- SPELLING STATUS, STORE THE STATUS OF THIS ----- ! ----- RECENT WORD AFTER CHECKING THE DICTIONARY ----- ! ----- FILES ----- IF RECENT_WORD_STATUS(RECENT_WORD_INDEX, 1%) = 1% THEN RECENT_WORD_STATUS(RECENT_WORD_INDEX, 1%) = -1% END IF ! ----- SET FLAG SO AS TO EXIT LOOP ----- ERROR_LINE = "EXIT CHECK LOOP" DONE_CHECKING_WORD = TRUE NEXT ! ----- DONE WITH ALL SEARCHING FOR THIS WORD ----- ! ----- SEE IF WORD IS CORRECTLY SPELLED ----- ERROR_LINE = "SEE IF CORRECT" IF WORD_STATUS = -1% THEN ! ----- STORE THE CORRECT SPELLING STATUS OF ----- ! ----- THIS QUICK WORD ----- QUICK_WORD_STATUS(QUICK_WORD_INDEX, 1%) = -1% ITERATE END IF ! ----- CHECK TO SEE IF THIS MISPELLED WORD HAS BEEN ----- ! ----- PREVIOUSLY CORRECTED BY THE USER ----- IF OUTPUT_FILE <> "NL:" AND NOT HYPHEN_FLAG THEN FOUND_MATCH = FALSE CORRECTED_WORD_INDEX = 0% WHILE CORRECTED_WORD_INDEX < CORRECTED_WORD_TOT & AND NOT FOUND_MATCH CORRECTED_WORD_INDEX = CORRECTED_WORD_INDEX + 1% ! ----- IF WORD WAS PREVIOUSLY CORRECTED: ----- IF CORRECTED_WORDS(CORRECTED_WORD_INDEX,& 0%) = WORD_WITH_APOSTROPHE THEN FOUND_MATCH = TRUE END IF NEXT IF FOUND_MATCH THEN ! ----- AUTOMATICALLY CORRECT IT ----- INPUT_LINE = LEFT(INPUT_LINE, & FIRST_LETTER_LOCATION - 1%) + & CORRECTED_WORDS( & CORRECTED_WORD_INDEX, 1%) + & RIGHT(INPUT_LINE, & LAST_LETTER_LOCATION + 1%) ! ----- STORE THE UNKNOWN SPELLING STATUS ----- ! ----- OF THIS QUICK WORD SO THAT WE WILL ----- ! ----- KEEP CORRECTING IT ----- QUICK_WORD_STATUS(QUICK_WORD_INDEX, 1%) = 1% ! ----- RECALCULATE NEW POSITION POINTER ----- ! ----- TO SCAN TEXT LINE FROM (SINCE THE ----- ! ----- NEW WORD MAY BE A DIFFERENT LENGTH ----- ! ----- THAN THE OLD WORD) ----- POSITION_INDEX = POSITION_INDEX + & LEN(CORRECTED_WORDS( & CORRECTED_WORD_INDEX, 1%)) - & (LAST_LETTER_LOCATION - & FIRST_LETTER_LOCATION + 1%) ITERATE END IF END IF MAX_CHOICES = 0% ERROR_LINE = "PROGRAM FUNCTION" SELECT PROGRAM_FUNCTION CASE "A" ! IF ASSEMBLING A LIST OF WORDS: ! ----- GET POSITION OF PREVIOUSLY WRONG WORD ----- TEMP = POS(INCORRECT_WORDS, & CR+LF + WORD_WITH_APOSTROPHE + CR+LF, 1%) ! ----- SEE IF PREVIOUSLY WRONG ----- IF TEMP = 0% THEN ! ----- ALWAYS STORE THE FIRST TIME THAT ----- ! ----- THIS WORD IS SPELLED WRONG ----- INCORRECT_WORDS = INCORRECT_WORDS + & WORD_WITH_APOSTROPHE + CR+LF ELSE ! ----- DONE WITH THIS WORD IF PREVIOUSLY ----- ! ----- WRONG AND ONLY THE FIRST BAD WORD ----- ! ----- IS TO BE PRINTED ----- IF PRINT_ONLY_FIRST_BAD_WORD THEN ! ----- STORE THE BAD STATUS OF ----- ! ----- THIS QUICK WORD ----- QUICK_WORD_STATUS( & QUICK_WORD_INDEX, 1%) = 0% ITERATE END IF END IF ! ----- ASSEMBLE A LIST OF MISSPELLED WORDS ----- PRINT #2%, NUM1$(LINE_COUNTER); TAB(8%); & WORD_WITH_APOSTROPHE; PRINT #2%, TAB(30%);"(duplicate)"; IF TEMP > 0% PRINT #2% ! ----- STORE THE BAD STATUS OF THIS QUICK WORD ----- QUICK_WORD_STATUS(QUICK_WORD_INDEX, 1%) = 0% ITERATE CASE "U" ! AUTO-STORE NEW WORDS ! ----- ADD TO APPROPRIATE DICTIONARY ----- IF DICTIONARY_CHANNEL = 3% THEN INCORRECT_WORD_RESPONSE = "A" ELSE INCORRECT_WORD_RESPONSE = "P" END IF PRINT IF CURSOR_POSITION > 0% IF LEN(WORD_TO_BE_CHECKED) < 33% THEN PRINT "Auto-storing " + WORD_TO_BE_CHECKED ELSE PRINT "Skipping " + WORD_TO_BE_CHECKED END IF CASE ELSE ! CHECKING A TEXT FILE... ! ----- CHECK IF BAD WORD IS ALL CAPITALS, ----- ! ----- ALL LOWERCASE, ONLY FIRST CAPITALIZED, ----- ! ----- OR MIXED ----- ALL_UPPERCASE = TRUE FIRST_CAPITAL = FALSE ! ----- SCAN ENTIRE BAD WORD ----- FOR TEMP = FIRST_LETTER_LOCATION TO LAST_LETTER_LOCATION SELECT MID(INPUT_LINE, TEMP, 1%) CASE "A" TO "Z" IF TEMP = FIRST_LETTER_LOCATION THEN FIRST_CAPITAL = TRUE ELSE FIRST_CAPITAL = FALSE END IF CASE "a" TO "z" ALL_UPPERCASE = FALSE END SELECT NEXT TEMP INCORRECT_WORD_RESPONSE = "" PRINT IF CURSOR_POSITION <> 0% PRINT PRINT "---------- Line " + NUM1$(LINE_COUNTER) & + ": ----------" PRINT INPUT_LINE_PREV2 IF INPUT_LINE_PREV2 <> "~%(" PRINT INPUT_LINE_PREV1 IF INPUT_LINE_PREV1 <> "~%(" PRINT LEFT(INPUT_LINE, FIRST_LETTER_LOCATION - & 1%) + BOLD_VIDEO + SEG$(INPUT_LINE, & FIRST_LETTER_LOCATION, & LAST_LETTER_LOCATION) + NORMAL_VIDEO + & RIGHT(INPUT_LINE, LAST_LETTER_LOCATION + 1%) PRINT "Not in Dictionary: " + WORD_WITH_APOSTROPHE MAX_CHOICES = DISPLAY_POSSIBLE_SPELLINGS END SELECT CURSOR_POSITION = 0% ! ----- ASK THE USER WHAT HE WANTS TO DO ----- WHILE INCORRECT_WORD_RESPONSE = "" IF DISPLAY_MENU_OPTIONS THEN PRINT PRINT "Enter L Leave word as it is" IF OUTPUT_FILE <> "NL:" THEN ! ----- INVALID "C" OPTION IF ----- ! ----- HYPHENATED ----- IF NOT HYPHEN_FLAG THEN PRINT " C" + & " Change the word" ELSE PRINT " " + & " (Can" + & "'t change a" + & " hyphenated word)" END IF END IF PRINT " S Leave and" + & " stop asking about this word" IF LEN(WORD_TO_BE_CHECKED) < 33% THEN PRINT " A " + & "Leave, stop asking," + & " and add to general" + & " dictionary" IF PRIV_FLAG PRINT " P " + & "Leave, stop asking," + & " and add to private dictionary" END IF PRINT " D Search the" + & " dictionary for a range of spellings" PRINT " E Store all" + & " changes which have been" + & " made and then Exit program." PRINT " T Terminate this" + & " program without saving any changes." IF MAX_CHOICES <> 0% THEN PRINT " Or enter" & + " the number of" + & " the correct word" END IF DISPLAY_MENU_OPTIONS = FALSE END IF FOUND_MATCH = FALSE WHEN ERROR IN LINPUT & "Enter Option (Press for list of options) "; & INCORRECT_WORD_RESPONSE USE FOUND_MATCH = TRUE CONTINUE END WHEN ITERATE IF FOUND_MATCH ! RE-PROMPT IF ANY RESPONSE ERR ! ----- UPPERCASE AND DISCARD GARBAGE ----- INCORRECT_WORD_RESPONSE = & EDIT$(INCORRECT_WORD_RESPONSE, 38%) ! ----- EXIT IF ANY "E[XIT]" RESPONSE ----- IF LEN(INCORRECT_WORD_RESPONSE) > 0% THEN GOTO COPY_TO_EOF IF & INCORRECT_WORD_RESPONSE = & LEFT("EXIT", & LEN(INCORRECT_WORD_RESPONSE)) ELSE DISPLAY_MENU_OPTIONS = TRUE ITERATE END IF ! ----- SEE IF VALID NUMERIC WORD CHOICE ----- IF MAX_CHOICES <> 0% THEN IF LEN(INCORRECT_WORD_RESPONSE) > 0% & AND LEN(INCORRECT_WORD_RESPONSE) < 6% THEN IF NUMERIC(INCORRECT_WORD_RESPONSE) THEN TEMP_LONG2 = INTEGER( & INCORRECT_WORD_RESPONSE, & LONG) IF TEMP_LONG2 > 0% AND & TEMP_LONG2 <= & MAX_CHOICES THEN ! ----- SET FLAG ----- ! ----- SO AS TO ----- ! ----- CHANGE ----- ! ----- THIS WORD ----- INCORRECT_WORD_RESPONSE& = "C" ! ----- STORE ----- ! ----- CORRECTED ----- ! ----- WORD ----- NEW_WORD_SPELLING = & DICT_WORDS( & TEMP_LONG2) ITERATE END IF END IF END IF END IF SELECT INCORRECT_WORD_RESPONSE CASE "T" ! TERMINATE PROCESSING ! ----- STORE "ABORT" PROGRAM CODE ----- TEMP_LONG2 = -1234% ! ----- SET FLAG SO AS TO DELETE OUTPUT ----- ! ----- FILE ----- CORRECTIONS_MADE = FALSE GOTO END_PROGRAM! STOP PROGRAM CASE "D" ! SEARCH THE DICTIONARY IF SEARCH_THE_DICTIONARY THEN ! ----- SET FLAG SO AS TO CHANGE ----- ! ----- THIS WORD ----- INCORRECT_WORD_RESPONSE = "C" ELSE PRINT CLEAR_SCREEN ! ----- CLEAR VARIABLE TO ----- ! ----- RE-PROMPT USER ----- INCORRECT_WORD_RESPONSE = "" DISPLAY_MENU_OPTIONS = TRUE ITERATE END IF CASE "L" ! LEAVE THIS WORD ! ----- ASSUME WORD IS NOT TO BE ADDED ----- USER_OPTION = "N" ITERATE IF LEN(WORD_TO_BE_CHECKED) > 32% FOUND_MATCH = FALSE WHILE NOT FOUND_MATCH PRINT IF PRIV_FLAG THEN PRINT "Enter:" PRINT " P = Add this" +& " word to you" +& "r private di" +& "ctionary, OR" PRINT " G = Add this" +& " word to the" +& " general dic" +& "tionary, OR" PRINT " N = Do NOT a" +& "dd this word" +& " to any dict" +& "ionary "; ELSE PRINT "Add this word " +& "to your priv" +& "ate dictiona" +& "ry (Y/N) "; END IF WHEN ERROR IN LINPUT USER_OPTION USE FOUND_MATCH = TRUE USER_OPTION = "*" CONTINUE END WHEN ITERATE IF FOUND_MATCH ! ----- UPPERCASE AND DISCARD ----- ! ----- GARBAGE ----- USER_OPTION = EDIT$(USER_OPTION, 38%) USER_OPTION = "N" IF USER_OPTION = "" SELECT USER_OPTION CASE "P" USER_OPTION = "" & IF NOT PRIV_FLAG DICTIONARY_CHANNEL = 4% CASE "G" USER_OPTION = "" & IF NOT PRIV_FLAG DICTIONARY_CHANNEL = 3% CASE "N" CASE "Y" IF PRIV_FLAG THEN USER_OPTION = "" ELSE USER_OPTION = "P" END IF DICTIONARY_CHANNEL = 4% CASE ELSE USER_OPTION = "" END SELECT IF USER_OPTION = "" THEN PRINT PRINT "*** Invalid" + & " Response -" + & " Try Again ***" + BEL PRINT ELSE FOUND_MATCH = TRUE END IF NEXT ITERATE IF USER_OPTION = "*" CASE "C" ! CHANGE THIS WORD IF OUTPUT_FILE = "NL:" OR HYPHEN_FLAG THEN ! ----- CLEAR VARIABLE TO ----- ! ----- RE-PROMPT USER ----- INCORRECT_WORD_RESPONSE = "" ELSE PRINT "Type in the New" + & " Spelling for " + & BOLD_VIDEO + WORD_FOUND & + NORMAL_VIDEO + " "; FOUND_MATCH = FALSE WHEN ERROR IN LINPUT NEW_WORD_SPELLING USE FOUND_MATCH = TRUE CONTINUE END WHEN ! ----- RE-PROMPT IF ANY RESPONSE ----- ! ----- ERROR ----- ITERATE IF FOUND_MATCH IF NEW_WORD_SPELLING = "" THEN TEMP_STRING = "" WHILE TEMP_STRING <> & "Y" AND & TEMP_STRING <> "N" PRINT " Do you rea" + & "lly want t" + & "o delete t" + & "his word? " + & "(Y/N) "; WHEN ERROR IN LINPUT & TEMP_STRING USE CONTINUE END WHEN ! ----- UPPERCASE ----- ! ----- AND ----- ! ----- DISCARD ----- ! ----- GARBAGE ----- TEMP_STRING = & EDIT$( & TEMP_STRING, & 38%) NEXT ITERATE IF TEMP_STRING = "N" END IF END IF CASE "S" ! LEAVE THIS WORD AND STOP CASE "A" ! LEAVE, STOP, ADD TO GENERAL IF LEN(WORD_TO_BE_CHECKED) > 32% OR NOT & PRIV_FLAG THEN ! ----- CLEAR VARIABLE TO ----- ! ----- RE-PROMPT USER ----- INCORRECT_WORD_RESPONSE = "" END IF CASE "P" ! LEAVE, STOP, ADD TO PRIVATE IF LEN(WORD_TO_BE_CHECKED) > 32% THEN ! ----- CLEAR VARIABLE TO ----- ! ----- RE-PROMPT USER ----- INCORRECT_WORD_RESPONSE = "" END IF CASE ELSE ! ----- CLEAR VARIABLE TO RE-PROMPT USER ----- INCORRECT_WORD_RESPONSE = "" END SELECT IF INCORRECT_WORD_RESPONSE = "" THEN PRINT PRINT "*** Invalid Response - Try" + & " Again ***" + BEL PRINT DISPLAY_MENU_OPTIONS = TRUE END IF NEXT SELECT INCORRECT_WORD_RESPONSE CASE "L" ! LEAVE THIS WORD SELECT USER_OPTION CASE "G", "P" ! ADD WORD TO A DICTIONARY ! ----- MOVE THE NEW WORD TO THE MAP ----- DICTIONARY_RECORD = WORD_TO_BE_CHECKED ! ----- STORE NEW WORD IN DICTIONARY ----- PUT #DICTIONARY_CHANNEL END SELECT CASE "C" ! CHANGE THIS WORD ! ----- STORE UP TO 500 CORRECT WORDS ----- IF CORRECTED_WORD_TOT < 500% THEN CORRECTED_WORD_TOT = CORRECTED_WORD_TOT + 1% CORRECTED_WORDS(CORRECTED_WORD_TOT, 0%) & = WORD_WITH_APOSTROPHE CORRECTED_WORDS(CORRECTED_WORD_TOT, 1%) & = NEW_WORD_SPELLING END IF ! ----- REPLACE THE WORD ----- INPUT_LINE = LEFT(INPUT_LINE, & FIRST_LETTER_LOCATION - 1%) + & NEW_WORD_SPELLING + & RIGHT(INPUT_LINE, LAST_LETTER_LOCATION + 1%) CORRECTIONS_MADE = TRUE ! CORRECTIONS HAVE BEEN MADE PRINT PRINT " New Text is:" PRINT INPUT_LINE ! ----- RECALCULATE NEW POSITION POINTER TO ----- ! ----- SCAN TEXT LINE FROM (SINCE THE NEW WORD ----- ! ----- MAY BE A DIFFERENT LENGTH THAN THE OLD ----- ! ----- WORD) ----- POSITION_INDEX = POSITION_INDEX + & LEN(NEW_WORD_SPELLING) - & (LAST_LETTER_LOCATION - & FIRST_LETTER_LOCATION + 1%) CASE "S" ! LEAVE THIS WORD AND STOP ! ----- ADD THIS WORD TO THE LIST OF THE OKAY ----- ! ----- WORDS ----- OKAY_WORDS = OKAY_WORDS + WORD_TO_BE_CHECKED + CR+LF WORD_STATUS = -1% ! ----- LEAVE WORD AS IT IS ----- CASE "A", "P" ! LEAVE, STOP, ADD TO DICTIONARY SELECT PROGRAM_FUNCTION CASE "C" ! CHECK A TEXT FILE ! ----- ADD THIS WORD TO THE LIST OF THE ----- ! ----- OKAY WORDS ----- OKAY_WORDS = OKAY_WORDS + & WORD_TO_BE_CHECKED + CR+LF WORD_STATUS = -1% END SELECT ! ----- STORE WORD IN GENERAL DICTIONARY ----- IF LEN(WORD_TO_BE_CHECKED) < 33% THEN ! ----- ADD THIS WORD ALSO TO THE DESIRED ----- ! ----- DICTIONARY ----- ! ----- MOVE THE WORD TO THE MAP ----- DICTIONARY_RECORD = WORD_TO_BE_CHECKED ! ----- STORE "CORRECT" SPELLING STATUS ----- WORD_STATUS = -1% ! ----- STORE RECENT WORD STATUS AS BEING ----- ! ----- CORRECTLY SPELLED ----- RECENT_WORD_STATUS(RECENT_WORD_INDEX, 1%) = -1% WHEN ERROR IN IF INCORRECT_WORD_RESPONSE = "A" THEN ! ----- STORE WORD IN ----- ! ----- GENERAL DICTIONARY ----- PUT #3% ELSE ! ----- STORE WORD IN ----- ! ----- PRIVATE DICTIONARY ----- PUT #4% END IF USE IF ERR = BUCKET_LOCKED THEN SLEEP 1% RETRY END IF EXIT HANDLER IF ERR <> DUPLICATE_KEY CONTINUE! SKIP IF ALREADY IN DICTIONARY END WHEN END IF END SELECT ! ----- PRINT "CHECKING" DESC IF NOT AUTO-STORING WORDS ----- IF PROGRAM_FUNCTION <> "U" THEN PRINT "...Checking Line "; CURSOR_POSITION = 17% END IF ! ----- STORE THE STATUS OF THIS QUICK WORD AFTER ----- ! ----- PROCESSING THE USER'S RESPONSE ----- QUICK_WORD_STATUS(QUICK_WORD_INDEX, 1%) = WORD_STATUS NEXT ! ------------------------------------------------------------ ! ----- SUBROUTINE TO READ THE NEXT LINE FROM INPUT FILE ----- ! ------------------------------------------------------------ READ_NEXT_INPUT_LINE: INPUT_LINE_PREV2 = INPUT_LINE_PREV1 ! STORE PREV IN PREV INPUT LINE INPUT_LINE_PREV1 = INPUT_LINE ! STORE LAST IN PREV INPUT LINE FOUND_MATCH = TRUE ! SO LOOP WILL EXECUTE WHILE FOUND_MATCH ! READ LINES TILL ANY CHARS READ FOUND_MATCH = FALSE ! ASSUME LOOP WILL EXIT ! ----- DO NOT PRINT PREVIOUS LINE IF ASSEMBLE MODE ----- IF PROGRAM_FUNCTION <> "A" THEN ! ----- PRINT ANY PREVIOUS LINE TO THE OUTPUT FILE ----- PRINT #2%, INPUT_LINE IF PREVIOUS_LINE_FLAG ! ----- NO PREVIOUS LINE IN MEMORY ----- PREVIOUS_LINE_FLAG = FALSE END IF IF EOF_FLAG THEN PRINT PRINT "Finished Checking Spelling." PRINT ! ----- STORE "FINISHED" PROGRAM CODE ----- TEMP_LONG2 = -1233% GOTO END_PROGRAM END IF ! ----- READ NEXT LINE FROM THE INPUT FILE ----- WHEN ERROR IN LINPUT #1%, INPUT_LINE USE IF ERR = BUCKET_LOCKED THEN SLEEP 1% RETRY END IF EXIT HANDLER IF ERR <> END_OF_FILE ! ----- EOF ON INPUT FILE WAS FOUND ----- EOF_FLAG = TRUE ! SET END-OF-FILE FLAG INPUT_LINE = "" CONTINUE END WHEN POSITION_INDEX = 1% ! INIT POSITION WITHIN LINE RETURN IF EOF_FLAG ! DONE IF END-OF-FILE FLAG SET PREVIOUS_LINE_FLAG = TRUE ! SET FOR PREVIOUS LINE IN MEM LINE_COUNTER = LINE_COUNTER + 1% TEN_COUNTER = TEN_COUNTER + 1% IF TEN_COUNTER >= 10% THEN TEN_COUNTER = 0% PRINT " " + NUM1$(LINE_COUNTER); CURSOR_POSITION = CURSOR_POSITION + 1% + & LEN(NUM1$(LINE_COUNTER)) IF CURSOR_POSITION > 70% THEN PRINT ! END PRINT LINE CURSOR_POSITION = 0% END IF END IF IF LEN(INPUT_LINE) < 2% THEN ! ----- STORE PREV IN PREV INPUT LINE ----- INPUT_LINE_PREV2 = INPUT_LINE_PREV1 INPUT_LINE_PREV1 = INPUT_LINE ! ----- SET FLAG SO AS TO READ NEXT LINE ----- FOUND_MATCH = TRUE END IF NEXT RETURN ERROR_ROUTINE: ! ----- ERROR-HANDLING ROUTINE ----- TEMP_STRING = ERT$(ERR) CLOSE #TEMP FOR TEMP = 1% TO 12% ! CLOSE ALL OPEN FILES IF ERR <> CONTROL_C_TRAP THEN PRINT "UNEXPECTED ERROR " + NUM1$(ERR) + " OCCURRED" + & BEL + BEL + BEL PRINT "AFTER ERROR_LINE: " + ERROR_LINE PRINT TEMP_STRING PRINT "*** PROGRAM TERMINATED ***" END IF TEMP_LONG2 = -1234% ! STORE "ABORT" PROGRAM CODE RESUME END_PROGRAM ! STOP PROGRAM COPY_TO_EOF: ! ----- SKIP DATA COPY IF IN ASSEMBLE MODE ----- IF PROGRAM_FUNCTION <> "A" THEN PRINT PRINT "Copying data - Please wait..." PRINT FOUND_MATCH = TRUE ! SO LOOP WILL EXECUTE WHILE FOUND_MATCH ! READ LINES TILL ANY CHARS READ ! ----- PRINT ANY PREVIOUS LINE TO THE OUTPUT FILE ----- PRINT #2%, INPUT_LINE IF PREVIOUS_LINE_FLAG ! ----- READ NEXT LINE FROM THE INPUT FILE ----- WHEN ERROR IN LINPUT #1%, INPUT_LINE USE IF ERR = BUCKET_LOCKED THEN SLEEP 1% RETRY END IF EXIT HANDLER IF ERR <> END_OF_FILE ! ----- EOF ON INPUT FILE WAS FOUND ----- FOUND_MATCH = FALSE ! SET SO LOOP WILL EXIT CONTINUE END WHEN ! ----- SET FLAG FOR PREVIOUS LINE IN MEMORY ----- PREVIOUS_LINE_FLAG = TRUE NEXT END IF END_PROGRAM: ! ----- END OF PROGRAM ----- CLOSE #TEMP FOR TEMP = 1% TO 12% ! CLOSE ALL OPEN FILES IF PROGRAM_FUNCTION = "C" THEN ! IF CHECKING A TEXT FILE: IF NOT CORRECTIONS_MADE THEN ! IF ANY CORRECTIONS WERE MADE: IF OUTPUT_FILE <> "NL:" THEN IF NOT EVE_SPELL THEN PRINT "(Deleting new output" + & " file since no" + & " corrections were" + & " made...)" IF & TEMP_LONG2 <> -1234% PRINT END IF ! ----- SEE IF ABORTING PROGRAM OR NORMAL ----- ! ----- PROGRAM FINISH ----- IF TEMP_LONG2 = -1233% OR TEMP_LONG2 = -1234% THEN WHEN ERROR IN KILL OUTPUT_FILE USE PRINT PRINT "SPELL: Error" + & " deleting" + & " output file" + BEL PRINT " Please" + & " delete the" + & " LATEST" + & " version of " & + OUTPUT_FILE PRINT CONTINUE END WHEN END IF END IF END IF END IF PRINT "Done..." + BEL IF NOT EVE_SPELL IF TEMP_LONG2 = -1234% THEN ! ----- EXIT WITH ERROR STATUS, BUT WITH NO VMS MESSAGE ----- ! ----- DISPLAYED ----- LIB_STATUS = SYS$EXIT(ERROR_WITH_NO_MSG BY VALUE) END IF END