predict@charon.unm.edu (Andrew R. Large) (10/15/88)
Posting-number: Volume 4, Issue 124 Submitted-by: "Andrew R. Large" <predict@charon.unm.edu> Archive-name: sp Here is my simple UNIX(tm) spelling program. Nothing terribly exciting, just gives a curses interface to spell, (f)grep, and ex. Should be fairly stable for BSD environment. Don't have a (yuck) [right back at you! ++bsa] SYSV machine handy to test it on. Needs getopt and the -w option of grep. Other than that, fairly vanilla (I hope). Thought I'd send it in given the current craze over spelling programs. -=*=-=*=-=*=-=*=-=*=-=*=-=*=-=*=-=*=-=*=-=*=-=*=-=*=-=*=-=*=-=*=-=*=-=*=-=*=- * Andrew R. Large * ** (work) 505/255-8611 ------| Univ of New Mexico EECE Department ** *** (home) 505/888-4010 |---> Management Sciences, Inc. [MSI] *** **** _Babooshka!_ **** *** Usenet: {convex,gatech,ucbvax,csu-cs,anl-mcs}!unmvax!charon!predict *** ** Internet: predict@charon.UNM.EDU ** * If I am quoted, my employers will deny my existence. * -=*=-=*=-=*=-=*=-=*=-=*=-=*=-=*=-=*=-=*=-=*=-=*=-=*=-=*=-=*=-=*=-=*=-=*=-=*=- #!/bin/sh # shar: Shell Archiver # Run the following text with /bin/sh to create: # sp # This archive created: Thu Oct 13 01:15:11 1988 # By: Andrew R. Large (University of New Mexico, Albuquerque) echo shar: creating directory sp mkdir sp cd sp echo shar: extracting Makefile '(498 characters)' sed 's/^XX//' << \SHAR_EOF > Makefile XX#! /bin/sh XX# XX# Makefile for sp XX# Written by Andrew Large XX# XX XXBIN = /u1/staff/andy/bin XXMAN = /u1/staff/andy/man XX XXEXEC = sp XXMANPAGE = $(EXEC).1 XXHDRS = $(EXEC).h XX XXOBJS = $(EXEC).o doc_correct.o local_add.o parse.o spell.o tools.o user_input.o\ XX user_tools.o XXLIBS = -lcurses -ltermlib XXCC = cc XX XXCFLAGS = -O XX XX$(EXEC): $(OBJS) XX $(CC) $(CFLAGS) $(OBJS) -o $@ $(LIBS) XX XXinstall: $(EXEC) XX strip $(EXEC) XX cp $(EXEC) $(BIN) XX cp $(MANPAGE) $(MAN)/man1 XX XX$(OBJS): $(HDRS) XX XXclean: XX /bin/rm -f $(EXEC) core *.o *.out SHAR_EOF if test 498 -ne "`wc -c Makefile`" then echo shar: error transmitting Makefile '(should have been 498 characters)' fi echo shar: extracting README '(1617 characters)' sed 's/^XX//' << \SHAR_EOF > README XXSp is a visual spelling program. It may be run on one or more files, and XXfor each file, it presents a word-by-word list of the words spell(1) thinks XXare misspelled. You may then take any of a host of actions. XX XXThis program has come through many stages during its development. When it was XXoriginally written, it was designed around a shell script posted in net.sources XXin 1985 that put all misspelled words into a file, had you correct the file, XXand then, from the difference between the files, made the corrections. XX XXThe current version is so different from the original shell script that I don't XXcredit the original authors any more. After completing this program, I have XXnoticed a resemblance to both ispell and correct. However, this was written XXbefore I ever saw either of those programs, and no code was taken from either XXone when writing this. XX XXTo install: XX XX1) Edit 'sp.h' to reflect your current situation (mainly locations of system XX programs). XX2) Edit 'Makefile' and change 'BIN', 'MAN', and 'CC' to reflect your situation XX3) Type 'make' XX4) If everything looks OK, type 'make install' XX XXCopyright (C) 1988 Andrew Large XX XXThis software may be used and/or modified on any machine by anyone, as long XXas you don't violate the following conditions: XX XX 1) This copyright notice and the one in the program are left intact. XX XX 2) You credit me with original authorship. XX XX 3) No monetary gain is made by selling or distributing this software. XX XXI will be more than willing to try and support any additions/bug-fixes, but I XXWILL NOT ACCEPT RESPONSIBILITY FOR ANY HARM CAUSED DIRECTLY OR INDIRECTLY BY XXTHIS PROGRAM. SHAR_EOF if test 1617 -ne "`wc -c README`" then echo shar: error transmitting README '(should have been 1617 characters)' fi echo shar: extracting local_add.c '(1054 characters)' sed 's/^XX//' << \SHAR_EOF > local_add.c XX# include "sp.h" XX XX/* XX** local_add XX** Add all words in correct list to personal dictionary XX** and sort the dictionary. XX*/ XXlocal_add () { XX char *mktemp (), XX string[256]; XX FILE *fopen (), XX *tmp_ptr; XX register int loop; XX XX if ( access (dict, 0) == 0 && access (dict, 2) != 0 ) { XX sprintf (string, XX "Your local dictionary \"%s\" is not writable!", dict); XX message (True, string); XX return; XX } XX XX if ((tmp_ptr = fopen (mktemp (tmp_file), "w")) == NULL) { XX sprintf (string, XX "Your local dictionary \"%s\" is not writable!", dict); XX message (True, string); XX return; XX } XX XX for (loop = 0; loop < num_correct; loop++) XX fprintf (tmp_ptr, "%s\n", correct[loop]); XX XX fclose (tmp_ptr); XX XX if (vfork () == 0) { XX if (local) XX execl (SORT, "sort", "-f", "-m", "-o", dict, dict, XX tmp_file, (char *) 0); XX else XX execl (SORT, "sort", "-f", "-m", "-o", dict, tmp_file, XX (char *) 0); XX perror (SORT); XX _exit (-1); XX } XX XX wait (0); XX sprintf (string, "%d %s added to %s", num_correct, XX (num_correct == 1 ? "word" : "words"), dict); XX message (False, string); XX} SHAR_EOF if test 1054 -ne "`wc -c local_add.c`" then echo shar: error transmitting local_add.c '(should have been 1054 characters)' fi echo shar: extracting parse.c '(1156 characters)' sed 's/^XX//' << \SHAR_EOF > parse.c XX# include "sp.h" XX XX/* XX** parse XX** Parse input for -d option and establish whether XX** or not a personal dictionary exists XX*/ XXparse (argc, argv, place) XXint argc, *place; XXchar *argv[]; XX{ XX extern char *optarg; XX extern int optind; XX char *getenv (), getopt (); XX int option; XX XX if (argc < 2) XX usage (argv[0]); XX XX local = False; XX while ((option = getopt (argc, argv, "d:")) != EOF) XX switch (option) { XX case 'd': XX sprintf (dict, "%s", optarg); XX local = True; XX break; XX case '?': XX default: XX usage (argv[0]); XX } XX XX if (argv[optind] == NULL) XX usage (argv[0]); XX XX if (!local) XX if (getenv ("DICT") != NULL) XX strcpy (dict, getenv ("DICT")); XX else XX strcpy (dict, "./spelldict"); XX XX switch (check_dict ()) { XX case 1: XX local = True; XX break; XX case 0: XX local = False; XX printf ("\nYour local dictionary %s does not exist.", XX dict); XX printf ("\nI may try to create it later ..."); XX fflush (stdout); XX sleep (1); XX break; XX case -1: XX local = False; XX printf ("\nYour local dictionary %s is not readable.", XX dict); XX printf ("\nI may try to write to it later ..."); XX fflush (stdout); XX sleep (1); XX break; XX } XX *place = optind; XX} SHAR_EOF if test 1156 -ne "`wc -c parse.c`" then echo shar: error transmitting parse.c '(should have been 1156 characters)' fi echo shar: extracting sp.1 '(3717 characters)' sed 's/^XX//' << \SHAR_EOF > sp.1 XX.\" XX.\" Copyright (C) 1988 Andrew Large XX.\" XX.TH SP 1 "Version 3.4" XX.DA May 1988 XX.SH NAME XXsp \- check spelling of a document and fix any mistakes XX.SH SYNOPSIS XX.B sp XX[ XX.B \-d XX.B dictionary XX] XX.B file XX[ XX.B file2 XX.B ... XX] XX.SH DESCRIPTION XX.IR sp XXcalls spell(1) to check the spelling of a document. If you specify a XXpersonal dictionary (with the \-d option), this is searched in addition XXto the system dictionary for proper spellings of words. If you do not XXspecify a personal dictionary, XX.IR sp XXchecks for an environment variable called DICT. If it exists, it is taken XXto be the full path to your personal dictionary. If you do not XXspecify a personal dictionary or have $DICT defined, the file ``spelldict'' XXin your current directory will be established as your personal dictionary. XX.PP XXOnce the mis-spelled words are identified, you are prompted word by XXword for an action to take. Your choices are given in brackets and XXexplained below. XX.IP A XXMark the word for addition to your personal dictionary. XX.IP C XXMark the word for correction. You will be asked for the correct spelling. XX.IP I XXIgnore the word in question. This is the default option and is XXgenerally used when a word is spelled correctly for its usage, but XXyou don't want it added to your personal dictionary. XX.IP L XXLook up a string in the system dictionary. This is appropriate for XXobtaining the proper spelling of the word. You will be prompted for a string XXthat look(1) will use on the system dictionary. XX.IP W XXShow where the word occurs in the document. Runs grep(1) on the document XXfile searching for occurrences of the word and prints out lines that XXcontain the word. XX.IP ^ XXGo to previous document (given on command line). If your current document XXis the first given on the command line, this will re-run spell(1) on your XXcurrent document. If you have marked any words for correction or XXaddition to your personal dictionary, you will be XXasked whether or not you want to save your changes. XX.IP # XXGo to next document (given on command line). If your current document is XXthe last given on the command line, this exits the program. If you XXhave marked any words for correction or addition to your personal XXdictionary, you will be asked whether or not you want to save your changes. XX.IP + XXGo to next word. If you haven't taken action with the current word, this XXoption is equivalent to an ignore (don't correct or add to personal XXdictionary). Otherwise, previous actions hold true, i.e. if you correct XXa word, hit a '-' to go back to it, and hit a '+' to skip forward past it, XXthe correction would still be the course taken. However, if you hit an XX'I' to skip forward past it, no correction would take place. XX.IP - XXGo to previous word. This is the course of action to take if you XXmess up a correction or change your mind in some way. XX.IP ? XXThis will display a short help menu. XX.IP ^L XXThis will redraw the screen (as in vi(1)). XX.PP XXAfter you have processed all the words, you are prompted for an XXadditional action. You may go to either the previous or the next document. XXIn either case, you will be asked whether or not you wish to save your changes. XXIn this manner, you can make corrections to a file, and then back up to check XXyour corrections. Corrections are made to the documents via XX.B ex(1). XX.PP XXThe spelling checking is done one file at a time, so if you have the same XXmis-spelled word in several files, you will have to correct it for each file. XXHowever, the personal dictionary is updated between the checks on each file, XXso additions to it will be available when the next file is checked. XX.SH AUTHOR XXAndrew Large XX.SH FILES XX.nf XX$DICT, spelldict -- default personal dictionaries XX.fi XX.SH "SEE ALSO" XXex(1), grep(1), look(1), spell(1) SHAR_EOF if test 3717 -ne "`wc -c sp.1`" then echo shar: error transmitting sp.1 '(should have been 3717 characters)' fi echo shar: extracting sp.c '(1836 characters)' sed 's/^XX//' << \SHAR_EOF > sp.c XX# include "sp.h" XX# include <signal.h> XX XX/* XX** sp(1) -- uses spell(1) to check the spelling of a document. XX** The user is prompted with each of the mis-spelled words and XX** can ignore them, add them to a personal dictionary, correct XX** them, look up words in the dictionary, or find out where in XX** the file the word is found. Corrections are made to the XX** document via ex(1). XX** XX** Author: Andrew Large XX** December 1986 (First Edition) XX** May 1988 (Current Version) XX*/ XX XXchar *id = "@(#)sp.c\t3.4\t5/88"; XX XXchar *tmp_file = "/tmp/spXXXXXX"; XXchar dict[FILE_NAME_LEN], doc[FILE_NAME_LEN], XX *new[MAX_WORDS], *correct[MAX_WORDS], XX *orig[MAX_WORDS]; XX XXboolean local; XX XXint num_found, num_correct, num_ignored; XX XXmain (argc, argv) XXint argc; XXchar *argv[]; XX{ XX int place, XX spell_val, XX start_place; XX XX parse (argc, argv, &place); /* Parse input arguments */ XX start_place = place; XX XX /* XX ** Initialization XX */ XX signal (SIGINT, leave); signal (SIGQUIT, leave); XX initscr (); crmode (); noecho (); XX mvaddstr (9, 30, VERSION1); XX mvaddstr (10, 28, VERSION2); XX mvaddstr (11, 31, VERSION3); XX move (0, 0); refresh (); sleep (1); XX XX for (; place < argc; place++) { XX sprintf (doc, "%s", argv[place]); XX num_found = num_correct = num_ignored = 0; XX clean_lists (); XX XX if (check_dict () == 1) XX local = True; XX else XX local = False; XX XX if ( (spell_val = spell ()) >= 0 ) XX switch (user_input ()) { XX case -2: /* previous doc, no save */ XX if (place > start_place) XX place -= 2; XX else XX --place; XX break; XX case -1: /* previous doc, save */ XX save (spell_val); XX if (place > start_place) XX place -= 2; XX else XX --place; XX break; XX case 0: /* normal exit with save */ XX case 1: /* early exit with save */ XX save (spell_val); XX case 2: /* early exit, no save */ XX default: XX break; XX } XX } XX leave (); XX} SHAR_EOF if test 1836 -ne "`wc -c sp.c`" then echo shar: error transmitting sp.c '(should have been 1836 characters)' fi echo shar: extracting spell.c '(1884 characters)' sed 's/^XX//' << \SHAR_EOF > spell.c XX# include "sp.h" XX XX/* XX** spell XX** Run spell(1) on the file and check personal dictionary also. XX** Establishes the original list of mis-spelled words XX*/ XXspell () { XX char command[256]; XX int ypos, xpos, ret_val; XX FILE *popen (), *fopen (), *spell_out; XX XX clear (); fname (); XX XX ret_val = 0; XX XX if (access (doc, 0) != 0) { /* Check for existence */ XX sprintf (command, "Cannot access file %s!", doc); XX message (True, command); XX return (-1); XX } XX XX if (access (doc, 6) != 0) { /* Read and write */ XX if (access (doc, 4) != 0) { /* Read */ XX sprintf (command, "You are unable to read %s!", doc); XX message (True, command); XX return (-1); XX } XX mvaddstr (3, 0, "You are unable to write to this file"); XX mvaddstr (4, 0, "I will check spelling, but you will not be "); XX addstr ("able to save any corrections"); XX ret_val = 1; XX move (0,0); refresh (); sleep (3); fname (); XX } XX XX message (False, "Checking spelling ..."); XX XX /* XX ** Get the list of mis-spelled words XX */ XX if (local) XX sprintf (command, "%s %s | %s -v -f %s", SPELL, doc, FGREP, XX dict); XX else XX sprintf (command, "%s %s", SPELL, doc); XX XX spell_out = popen (command, "r"); XX XX for (num_found = 0; num_found < MAX_WORDS; num_found++) { XX orig[num_found] = sfalloc ((unsigned) WORD_LENGTH); XX if (fgets (orig[num_found], WORD_LENGTH, spell_out) == NULL) XX break; XX else XX orig[num_found][strlen (orig[num_found]) - 1] = '\0'; XX } XX fclose (spell_out); XX XX if (num_found >= MAX_WORDS) { XX getyx (stdscr, ypos, xpos); XX sprintf (command, "You have more than %d mis-spelled words", XX MAX_WORDS); XX mvaddstr (5, 10, command); XX sprintf (command, "Run this again after corrections are made"); XX mvaddstr (6, 10, command); XX move (ypos, xpos); refresh (); sleep (2); XX } XX XX addstr (" done"); XX refresh (); sleep (1); XX XX if (num_found <= 0) { XX mvaddstr (5, 0, "No spelling errors"); XX move (0, 0); refresh (); sleep (1); XX } XX return (ret_val); XX} SHAR_EOF if test 1884 -ne "`wc -c spell.c`" then echo shar: error transmitting spell.c '(should have been 1884 characters)' fi echo shar: extracting user_input.c '(1921 characters)' sed 's/^XX//' << \SHAR_EOF > user_input.c XX# include "sp.h" XX XX/* XX** user_input -- user interface for correcting mis-spelled words XX*/ XXuser_input () { XX char string[WORD_LENGTH + 20]; XX boolean done; XX register int loop; XX XX for (loop = 0; loop < num_found; loop++) { XX page_clear (loop + 1, False); XX sprintf (string, "Word ``%s'' is not in the dictionary", XX orig[loop]); XX mvaddstr (3, 0, string); refresh (); XX XX done = False; XX do { XX sprintf (string, "(%s) [ilwac^#+-?] ", orig[loop]); XX mvaddstr (5, 0, string); refresh (); XX XX switch (getch ()) { XX case 'I': XX case 'i': XX case ' ': XX case '\n': XX case '\r': XX addstr ("Ignore"); refresh (); XX done = True; ignore (loop); XX break; XX case 'L': XX case 'l': XX addstr ("Lookup"); refresh (); XX lookup (loop); XX break; XX case 'W': XX case 'w': XX addstr ("Where"); refresh (); XX where (loop); XX break; XX case 'A': XX case 'a': XX addstr ("Add"); refresh (); XX done = True; add (loop); XX break; XX case 'C': XX case 'c': XX addstr ("Correct"); refresh (); XX done = True; word_correct (loop); XX break; XX case '^': XX addstr ("Previous Document"); XX refresh (); XX if (ask_save (loop) == 1) XX return (-1); XX else XX return (-2); XX case '#': XX addstr ("Next Document"); XX refresh (); XX if (ask_save (loop) == 1) XX return (1); XX else XX return (2); XX case '+': XX addstr ("Next Word"); XX refresh (); XX done = True; XX if (new[loop] == NULL) XX ignore (loop); XX break; XX case '-': XX addstr ("Previous Word"); XX refresh (); XX done = True; XX if (loop > 0) loop -=2; XX else --loop; XX break; XX case 'H': XX case 'h': XX case '?': XX addstr ("Help!"); refresh (); XX help (loop); XX break; XX case CTRL_L: XX case CTRL_R: XX page_clear (loop + 1, True); XX default: XX page_clear (loop + 1, False); XX break; XX } XX } while (!done); XX } XX return (ask_action ()); XX} SHAR_EOF if test 1921 -ne "`wc -c user_input.c`" then echo shar: error transmitting user_input.c '(should have been 1921 characters)' fi echo shar: extracting MANIFEST '(610 characters)' sed 's/^XX//' << \SHAR_EOF > MANIFEST XXFILE WHAT XX-------------------------- XXMANIFEST This file -- list of files in package XXMakefile For making executable XXREADME Read this first for installation and copyright information XXdoc_correct.c Source for document correction XXlocal_add.c Source for adding to personal dictionary XXparse.c Command line parser (calls getopt) XXsp.1 Manual page XXsp.c Main program XXsp.h Include file (may need editing) XXspell.c Runs spell(1) and fgrep(1) to get initial mis-spelling list XXtools.c General tools used througout program XXuser_input.c Get user input for corrections XXuser_tools.c Process option selected in user_input SHAR_EOF if test 610 -ne "`wc -c MANIFEST`" then echo shar: error transmitting MANIFEST '(should have been 610 characters)' fi echo shar: extracting tools.c '(3116 characters)' sed 's/^XX//' << \SHAR_EOF > tools.c XX# include "sp.h" XX XX XX/* XX** ask_more XX** Prompt the user to continue. XX*/ XXask_more () { XX standout (); XX mvaddstr (23, 29, "Hit any key to continue"); XX standend (); XX refresh (); getch (); XX} XX XX XX/* XX** check_dict XX** Check for existence/read permission on dictionary. XX*/ XXcheck_dict () { XX if ( access (dict, 4) == 0 ) /* Read permission */ XX return (1); XX else XX if ( access (dict, 0) != 0 ) /* Existence check */ XX return (0); XX else XX return (-1); XX} XX XX XX/* XX** clean_lists XX** Clean up the three lists used in the program. XX*/ XXclean_lists () { XX register int i; XX XX for (i = 0; i < MAX_WORDS; i++) { XX if (orig[i] != NULL) { XX free (orig[i]); orig[i] = NULL; XX } XX if (new[i] != NULL) { XX free (new[i]); new[i] = NULL; XX } XX if (correct[i] != NULL) { XX free (correct[i]); correct[i] = NULL; XX } XX } XX} XX XX XX/* XX** curse_die XX** Die with an explanation when inside of curses XX*/ XXcurse_die (string) XXchar *string; XX{ XX extern int errno; XX extern char *sys_errlist[]; XX char line[256]; XX XX sprintf (line, "Fatal Error, %s:%s", string, sys_errlist[errno]); XX message (True, line); XX leave (); XX} XX XX XX/* XX** fname XX** Print out the page header (file name, etc.) XX*/ XXfname () { XX erase (); XX mvaddstr (0, (65 - strlen (doc)) / 2, /* (80-overhead-len) / 2 */ XX "[ --- "); XX standout (); XX addch (' '); addstr (doc); addch (' '); XX standend (); XX addstr (" --- ]"); XX} XX XX XX/* XX** leave XX** Clean up curses and exit. XX*/ XXvoid leave () { XX unlink (tmp_file); XX clear (); move (23, 0); refresh (); XX endwin (); XX exit (0); XX} XX XX XX/* XX** message XX** Write message on the screen XX*/ XXmessage (error, line) XXboolean error; XXchar *line; XX{ XX page_clear (0, False); XX XX if (error) { XX addch ('\07'); XX mvaddstr (3, (78 - strlen (line)) / 2, line); XX move (0,0); XX refresh (); sleep (2); XX } XX else { XX mvaddstr (3, (78 - strlen (line)) / 2, line); XX refresh (); sleep (1); XX } XX} XX XX XX/* XX** page_clear XX** Clear part of the screen and display the number XX** of the current word XX*/ XXpage_clear (word_num, cls) XXint word_num; XXboolean cls; XX{ XX char str[20]; XX XX if (cls) XX clear (); XX fname (); XX if (word_num != 0) { XX sprintf (str, "Word #%d of %d", word_num, num_found); XX mvaddstr (23, 79 - strlen (str), str); XX mvaddstr (23, 0, VERSION1); XX } XX move (3, 0); XX refresh (); XX} XX XX XX/* XX** safe_copy XX** A pre-malloced copy from one string to another XX*/ XXsafe_copy (string1, string2) XXchar **string1, XX *string2; XX{ XX if (*string1 == NULL) XX *string1 = sfalloc ((unsigned) strlen (string2) + 1); XX strcpy (*string1, string2); XX} XX XX XX/* XX** save XX** Save changes made to document XX*/ XXsave (spell_val) XXint spell_val; XX{ XX if (num_correct > 0) XX local_add (); XX XX if (num_found == (num_correct + num_ignored)) XX message (False, "No corrections made"); XX else XX if (spell_val == 0) doc_correct (); XX} XX XX XX/* XX** sfalloc XX** A safe malloc () XX*/ XXchar *sfalloc (num_bytes) XXunsigned num_bytes; XX{ XX char *calloc (), *hold; XX XX if (num_bytes == 0) return ((char *) NULL); XX XX if ( (hold = calloc (1, num_bytes)) == NULL) XX curse_die ("calloc"); XX XX return (hold); XX} XX XX XX/* XX** usage XX** Print out program usage statement and exit. XX*/ XXusage (name) XXchar *name; XX{ XX fprintf (stderr, "Usage: %s [ -d dictionary ] file [ file2 ... ]\n", XX name); XX exit (1); XX} SHAR_EOF if test 3116 -ne "`wc -c tools.c`" then echo shar: error transmitting tools.c '(should have been 3116 characters)' fi echo shar: extracting sp.h '(1329 characters)' sed 's/^XX//' << \SHAR_EOF > sp.h XX/* XX** Configuration options for sp XX*/ XX XX# include <curses.h> /* includes <stdio.h> */ XX XX# define True 1 XX# define False 0 XX XX# define VERSION1 "Sp Version 3.4" XX# define VERSION2 "Copyright (C) 1988" XX# define VERSION3 "Andrew Large" XX XX/* XX** Lookup dictionary -- use /usr/dict/web2 if you have it XX*/ XX# define L_DICT "/usr/dict/words" XX XX/* XX** Location of common programs XX*/ XX# define EX "/usr/ucb/ex" XX# define FGREP "/usr/bin/fgrep" XX# define GREP "/bin/grep" XX# define LOOK "/usr/bin/look" XX# define MORE "/usr/ucb/more" XX# define SORT "/usr/bin/sort" XX# define SPELL "/usr/bin/spell" XX XX/* XX** Constant sizes XX*/ XX# define MAX_WORDS 512 /* Max words corrected on one pass */ XX# define WORD_LENGTH 256 /* Max length of a word */ XX# define FILE_NAME_LEN 256 /* Max length of a file name */ XX XX# define CTRL_R 022 XX# define CTRL_L 014 XX XXtypedef unsigned char boolean; XX XXextern char *tmp_file, XX dict[FILE_NAME_LEN], /* Name of personal dictionary */ XX doc[FILE_NAME_LEN], /* Name of document you are checking */ XX *orig[MAX_WORDS], /* Original list of mis-spelled words */ XX *new[MAX_WORDS], /* New list (with corrections, etc) */ XX *correct[MAX_WORDS]; /* Words to be added to personal dict */ XX XXextern boolean local; /* Whether we have a personal dict */ XX XXextern int num_found, num_correct, num_ignored; XX XXextern void leave (); XXextern char *sfalloc (); SHAR_EOF if test 1329 -ne "`wc -c sp.h`" then echo shar: error transmitting sp.h '(should have been 1329 characters)' fi echo shar: extracting user_tools.c '(3572 characters)' sed 's/^XX//' << \SHAR_EOF > user_tools.c XX# include "sp.h" XX XX XX/* XX** add XX** Add an entry into list of words to be added to personal dict XX*/ XXadd (word_num) XXint word_num; XX{ XX safe_copy (& (correct[num_correct++]), orig[word_num]); XX safe_copy (& (new[word_num]), orig[word_num]); XX} XX XX XX/* XX** ask_action XX** Ask the user what to do after processing words XX*/ XXask_action () { XX char done; XX XX done = False; XX while (!done) { XX page_clear (0, False); XX mvaddstr (3, 0, "Action? [#^?] "); XX refresh (); XX XX switch (getch ()) { XX case ' ': case '\n': case '\r': XX case '#': XX done = True; XX addstr ("Next Document"); refresh (); XX if (ask_save (num_found) == 1) return (0); XX else return (2); XX case '^': XX done = True; XX addstr ("Previous Document"); refresh (); XX if (ask_save (num_found) == 1) return (-1); XX else return (-2); XX case '?': XX addstr ("Help!"); refresh (); XX mvaddstr (5, 10, "# --- Go to next document (or exit)"); XX mvaddstr (6, 10, "^ --- Go to previous document (or re-spell this one)"); XX mvaddstr (7, 10, "? --- This help message"); XX ask_more (); XX default: XX break; XX } XX } XX return (0); XX} XX XX XX/* XX** ask_save XX** Ask user if he/she wants to save these changes XX*/ XXask_save (word_num) XXint word_num; XX{ XX char ch; XX XX if (word_num == num_ignored) return (0); XX mvaddstr (7, 0, "Do you wish to save your changes? [y] "); XX refresh (); XX if ( (ch = getch ()) == 'n' || ch == 'N' ) return (0); XX return (1); XX} XX XX XX/* XX** correct XX** Get correct spelling for a word XX*/ XXword_correct (word_num) XXint word_num; XX{ XX mvaddstr (7, 0, "****** Proper spelling: "); XX XX nocrmode (); echo (); refresh (); XX XX if (new[word_num] == NULL) XX new[word_num] = sfalloc ((unsigned) WORD_LENGTH + 1); XX gets (new[word_num]); XX XX crmode (); noecho (); XX ask_more (); page_clear (word_num + 1, True); XX} XX XX XX/* XX** help XX** Give user some help with commands XX*/ XXhelp (word_num) XXint word_num; XX{ XX mvaddstr ( 7, 10, " I --- Ignore all occurrences of word"); XX mvaddstr ( 8, 10, " L --- Lookup a sub-string in the dictionary"); XX mvaddstr ( 9, 10, " W --- show Where word occurs in the document"); XX mvaddstr (10, 10, " A --- Add word to your personal dictionary"); XX mvaddstr (11, 10, " C --- Correct all occurrences of the word"); XX mvaddstr (12, 10, " ^ --- go to previous document (or re-spell this one)"); XX mvaddstr (13, 10, " # --- go to next document (or exit)"); XX mvaddstr (14, 10, " + --- go to next word"); XX mvaddstr (15, 10, " - --- go to previous word"); XX mvaddstr (16, 10, " ?, H --- this help message"); XX mvaddstr (17, 10, "^R, ^L --- redraw the screen"); XX ask_more (); XX page_clear (word_num + 1, False); XX} XX XX XX/* XX** ignore XX** Ignore the word (i.e. don't substitute for it) XX*/ XXignore (word_num) XXint word_num; XX{ XX safe_copy (& (new[word_num]), orig[word_num]); XX num_ignored++; XX} XX XX XX/* XX** lookup XX** Look up string in the dictionary XX*/ XXlookup (word_num) XXint word_num; XX{ XX char hold_str[WORD_LENGTH + 1], XX command[BUFSIZ]; XX XX mvaddstr (7, 0, "****** Lookup string: "); XX refresh (); XX XX echo (); nocrmode (); gets (hold_str); XX move (8, 0); clrtobot (); move (8, 0); refresh (); XX XX sprintf (command, "%s -df %s %s | %s", LOOK, hold_str, L_DICT, MORE); XX system (command); XX XX crmode (); noecho (); ask_more (); XX page_clear (word_num + 1, True); XX} XX XX/* XX** where XX** Show where a word occurs in the document XX*/ XXwhere (word_num) XXint word_num; XX{ XX char command[BUFSIZ]; XX XX move (7, 0); clrtobot (); move (7, 0); echo (); nocrmode (); refresh (); XX sprintf (command, "%s -w %s %s | %s", GREP, orig[word_num], doc, MORE); XX system (command); XX XX crmode (); noecho (); ask_more (); XX page_clear (word_num + 1, True); XX} SHAR_EOF if test 3572 -ne "`wc -c user_tools.c`" then echo shar: error transmitting user_tools.c '(should have been 3572 characters)' fi echo shar: extracting doc_correct.c '(677 characters)' sed 's/^XX//' << \SHAR_EOF > doc_correct.c XX# include "sp.h" XX XX/* XX** doc_correct XX** Correct the document, based upon the difference between the XX** original list and the new list of words. Uses EX to make the XX** corrections. XX*/ XXdoc_correct () { XX register int loop; XX FILE *fopen (), *popen (), *ex_ptr; XX char command[256]; XX XX page_clear (0, False); XX mvaddstr (3, 0, "Making changes ..."); refresh (); XX XX sprintf (command, "%s - %s", EX, doc); XX ex_ptr = popen (command, "w"); XX XX for (loop = 0; loop < num_found; loop++) XX if (strcmp (orig[loop], new[loop]) != 0) XX fprintf (ex_ptr, "1,$s/\\<%s\\>/%s/g\n", orig[loop], XX new[loop]); XX XX fprintf (ex_ptr, "w\nq\n"); fclose (ex_ptr); XX XX addstr (" done"); refresh (); sleep (1); XX} SHAR_EOF if test 677 -ne "`wc -c doc_correct.c`" then echo shar: error transmitting doc_correct.c '(should have been 677 characters)' fi echo shar: done with directory sp cd .. # End of shell archive exit 0