home *** CD-ROM | disk | FTP | other *** search
- Path: wucfua!wucs1!uunet!wyse!vsi1!ames!mailrus!cwjcc!hal!ncoast!allbery
- From: predict%charon.unm.edu@ariel.unm.edu (Andrew R. Large)
- Newsgroups: comp.sources.misc
- Subject: v05i051: sp version 4.0
- Message-ID: <18617.8811140812@charon.unm.edu>
- Date: 15 Nov 88 00:36:07 GMT
- Sender: allbery@ncoast.UUCP
- Reply-To: predict%charon.unm.edu@ariel.unm.edu (Andrew R. Large)
- Lines: 1448
- Approved: allbery@ncoast.UUCP
-
- Posting-number: Volume 5, Issue 51
- Submitted-by: "Andrew R. Large" <predict%charon.unm.edu@ariel.unm.edu>
- Archive-name: sp4
-
- This is the new version of my visual spelling checker.
-
- I've incorporated a few bug fixes (including the pclose one) and a warning
- about one I couldn't take care of (spell and ex have slightly different
- ideas of what makes a word).
-
- I found out that SYSV didn't have a -w flag on their grep. This brought
- the usefulness of the `where' function down, so ... I wrote an in-line search
- routine that carries with it a context window, so you can see the lines before
- and after the word. You can change the default number of lines in the context
- window with a new command line -w option (see the man page). Enjoy!
-
- [Of course, you could always use "context" (plug plug ;-) ++bsa]
-
- -=*=-=*=-=*=-=*=-=*=-=*=-=*=-=*=-=*=-=*=-=*=-=*=-=*=-=*=-=*=-=*=-=*=-=*=-=*=-
- * 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. *
- -=*=-=*=-=*=-=*=-=*=-=*=-=*=-=*=-=*=-=*=-=*=-=*=-=*=-=*=-=*=-=*=-=*=-=*=-=*=-
-
- --------------------------------- CUT HERE -----------------------------------
- #!/bin/sh
- # shar: Shell Archiver
- # Run the following text with /bin/sh to create:
- # sp
- # This archive created: Mon Nov 14 01:00:49 1988
- # By: Andrew R. Large (University of New Mexico, Albuquerque)
- echo shar: creating directory sp
- mkdir sp
- cd sp
- echo shar: extracting Makefile '(607 characters)'
- sed 's/^XX//' << \SHAR_EOF > Makefile
- XX#! /bin/sh
- XX#
- XX# Makefile for sp
- XX# Written by Andrew Large
- XX#
- XX# Edit BIN, MAN, CC and CFLAGS
- 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 add_local.o doc_correct.o externs.o parse.o spell.o tools.o\
- XX user_input.o user_tools.o where.o
- XXLIBS = -lcurses -ltermlib
- XXCC = cc
- XX
- XX#
- XX# If you are a BSD system, then BSD
- XX# CFLAGS = -O
- XXCFLAGS = -O -DBSD
- 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 607 -ne "`wc -c Makefile`"
- then
- echo shar: error transmitting Makefile '(should have been 607 characters)'
- fi
- echo shar: extracting README '(1682 characters)'
- sed 's/^XX//' << \SHAR_EOF > README
- XX** SP **
- XX
- XXSp is a visual spelling program that is based upon existing UN*X utilites.
- XXIt may be run on one or more files, and for each file, it presents a
- XXword-by-word list of the words received from spell(1). You may then take
- XXany 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
- XX 1) Edit `sp.h' to reflect your current situation (mainly locations
- XX of system programs).
- XX
- XX 2) Edit Makefile and change `BIN', `MAN', `CC', and `CFLAGS' to
- XX their proper values.
- XX
- XX 3) Type `make'.
- XX
- XX 4) If everything tests out 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 1682 -ne "`wc -c README`"
- then
- echo shar: error transmitting README '(should have been 1682 characters)'
- fi
- echo shar: extracting where.c '(3717 characters)'
- sed 's/^XX//' << \SHAR_EOF > where.c
- XX# include "sp.h"
- XX# include <ctype.h>
- XX# define LEAVE {\
- XX fclose (fp); free2 (window, window_size);\
- XX page_clear (word_num+1, True); return;\
- XX}
- XX# define letter(ch) (isalpha (ch) || ch == '.')
- XX
- XX/*
- XX** where
- XX** Show where a word occurs in the document with surrounding context.
- XX*/
- XXwhere (word_num)
- XXint word_num;
- XX{
- XX extern char *bad_words[], *spell_doc;
- XX extern char sys_errlist[];
- XX extern int errno, window_size;
- XX FILE *fp;
- XX char *window[MAX_WINDOW], line[BUFSIZ], *word;
- XX boolean done = False;
- XX int mid;
- XX register int i, nlines;
- XX
- XX move (7,0); clrtobot (); move (7,0); refresh ();
- XX if ((fp = fopen (spell_doc, "r")) == NULL) {
- XX sprintf (line, "Can't open %s for read: %s", spell_doc,
- XX sys_errlist[errno]);
- XX message (True, line);
- XX ask_more (); page_clear (word_num + 1, True); return;
- XX }
- XX
- XX for (i=0; i < window_size; window[i++] = NULL);
- XX word = bad_words[word_num];
- XX nlines = ctx_open (fp, window, window_size);
- XX mid = nlines / 2;
- XX
- XX for (i=0; i < mid; i++)
- XX if (ctx_display (window, word, nlines, i)) LEAVE
- XX
- XX while (!done) {
- XX if (ctx_display (window, word, nlines, mid)) LEAVE
- XX done = ctx_step (fp, window, window_size);
- XX }
- XX
- XX for (i=mid+1; i < nlines; i++)
- XX if (ctx_display (window, word, nlines, i)) LEAVE
- XX LEAVE
- XX}
- XX
- XX
- XX/*
- XX** ctx_display
- XX** If the interest line has the word in it, then display the identified
- XX** window with the word in reverse video. Return True if the user doesn't
- XX** want to see any more occurances.
- XX*/
- XXctx_display (window, word, nlines, chkline)
- XXchar *window[], *word;
- XXint nlines, chkline;
- XX{
- XX int beg, end;
- XX register int line, ch;
- XX char c;
- XX
- XX word_in (window[chkline], word, &beg, &end);
- XX if (beg != -1) {
- XX for (line = 0; line < chkline; line++)
- XX mvaddstr (line+7, 0, window[line]);
- XX
- XX for (ch = 0; ch < beg; ch++)
- XX mvaddch (chkline+7, ch, window[chkline][ch]);
- XX standout ();
- XX for (ch = beg; ch <= end; ch++)
- XX mvaddch (chkline+7, ch, window[chkline][ch]);
- XX standend ();
- XX for (ch = end+1; window[chkline][ch]; ch++)
- XX mvaddch (chkline+7, ch, window[chkline][ch]);
- XX
- XX for (line = chkline + 1; line < nlines; line++)
- XX mvaddstr (line+7, 0, window[line]);
- XX
- XX mvaddstr (23,0,
- XX "Hit any key for next occurrence, <Esc> to return: ");
- XX refresh ();
- XX
- XX if (getch() != ESC)
- XX return False;
- XX else
- XX return True;
- XX }
- XX return False;
- XX}
- XX
- XX
- XX/*
- XX** ctx_open
- XX** Open a context window of n lines. Return the number of
- XX** lines read in.
- XX*/
- XXctx_open (fp, window, n)
- XXFILE *fp;
- XXchar *window[];
- XXint n;
- XX{
- XX register int i;
- XX char line[BUFSIZ+1];
- XX
- XX for (i=0; i < n; i++) {
- XX if (fgets (line, BUFSIZ+1, fp) == NULL) return i;
- XX safe_copy (&window[i], line);
- XX }
- XX return n;
- XX}
- XX
- XX
- XX/*
- XX** ctx_step
- XX** Move down the context window by one line
- XX*/
- XXctx_step (fp, window, n)
- XXFILE *fp;
- XXchar *window[];
- XXint n;
- XX{
- XX char line[BUFSIZ+1];
- XX register int i;
- XX
- XX if (fgets (line, BUFSIZ+1, fp) == NULL) return True;
- XX
- XX free (window[0]);
- XX for (i=0; i < (n-1); i++)
- XX window[i] = window[i+1];
- XX
- XX window[n-1] = NULL;
- XX safe_copy (&window[n-1], line);
- XX
- XX return False;
- XX}
- XX
- XX
- XX/*
- XX** word_in
- XX** If the given word occurs in the string, return the starting
- XX** and ending indices. May show a few occurances _not_ found
- XX** by spell.
- XX*/
- XXword_in (line, word, beg, end)
- XXchar *line, *word;
- XXint *beg, *end;
- XX{
- XX register int i, len;
- XX
- XX *beg = *end = -1;
- XX len = strlen (word);
- XX
- XX if (strncmp (line, word, len) == 0 && !letter (line[len])) {
- XX *beg = 0; *end = len - 1;
- XX return;
- XX }
- XX
- XX /*
- XX ** 1. Skip past current word
- XX ** 2. Skip to beginning of next word
- XX ** 3. If this is not the correct word, go back to 1.
- XX */
- XX i=0;
- XX while (line[i]) {
- XX while (letter (line[i])) i++;
- XX while (line[i] && !letter (line[i])) i++;
- XX if (line[i] && strncmp (&line[i], word, len) == 0 &&
- XX !letter (line[i+len])) {
- XX *beg = i; *end = i + len - 1;
- XX return;
- XX }
- XX }
- XX}
- SHAR_EOF
- if test 3717 -ne "`wc -c where.c`"
- then
- echo shar: error transmitting where.c '(should have been 3717 characters)'
- fi
- echo shar: extracting parse.c '(1463 characters)'
- sed 's/^XX//' << \SHAR_EOF > parse.c
- XX# include "sp.h"
- XX
- XX/*
- XX** parse
- XX** Parse input for -d and -w options 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, *local_dict;
- XX extern int optind, window_size;
- XX extern boolean local;
- XX char *getenv (), getopt ();
- XX int option;
- XX
- XX if (argc < 2) usage (argv[0]);
- XX
- XX local = False; window_size = 5;
- XX while ((option = getopt (argc, argv, "d:w:")) != EOF)
- XX switch (option) {
- XX case 'd':
- XX local_dict =
- XX sfalloc ((unsigned) strlen (optarg) + 1);
- XX strcpy (local_dict, optarg);
- XX local = True;
- XX break;
- XX case 'w':
- XX if ((window_size = atoi (optarg)) < 1)
- XX window_size = 1;
- XX else if (window_size > MAX_WINDOW)
- XX window_size = MAX_WINDOW;
- 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 local_dict = getenv ("DICT");
- XX else
- XX local_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 local_dict);
- XX printf ("\nI may try to create it later ...");
- XX fflush (stdout);
- XX sleep (2);
- XX break;
- XX case -1:
- XX local = False;
- XX printf ("\nYour local dictionary %s is not readable.",
- XX local_dict);
- XX printf ("\nI may try to write to it later ...");
- XX fflush (stdout);
- XX sleep (2);
- XX break;
- XX }
- XX *place = optind;
- XX}
- SHAR_EOF
- if test 1463 -ne "`wc -c parse.c`"
- then
- echo shar: error transmitting parse.c '(should have been 1463 characters)'
- fi
- echo shar: extracting sp.1 '(4358 characters)'
- sed 's/^XX//' << \SHAR_EOF > sp.1
- XX.\"
- XX.\" Copyright (C) 1988 Andrew Large
- XX.\"
- XX.de Cm
- XX\fI\\$1\fP(\fI\\$2\fP)\\$3
- XX..
- XX.TH SP 1 "Version 4.0"
- XX.DA 13 November 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[
- XX.B \-w
- XX.B window_size
- XX]
- XX.B file
- XX[
- XX.B file2
- XX.B ...
- XX]
- XX.SH DESCRIPTION
- XX.PP
- XX.IR sp
- XXcalls
- XX.Cm spell 1
- XXto check the spelling of your document(s).
- XXIt then presents you with a list of the mis-spelled words and allows
- XXyou to ignore the word, correct it, or add it to your personal dictionary.
- XX.PP
- XXYour personal dictionary is searched for words
- XX.I after
- XXthe system dictionary. You may specify a personal dictionary in two
- XXdifferent ways:
- XX.RS
- XX.IP 1. 5n
- XXOn the command line (with the \-d option).
- XX.IP 2. 5n
- XXSet the environment variable DICT to the name of your personal dictionary.
- XX.RE
- XX.PP
- XXIf you don't explicitly set your personal dictionary, then the file
- XX``spelldict'' in your current directory will be used.
- 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
- XXused when a word is spelled correctly, but you don't want it added
- XXto 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
- XX.Cm look 1
- XXwill use on the system dictionary.
- XX.IP W
- XXShow where the word occurs in the document. This shows the line the word
- XXoccurred on plus some additional lines to show the context. The size of
- XXthe context window is set to 5 by default (two lines above, two lines below).
- XXYou can change the context window size with the \-w option. The window
- XXsize may be set to anything from 1 to 15.
- 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
- XX.Cm spell 1
- XXon your current 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 with
- XX.Cm 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.Cm ex 1 .
- XX.PP
- XXThe spell 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$DICT, spelldict \- default personal dictionaries
- XX.SH BUGS
- XX.PP
- XX.Cm spell 1
- XXand
- XX.Cm ex 1
- XXhave different ideas of what constitutes a word. Most notably,
- XX.Cm spell 1
- XXconsiders ``_'' to be a word separation character. For those cases,
- XXcorrect the word by hand. Trying to correct it via
- XX.B sp
- XXwill cause
- XX.Cm ex 1
- XXto fail, and all your corrections will be lost.
- XX.SH "SEE ALSO"
- XX.Cm ex 1 ,
- XX.Cm grep 1 ,
- XX.Cm look 1 ,
- XXand
- XX.Cm spell 1 .
- SHAR_EOF
- if test 4358 -ne "`wc -c sp.1`"
- then
- echo shar: error transmitting sp.1 '(should have been 4358 characters)'
- fi
- echo shar: extracting sp.c '(1416 characters)'
- sed 's/^XX//' << \SHAR_EOF > sp.c
- XX# include "sp.h"
- XX
- XX/*
- XX** sp main program
- XX** 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** October 1988 (Current Version)
- XX*/
- XX
- XXmain (argc, argv)
- XXint argc;
- XXchar *argv[];
- XX{
- XX extern int exit_val;
- XX extern char *spell_doc;
- XX int spell_val, start_pos;
- XX register int pos;
- XX
- XX /*
- XX ** Parse input arguments and initialize
- XX ** curses and signals
- XX */
- XX parse (argc, argv, &start_pos);
- XX init ();
- XX
- XX /*
- XX ** Main loop. Keep going until user leaves the last document.
- XX */
- XX pos = start_pos;
- XX while (pos < argc) {
- XX reset_data (); /* Clean lists and reset globals */
- XX spell_doc = argv[pos];
- XX
- XX if ( (spell_val = spell ()) >= 0 ) {
- XX switch (user_input ()) {
- XX case -1: /* previous doc, save */
- XX rest_ignore ();
- XX save (spell_val);
- XX case -2: /* previous doc, no save */
- XX if (pos > start_pos) --pos;
- XX break;
- XX case 0: /* normal exit with save */
- XX case 1: /* early exit with save */
- XX rest_ignore ();
- XX save (spell_val);
- XX case 2: /* early exit, no save */
- XX default:
- XX ++pos;
- XX break;
- XX }
- XX }
- XX else {
- XX ++pos;
- XX exit_val = Error;
- XX }
- XX }
- XX leave ();
- XX}
- SHAR_EOF
- if test 1416 -ne "`wc -c sp.c`"
- then
- echo shar: error transmitting sp.c '(should have been 1416 characters)'
- fi
- echo shar: extracting spell.c '(2033 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 extern char *bad_words[], *spell_doc, *local_dict;
- XX extern int num_bad;
- XX extern boolean local;
- XX FILE *popen (), *spell_out;
- XX char command[256];
- XX int ypos, xpos, ret_val;
- XX register int i;
- XX
- XX clear (); fname ();
- XX
- XX if (access (spell_doc, 0) != 0) { /* Check for existence */
- XX sprintf (command, "Cannot access file %s!", spell_doc);
- XX message (True, command);
- XX return (-1);
- XX }
- XX
- XX ret_val = 0;
- XX if (access (spell_doc, 6) != 0) { /* Read and write */
- XX if (access (spell_doc, 4) != 0) { /* Read */
- XX sprintf (command, "You are unable to read %s!",
- XX spell_doc);
- XX message (True, command);
- XX return (-1);
- XX }
- XX message (True, "You are unable to write to this file!");
- XX mvaddstr (5,22, "I will check spelling, but you will");
- XX mvaddstr (6,22, "not be able to save any corrections.");
- XX ret_val = 1;
- XX move (0,0); refresh (); sleep (3); fname ();
- XX }
- XX
- XX mvaddstr (3,0, "Checking spelling ..."); refresh ();
- XX
- XX /*
- XX ** Get the list of mis-spelled words
- XX */
- XX if (local)
- XX sprintf (command, "%s %s | %s -v -f %s", SPELL, spell_doc,
- XX FGREP, local_dict);
- XX else
- XX sprintf (command, "%s %s", SPELL, spell_doc);
- XX
- XX spell_out = popen (command, "r");
- XX
- XX for (i = 0; i < MAX_WORDS; i++) {
- XX bad_words[i] = sfalloc ((unsigned) MAX_WORD_LEN);
- XX if (fgets (bad_words[i], MAX_WORD_LEN, spell_out) == NULL)
- XX break;
- XX else
- XX bad_words[i][strlen (bad_words[i]) - 1] = '\0';
- XX }
- XX fflush (spell_out); pclose (spell_out);
- XX
- XX if ((num_bad = i) >= 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 strcpy (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"); refresh ();
- XX
- XX if (num_bad <= 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 2033 -ne "`wc -c spell.c`"
- then
- echo shar: error transmitting spell.c '(should have been 2033 characters)'
- fi
- echo shar: extracting user_input.c '(2012 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 extern char *bad_words[], *good_words[];
- XX extern int num_bad;
- XX char string[MAX_WORD_LEN + 64];
- XX boolean done;
- XX register int loop;
- XX
- XX for (loop = 0; loop < num_bad; loop++) {
- XX page_clear (loop + 1, False);
- XX sprintf (string, "Word ``%s'' is not in the dictionary",
- XX bad_words[loop]);
- XX mvaddstr (3, 0, string); refresh ();
- XX
- XX done = False;
- XX do {
- XX sprintf (string, "(%s) [ilwac^#+-?] ", bad_words[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 (good_words[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 break;
- XX default:
- XX page_clear (loop + 1, False);
- XX break;
- XX }
- XX } while (!done);
- XX }
- XX return (ask_action ());
- XX}
- SHAR_EOF
- if test 2012 -ne "`wc -c user_input.c`"
- then
- echo shar: error transmitting user_input.c '(should have been 2012 characters)'
- fi
- echo shar: extracting MANIFEST '(785 characters)'
- sed 's/^XX//' << \SHAR_EOF > MANIFEST
- XXFile Explanation
- XX------------------------------------------------------------------------------
- XXMANIFEST This file -- list of files in package
- XXMakefile For compiling ``sp''.
- XXREADME Read this first for installation and copyright information
- XXadd_local.c Routine for adding words to personal dictionary
- XXdoc_correct.c Routine for correcting the document
- XXexterns.c Declarations of global data structures
- XXparse.c Command line parser (uses 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
- XXwhere.c For showing context-surrounded word occurences
- SHAR_EOF
- if test 785 -ne "`wc -c MANIFEST`"
- then
- echo shar: error transmitting MANIFEST '(should have been 785 characters)'
- fi
- echo shar: extracting tools.c '(4427 characters)'
- sed 's/^XX//' << \SHAR_EOF > tools.c
- XX# include "sp.h"
- XX# include <signal.h>
- XX
- XX
- XX/*
- XX** ask_more
- XX** Prompt the user to continue.
- XX*/
- XXask_more () {
- XX move (23,0); clrtoeol ();
- 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 extern char *local_dict;
- XX
- XX if ( access (local_dict, 4) == 0 ) /* Read permission */
- XX return (1);
- XX else
- XX if ( access (local_dict, 0) != 0 ) /* Existence check */
- XX return (0);
- XX else
- XX return (-1);
- 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, exit_val;
- 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 exit_val = Error; leave ();
- XX}
- XX
- XX
- XX/*
- XX** fname
- XX** Print out the page header (file name, etc.)
- XX*/
- XXfname () {
- XX extern char *spell_doc;
- XX erase ();
- XX mvaddstr (0, (65 - strlen (spell_doc)) / 2, /* (80-overhead-len) / 2 */
- XX "[ --- ");
- XX standout ();
- XX addch (' '); addstr (spell_doc); addch (' ');
- XX standend ();
- XX addstr (" --- ]");
- XX}
- XX
- XX
- XX/*
- XX** free2
- XX** Free a list of strings
- XX*/
- XXfree2 (args, max)
- XXregister char **args;
- XXregister int max;
- XX{
- XX while (*args && max-- > 0) free (*args++);
- XX}
- XX
- XX
- XX/*
- XX** init
- XX** Initialize the screen and take care of nasty signals
- XX*/
- XXinit () {
- XX extern char *bad_words[], *good_words[], *add_words[];
- XX register int i;
- XX
- XX for (i=0; i < MAX_WORDS; i++) {
- XX bad_words[i] = good_words[i] = add_words[i] = NULL;
- XX }
- XX
- XX signal (SIGINT, leave); signal (SIGQUIT, leave);
- XX
- XX initscr (); crmode (); noecho ();
- XX
- XX mvaddstr ( 9,30, VERSION1);
- XX mvaddstr (10,28, VERSION2);
- XX mvaddstr (11,31, VERSION3);
- XX
- XX move (0,0); refresh (); sleep (1);
- XX}
- XX
- XX
- XX/*
- XX** leave
- XX** Clean up curses and exit.
- XX*/
- XXvoid leave () {
- XX extern char tmp_file[];
- XX extern int exit_val;
- XX
- XX unlink (tmp_file);
- XX clear (); move (23,0); refresh (); endwin ();
- XX exit (exit_val);
- 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 (3);
- XX }
- XX else {
- XX mvaddstr (3, (78 - strlen (line)) / 2, line);
- XX refresh (); sleep (2);
- 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 extern int num_bad;
- XX char str[20];
- XX
- XX if (cls)
- XX clear ();
- XX fname ();
- XX if (word_num) {
- XX sprintf (str, "Word #%d of %d", word_num, num_bad);
- XX mvaddstr (23, 79 - strlen (str), str);
- XX mvaddstr (23, 0, VERSION1);
- XX }
- XX move (3, 0);
- XX refresh ();
- XX}
- XX
- XX
- XX/*
- XX** reset_data
- XX** Reset all global data
- XX*/
- XXreset_data () {
- XX extern char *bad_words[], *good_words[], *add_words[];
- XX extern int num_bad, num_added, num_ignored;
- XX register int i;
- XX
- XX for (i = 0; i < MAX_WORDS; i++) {
- XX if (bad_words[i] != NULL) {
- XX free (bad_words[i]); bad_words[i] = NULL;
- XX }
- XX if (good_words[i] != NULL) {
- XX free (good_words[i]); good_words[i] = NULL;
- XX }
- XX if (add_words[i] != NULL) {
- XX free (add_words[i]); add_words[i] = NULL;
- XX }
- XX }
- XX
- XX num_bad = num_added = num_ignored = 0;
- XX}
- XX
- XX
- XX/*
- XX** safe_copy
- XX** A pre-malloc'd 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 extern int num_bad, num_added, num_ignored;
- XX
- XX if (num_added)
- XX add_local ();
- XX if (num_bad == (num_added + num_ignored))
- XX message (False, "No corrections made");
- XX else
- XX if (spell_val == 0) doc_correct ();
- XX}
- XX
- XX
- XX/*
- XX** rest_ignore
- XX** When user exits before viewing all the words, set the rest
- XX** of the words to ignore.
- XX*/
- XXrest_ignore () {
- XX extern char *bad_words[], *good_words[];
- XX extern int num_bad;
- XX register int i;
- XX
- XX for (i = num_bad - 1; !good_words[i]; ignore (i--));
- 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,
- XX "Usage: %s [ -d dictionary ] [ -w window_size ] file [ file2 ... ]\n",
- XX name);
- XX exit (1);
- XX}
- SHAR_EOF
- if test 4427 -ne "`wc -c tools.c`"
- then
- echo shar: error transmitting tools.c '(should have been 4427 characters)'
- fi
- echo shar: extracting sp.h '(992 characters)'
- sed 's/^XX//' << \SHAR_EOF > sp.h
- XX/*
- XX** Configuration information for sp
- XX*/
- XX
- XX# include <curses.h>
- XX
- XX# define True 1
- XX# define False 0
- XX
- XX# define Error 1
- XX# define Okay 0
- XX
- XX# define VERSION1 "Sp Version 4.0"
- 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 LOOK_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 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 MAX_WORD_LEN 256 /* Max length of a word */
- XX# define MAX_WINDOW 15 /* Maximum window size (for where) */
- XX
- XX# define CTRL_R 022 /* Ascii value of ^R -- for redraw */
- XX# define CTRL_L 014 /* Ascii value of ^L -- for redraw */
- XX# define ESC 033 /* Ascii value of Escape */
- XX
- XX
- XXtypedef unsigned char boolean;
- XX
- XXvoid leave ();
- XXchar *sfalloc ();
- SHAR_EOF
- if test 992 -ne "`wc -c sp.h`"
- then
- echo shar: error transmitting sp.h '(should have been 992 characters)'
- fi
- echo shar: extracting user_tools.c '(3592 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 extern char *add_words[], *bad_words[], *good_words[];
- XX extern int num_added;
- XX
- XX safe_copy (& (add_words[num_added++]), bad_words[word_num]);
- XX safe_copy (& (good_words[word_num]), bad_words[word_num]);
- XX}
- XX
- XX
- XX/*
- XX** ask_action
- XX** Ask the user what to do after processing words
- XX*/
- XXask_action () {
- XX extern int num_bad;
- XX boolean 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_bad) == 1) return (0);
- XX else return (2);
- XX case '^':
- XX done = True;
- XX addstr ("Previous Document"); refresh ();
- XX if (ask_save (num_bad) == 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 extern int num_ignored;
- 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 extern char *good_words[];
- XX
- XX mvaddstr (7, 0, "****** Proper spelling: "); refresh();
- XX echo(); nocrmode(); refresh ();
- XX
- XX if (good_words[word_num] == NULL)
- XX good_words[word_num] = sfalloc ((unsigned) MAX_WORD_LEN + 1);
- XX fgets (good_words[word_num], MAX_WORD_LEN + 1, stdin);
- XX good_words[word_num][strlen (good_words[word_num]) - 1] = '\0';
- 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 extern char *good_words[], *bad_words[];
- XX extern int num_ignored;
- XX
- XX safe_copy (& (good_words[word_num]), bad_words[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[MAX_WORD_LEN + 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, LOOK_DICT,
- XX MORE);
- XX system (command);
- XX
- XX crmode (); noecho (); ask_more ();
- XX page_clear (word_num + 1, True);
- XX}
- SHAR_EOF
- if test 3592 -ne "`wc -c user_tools.c`"
- then
- echo shar: error transmitting user_tools.c '(should have been 3592 characters)'
- fi
- echo shar: extracting doc_correct.c '(846 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 and new lists of words. Uses EX to make the corrections.
- XX*/
- XXdoc_correct () {
- XX extern char *bad_words[], *good_words[], *spell_doc;
- XX extern int num_bad;
- XX FILE *popen (), *ex_ptr;
- XX char command[256];
- XX register int loop;
- XX
- XX page_clear (0, False);
- XX mvaddstr (3,0, "Making changes ..."); refresh ();
- XX
- XX sprintf (command, "%s - %s", EX, spell_doc);
- XX ex_ptr = popen (command, "w");
- XX
- XX fprintf (ex_ptr, "set nomagic\n"); /* Don't match '.' */
- XX for (loop = 0; loop < num_bad; loop++)
- XX if (strcmp (bad_words[loop], good_words[loop]) != 0) {
- XX fprintf (ex_ptr, "%%s/\\<%s\\>/%s/g\n", bad_words[loop],
- XX good_words[loop]);
- XX fflush (ex_ptr);
- XX }
- XX fprintf (ex_ptr, "w\nq\n");
- XX fflush (ex_ptr); pclose (ex_ptr);
- XX
- XX addstr (" done"); refresh ();
- XX}
- SHAR_EOF
- if test 846 -ne "`wc -c doc_correct.c`"
- then
- echo shar: error transmitting doc_correct.c '(should have been 846 characters)'
- fi
- echo shar: extracting externs.c '(774 characters)'
- sed 's/^XX//' << \SHAR_EOF > externs.c
- XX# include "sp.h"
- XX
- XX/*
- XX** Global data use throughout the program
- XX*/
- XXchar *id = "@(#)SP\t4.0\t88/11/13"; /* Identification string for what(1) */
- XX
- XXchar *bad_words[MAX_WORDS], /* Words obtained from spell(1) */
- XX *good_words[MAX_WORDS], /* Words to correct in document */
- XX *add_words[MAX_WORDS], /* Words to add to local dictionary */
- XX *local_dict, /* Local dictionary */
- XX *spell_doc, /* Document we are currently spelling */
- XX tmp_file[16]; /* Temporary file used for */
- XX
- XXint num_bad, /* Number of bad words */
- XX num_added, /* Number added to local dict */
- XX num_ignored, /* Number bad words ignored */
- XX exit_val, /* Program exit value (for leave ()) */
- XX window_size; /* Context window size (for where ()) */
- XX
- XXboolean local; /* Is the local dict available? */
- SHAR_EOF
- if test 774 -ne "`wc -c externs.c`"
- then
- echo shar: error transmitting externs.c '(should have been 774 characters)'
- fi
- echo shar: extracting add_local.c '(1293 characters)'
- sed 's/^XX//' << \SHAR_EOF > add_local.c
- XX# include "sp.h"
- XX
- XX/*
- XX** add_local
- XX** Add all words in correct list to personal dictionary
- XX** and sort the dictionary.
- XX*/
- XXadd_local () {
- XX extern char *add_words[], *local_dict, tmp_file[];
- XX extern int num_added;
- XX extern boolean local;
- XX char *mktemp (), string[256];
- XX FILE *fopen (), *tmp_ptr;
- XX register int loop;
- XX
- XX if ( access (local_dict, 0) == 0 && access (local_dict, 2) != 0 ) {
- XX sprintf (string,
- XX "Your local dictionary \"%s\" is not writable!",
- XX local_dict);
- XX message (True, string);
- XX return;
- XX }
- XX
- XX strcpy (tmp_file, "/tmp/spXXXXXX");
- XX if ((tmp_ptr = fopen (mktemp (tmp_file), "w")) == NULL) {
- XX sprintf (string, "Can't open tmp file \"%s\" for writing!",
- XX tmp_file);
- XX message (True, string);
- XX return;
- XX }
- XX
- XX for (loop = 0; loop < num_added; loop++)
- XX fprintf (tmp_ptr, "%s\n", add_words[loop]);
- XX fflush (tmp_ptr); fclose (tmp_ptr);
- XX
- XX# ifdef BSD
- XX if (vfork () == 0) {
- XX# else
- XX if (fork () == 0) {
- XX# endif
- XX if (local)
- XX execl (SORT, "sort", "-f", "-m", "-o", local_dict,
- XX local_dict, tmp_file, (char *) NULL);
- XX else
- XX execl (SORT, "sort", "-f", "-m", "-o", local_dict,
- XX tmp_file, (char *) NULL);
- XX perror (SORT);
- XX _exit (-1);
- XX }
- XX
- XX wait (0);
- XX sprintf (string, "%d %s added to %s", num_added,
- XX (num_added == 1 ? "word" : "words"), local_dict);
- XX message (False, string);
- XX}
- SHAR_EOF
- if test 1293 -ne "`wc -c add_local.c`"
- then
- echo shar: error transmitting add_local.c '(should have been 1293 characters)'
- fi
- echo shar: done with directory sp
- cd ..
- # End of shell archive
- exit 0
-