ispell repost (less dict) 02/02: enhanced, fixed
geoff at desint.UUCP
geoff at desint.UUCP
Sat Mar 14 20:04:14 AEST 1987
#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
# config.h
# good.c
# hash.c
# ispell.c
# ispell.h
# lookup.c
# term.c
# tree.c
# This archive created: Sat Mar 14 00:59:10 1987
export PATH; PATH=/bin:$PATH
echo shar: extracting "'config.h'" '(2543 characters)'
if test -f 'config.h'
then
echo shar: will not over-write existing file "'config.h'"
else
sed 's/^X //' << \SHAR_EOF > 'config.h'
X /*
X ** library directory for hash table(s) / default hash table name
X ** If you intend to use multiple dictionary files, I would suggest
X ** LIBDIR be a directory which will contain nothing else, so sensible
X ** names can be constructed for the -d option without conflict.
X */
X #define LIBDIR "/usr/local/lib"
X #define DEFHASH "ispell.hash"
X
X #ifdef SYSV
X #define index strchr
X #endif
X
X /* environment variable for user's word list */
X #define PDICTVAR "WORDLIST"
X
X /* default word list */
X #define DEFPDICT "ispell.words"
X
X /* mktemp template for temporary file - MUST contain 6 consecutive X's */
X #define TEMPNAME "/usr/tmp/spellXXXXXX"
X
X /* default dictionary file */
X #define DEFDICT "dict.191"
X
X /* define LOOK if look(1) command is available */
X #define LOOK
X
X /* path to egrep (use speeded up version if available) */
X #define EGREPCMD "/usr/local/egrep -i"
X
X /* path to wordlist for Lookup command (typically /usr/dict/{words|web2} */
X #define WORDS "/usr/dict/web2"
X
X /* buffer size to use for file names if not in sys/param.h */
X #ifndef MAXPATHLEN
X #define MAXPATHLEN 240
X #endif
X
X /* word length allowed in dictionary by buildhash */
X #define WORDLEN 30
X
X /* hash table magic number */
X #define MAGIC 1
X
X /* suppress the 8-bit character feature */
X #define NO8BIT
X
X /* Approximate number of words in the full dictionary, after munching.
X ** Err on the high side unless you are very short on memory, in which
X ** case you might want to change the tables in tree.c and also increase
X ** MAXPCT.
X **
X ** (Note: dict.191 is a bit over 15000 words. dict.191 munched with
X ** /usr/dict/words is a little over 28000).
X */
X #define BIG_DICT 29000
X
X /*
X ** Maximum hash table fullness percentage. Larger numbers trade space
X ** for time.
X **/
X #define MAXPCT 70 /* Expand table when 70% full */
X
X /*
X ** the isXXXX macros normally only check ASCII range. These are used
X ** instead for text characters, which we assume may be 8 bit. The
X ** NO8BIT ifdef shuts off significance of 8 bit characters. If you are
X ** using this, and your ctype.h already masks, you can simplify.
X */
X #ifdef NO8BIT
X #define myupper(X) isupper((X)&0x7f)
X #define mylower(X) islower((X)&0x7f)
X #define myspace(X) isspace((X)&0x7f)
X #define myalpha(X) isalpha((X)&0x7f)
X #else
X #define myupper(X) (!((X)&0x80) && isupper(X))
X #define mylower(X) (!((X)&0x80) && islower(X))
X #define myspace(X) (!((X)&0x80) && isspace(X))
X #define myalpha(X) (!((X)&0x80) && isalpha(X))
X #endif
X
X /*
X ** the NOPARITY mask is applied to user input characters from the terminal
X ** in order to mask out the parity bit.
X */
X #define NOPARITY 0x7f
SHAR_EOF
if test 2543 -ne "`wc -c < 'config.h'`"
then
echo shar: error transmitting "'config.h'" '(should have been 2543 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'good.c'" '(10274 characters)'
if test -f 'good.c'
then
echo shar: will not over-write existing file "'good.c'"
else
sed 's/^X //' << \SHAR_EOF > 'good.c'
X /* -*- Mode:Text -*- */
X
X /*
X * good.c - see if a word or its root word
X * is in the dictionary.
X *
X * Pace Willisson, 1983
X */
X
X #include <stdio.h>
X #include <ctype.h>
X #include "ispell.h"
X #include "config.h"
X
X struct dent *lookup();
X
X static int wordok;
X
X extern int cflag;
X
X good (w)
X register char *w;
X {
X char nword[100];
X register char *p, *q;
X register n;
X
X for (p = w, q = nword; *p; p++, q++) {
X if (mylower (*p))
X *q = toupper (*p);
X else
X *q = *p;
X }
X *q = 0;
X
X rootword[0] = 0;
X
X if (cflag)
X printf ("%s\n", nword);
X else if (lookup (nword, q - nword, 1) != NULL) {
X return (1);
X }
X
X /* try stripping off suffixes */
X
X n = strlen (w);
X if (n == 1)
X return (1);
X
X if (n < 4)
X return 0;
X
X wordok = 0;
X
X /* this part from 'check.mid' */
X switch (q[-1]) {
X case 'D': d_ending (nword); break; /* FOR "CREATED", "IMPLIED", "CROSSED" */
X case 'T': t_ending (nword); break; /* FOR "LATEST", "DIRTIEST", "BOLDEST" */
X case 'R': r_ending (nword); break; /* FOR "LATER", "DIRTIER", "BOLDER" */
X case 'G': g_ending (nword); break; /* FOR "CREATING", "FIXING" */
X case 'H': h_ending (nword); break; /* FOR "HUNDREDTH", "TWENTIETH" */
X case 'S': s_ending (nword); break; /* FOR ALL SORTS OF THINGS ENDING IN "S" */
X case 'N': n_ending (nword); break; /* "TIGHTEN", "CREATION", "MULIPLICATION" */
X case 'E': e_ending (nword); break; /* FOR "CREATIVE", "PREVENTIVE" */
X case 'Y': y_ending (nword); break; /* FOR "QUICKLY" */
X default:
X break;
X }
X
X if (wordok) {
X strcpy (rootword, lastdent->word);
X }
X return (wordok);
X
X }
X
X
X g_ending (w)
X char *w;
X {
X char *p;
X struct dent *dent;
X
X p = w + strlen (w) - 3; /* if the word ends in 'ing', then *p == 'i' */
X
X if (strcmp (p, "ING") != 0)
X return;
X
X *p = 'E'; /* change I to E, like in CREATING */
X *(p+1) = 0;
X
X if (strlen (w) < 2)
X return;
X
X if (cflag)
X printf ("%s/G\n", w);
X else if ((dent = lookup (w, strlen (w), 1)) != NULL
X && dent->g_flag) {
X wordok = 1;
X return;
X }
X
X
X *p = 0;
X
X if (strlen (w) < 2)
X return;
X
X if (p[-1] == 'E')
X return; /* this stops CREATEING */
X
X if (cflag)
X printf ("%s/G\n", w);
X else if ((dent = lookup (w, strlen (w), 1)) != NULL) {
X if (dent->g_flag)
X wordok = 1;
X return;
X }
X return;
X }
X
X d_ending (w)
X char *w;
X {
X char *p;
X struct dent *dent;
X
X p = w + strlen (w) - 2;
X
X if (strcmp (p, "ED") != 0)
X return;
X
X p[1] = 0; /* kill 'D' */
X
X if (cflag)
X printf ("%s/D\n", w);
X else if ((dent = lookup (w, strlen (w), 1)) != NULL) { /* eg CREATED */
X if (dent->d_flag)
X wordok = 1;
X return;
X }
X
X if (strlen (w) < 3)
X return;
X
X p[0] = 0;
X p--;
X
X /* ED is now completely gone */
X
X if (p[0] == 'I' && !vowel (p[-1])) {
X p[0] = 'Y';
X if (cflag)
X printf ("%s/D\n", w);
X else if ((dent = lookup (w, strlen (w), 1)) != NULL
X && dent->d_flag) {
X wordok = 1;
X return;
X }
X p[0] = 'I';
X }
X
X if ((p[0] != 'E' && p[0] != 'Y') ||
X (p[0] == 'Y' && vowel (p[-1]))) {
X if (cflag)
X printf ("%s/D\n", w);
X else if ((dent = lookup (w, strlen (w), 1)) != NULL) {
X if (dent->d_flag)
X wordok = 1;
X return;
X }
X }
X }
X
X t_ending (w)
X char *w;
X {
X
X char *p;
X struct dent *dent;
X
X p = w + strlen (w) - 3;
X
X if (strcmp (p, "EST") != 0)
X return;
X
X p[1] = 0; /* kill 'S' */
X
X if (cflag)
X printf ("%s/T\n", w);
X else if ((dent = lookup (w, strlen (w), 1)) != NULL
X && dent->t_flag) {
X wordok = 1;
X return;
X }
X
X if (strlen (w) < 3)
X return;
X
X p[0] = 0;
X p--;
X
X /* EST is now completely gone */
X
X if (p[0] == 'I' && !vowel (p[-1])) {
X p[0] = 'Y';
X if (cflag)
X printf ("%s/T\n", w);
X else if ((dent = lookup (w, strlen (w), 1)) != NULL
X && dent->t_flag) {
X wordok = 1;
X return;
X }
X p[0] = 'I';
X }
X
X if ((p[0] != 'E' && p[0] != 'Y') ||
X (p[0] == 'Y' && vowel (p[-1]))) {
X if (cflag)
X printf ("%s/T\n", w);
X else if ((dent = lookup (w, strlen (w), 1)) != NULL) {
X if (dent->t_flag)
X wordok = 1;
X return;
X }
X }
X
X }
X
X
X r_ending (w)
X char *w;
X {
X char *p;
X struct dent *dent;
X
X p = w + strlen (w) - 2;
X
X if (strcmp (p, "ER") != 0)
X return;
X
X p[1] = 0; /* kill 'R' */
X
X if (cflag)
X printf ("%s/R\n", w);
X else if ((dent = lookup (w, strlen (w), 1)) != NULL
X && dent->r_flag) {
X wordok = 1;
X return;
X }
X
X if (strlen (w) < 3)
X return;
X
X p[0] = 0;
X p--;
X
X /* ER is now completely gone */
X
X if (p[0] == 'I' && !vowel (p[-1])) {
X p[0] = 'Y';
X if (cflag)
X printf ("%s/R\n", w);
X else if ((dent = lookup (w, strlen (w), 1)) != NULL
X && dent->r_flag) {
X wordok = 1;
X return;
X }
X p[0] = 'I';
X }
X
X if ((p[0] != 'E' && p[0] != 'Y') ||
X (p[0] == 'Y' && vowel (p[-1]))) {
X if (cflag)
X printf ("%s/R\n", w);
X else if ((dent = lookup (w, strlen (w), 1)) != NULL) {
X if (dent->r_flag)
X wordok = 1;
X return;
X }
X }
X
X }
X
X h_ending (w)
X char *w;
X {
X char *p;
X struct dent *dent;
X
X p = w + strlen (w) - 2;
X
X if (strcmp (p, "TH") != 0)
X return;
X
X *p = 0;
X
X p -= 2;
X
X if (p[1] != 'Y') {
X if (cflag)
X printf ("%s/H\n", w);
X else if ((dent = lookup (w, strlen (w), 1)) != NULL
X && dent->h_flag)
X wordok = 1;
X }
X
X if (strcmp (p, "IE") != 0)
X return;
X
X p[0] = 'Y';
X p[1] = 0;
X
X if (cflag)
X printf ("%s/H\n", w);
X else if ((dent = lookup (w, strlen (w), 1)) != NULL)
X if (dent->h_flag)
X wordok = 1;
X
X }
X
X /*
X * check for flags: X, J, Z, S, P, M
X *
X * X -ions or -ications or -ens
X * J -ings
X * Z -ers or -iers
X * S -ies or -es or -s
X * P -iness or -ness
X * M -'S
X */
X
X s_ending (w)
X char *w;
X {
X char *p;
X struct dent *dent;
X
X p = w + strlen (w);
X
X p[-1] = 0;
X
X if (index ("SXZHY", p[-2]) == NULL || (p[-2] == 'Y' && vowel (p[-3]))) {
X if (cflag)
X printf ("%s/S\n", w);
X else if ((dent = lookup (w, strlen (w), 1)) != NULL
X && dent->s_flag) {
X wordok = 1;
X return;
X }
X }
X
X
X switch (p[-2]) { /* letter before S */
X case 'N': /* X */
X if (strcmp (p-4, "ION") == 0) {
X p[-4] = 'E';
X p[-3] = 0;
X if (cflag)
X printf ("%s/X\n", w);
X else if ((dent = lookup (w, strlen (w), 1)) != NULL
X && dent->x_flag) {
X wordok = 1;
X return;
X }
X }
X if (strcmp (p-8, "ICATE") == 0) {
X p[-8] = 'Y';
X p[-7] = 0;
X if (cflag)
X printf ("%s/X\n", w);
X else if ((dent = lookup (w, strlen (w), 1)) != NULL
X && dent->x_flag)
X wordok = 1;
X return;
X }
X if (strcmp (p-3, "EN") == 0 && p[-4] != 'E' && p[-4] != 'Y') {
X p[-3] = 0;
X if (cflag)
X printf ("%s/X\n", w);
X else if ((dent = lookup (w, strlen (w), 1)) != NULL
X && dent->x_flag)
X wordok = 1;
X return;
X }
X case 'G': /* J */
X if (strcmp (p-4, "ING") != 0)
X return;
X p[-4] = 'E';
X p[-3] = 0;
X if (cflag)
X printf ("%s/J\n", w);
X else if ((dent = lookup (w, strlen (w), 1)) != NULL
X && dent->j_flag) {
X wordok = 1;
X return;
X }
X if (p[-5] == 'E')
X return; /* This stops CREATEING */
X p[-4] = 0;
X if (cflag)
X printf ("%s/J\n", w);
X else if ((dent = lookup (w, strlen (w), 1)) != NULL
X && dent->j_flag)
X wordok = 1;
X return;
X case 'R': /* Z */
X if (strcmp (p-3, "ER") != 0)
X return;
X
X p[-2] = 0;
X if (cflag)
X printf ("%s/Z\n", w);
X else if ((dent = lookup (w, strlen (w), 1)) != NULL
X && dent->z_flag) {
X wordok = 1;
X return;
X }
X if (p[-4] == 'I' && !vowel (p[-5])) {
X p[-4] = 'Y';
X p[-3] = 0;
X if (cflag)
X printf ("%s/Z\n", w);
X else if ((dent = lookup (w, strlen (w), 1)) != NULL
X && dent->z_flag) {
X wordok = 1;
X return;
X }
X p[-4] = 'I';
X }
X if ((p[-4] != 'E' && p[-4] != 'Y') ||
X (p[-4] == 'Y' && vowel (p[-5]))) {
X p[-3] = 0;
X if (cflag)
X printf ("%s/Z\n", w);
X else if ((dent = lookup (w, strlen (w), 1)) != NULL
X && dent->z_flag)
X wordok = 1;
X }
X return;
X case 'E': /* S (except simple adding of an S) */
X p[-2] = 0; /* drop the ES */
X if (index ("SXZH", p[-3]) != NULL) {
X if (cflag)
X printf ("%s/S\n", w);
X else if ((dent = lookup (w, strlen (w), 1)) != NULL) {
X if (dent->s_flag)
X wordok = 1;;
X return;
X }
X }
X if (p[-3] == 'I') {
X p[-3] = 'Y';
X if (cflag)
X printf ("%s/S\n", w);
X else if ((dent = lookup (w, strlen (w), 1)) != NULL
X && dent->s_flag)
X wordok = 1;
X return;
X }
X return;
X
X case 'S': /* P */
X if (strcmp (p-4, "NES") != 0)
X return;
X
X p[-4] = 0; /* kill 'N' */
X if (p[-5] != 'Y' || vowel (p[-6])) {
X if (cflag)
X printf ("%s/P\n", w);
X else if ((dent = lookup (w, strlen (w), 1)) != NULL
X && dent->p_flag) {
X wordok = 1;
X return;
X }
X }
X if (p[-5] == 'I') {
X p[-5] = 'Y';
X if (cflag)
X printf ("%s/P\n", w);
X else if ((dent = lookup (w, strlen (w), 1)) != NULL
X && dent->p_flag)
X wordok = 1;
X }
X return;
X case '\'': /* M */
X p[-2] = '\0';
X if (cflag)
X printf ("%s/M\n", w);
X else if ((dent = lookup (w, strlen (w), 1)) != NULL
X && dent->m_flag)
X wordok = 1;
X return;
X }
X }
X
X /* only the N flag */
X n_ending (w)
X char *w;
X {
X char *p;
X struct dent *dent;
X
X p = w + strlen (w);
X
X if (p[-2] == 'E') {
X if (p[-3] == 'E' || p[-3] == 'Y')
X return;
X p[-2] = 0;
X if (cflag)
X printf ("%s/N\n", w);
X else if ((dent = lookup (w, strlen (w), 1)) != NULL
X && dent->n_flag)
X wordok = 1;
X return;
X }
X
X if (strcmp (p-3, "ION") != 0)
X return;
X
X p[-3] = 'E';
X p[-2] = 0;
X
X if (cflag)
X printf ("%s/N\n", w);
X else if ((dent = lookup (w, strlen (w), 1)) != NULL) {
X if (dent->n_flag)
X wordok = 1;
X return;
X }
X
X if (strcmp (p-7, "ICATE") != 0) /* check is really against "ICATION" */
X return;
X
X p[-7] = 'Y';
X p[-6] = 0;
X
X if (cflag)
X printf ("%s/N\n", w);
X else if ((dent = lookup (w, strlen (w), 1)) != NULL && dent->n_flag)
X wordok = 1;
X return;
X }
X
X /* flags: v */
X e_ending (w)
X char *w;
X {
X char *p;
X struct dent *dent;
X
X p = w + strlen (w);
X
X if (strcmp (p-3, "IVE") != 0)
X return;
X p[-3] = 'E';
X p[-2] = 0;
X
X if (cflag)
X printf ("%s/V\n", w);
X else if ((dent = lookup (w, strlen (w), 1)) != NULL
X && dent->v_flag) {
X wordok = 1;
X return;
X }
X
X if (p[-4] == 'E')
X return;
X
X p[-3] = 0;
X
X if (cflag)
X printf ("%s/V\n", w);
X else if ((dent = lookup (w, strlen (w), 1)) != NULL && dent->v_flag)
X wordok = 1;
X return;
X }
X
X /* flags: y */
X y_ending (w)
X char *w;
X {
X char *p;
X struct dent *dent;
X
X p = w + strlen (w);
X
X if (strcmp (p-2, "LY") != 0)
X return;
X
X p[-2] = 0;
X
X if (cflag)
X printf ("%s/Y\n", w);
X else if ((dent = lookup (w, strlen (w), 1)) != NULL && dent->y_flag)
X wordok = 1;
X return;
X }
X
X vowel (c)
X char c;
X {
X return (c == 'A' || c == 'E' || c == 'I' || c == 'O' || c == 'U');
X }
SHAR_EOF
if test 10274 -ne "`wc -c < 'good.c'`"
then
echo shar: error transmitting "'good.c'" '(should have been 10274 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'hash.c'" '(343 characters)'
if test -f 'hash.c'
then
echo shar: will not over-write existing file "'hash.c'"
else
sed 's/^X //' << \SHAR_EOF > 'hash.c'
X /* -*- Mode:Text -*- */
X /*
X * hash.c - a simple hash function for ispell
X *
X * Pace Willisson, 1983
X */
X
X hash (s, n, hashsize)
X register char *s;
X register n;
X register hashsize;
X {
X register short h = 0;
X
X while (n--) {
X h ^= *s++;
X if (h < 0) {
X h <<= 1;
X h++;
X } else {
X h <<= 1;
X }
X }
X
X h &= 077777;
X return (h %= hashsize);
X }
X
X
X
X
SHAR_EOF
if test 343 -ne "`wc -c < 'hash.c'`"
then
echo shar: error transmitting "'hash.c'" '(should have been 343 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'ispell.c'" '(16239 characters)'
if test -f 'ispell.c'
then
echo shar: will not over-write existing file "'ispell.c'"
else
sed 's/^X //' << \SHAR_EOF > 'ispell.c'
X /* -*- Mode:Text -*- */
X
X /*
X * ispell.c - An interactive spelling corrector.
X *
X * Copyright (c), 1983, by Pace Willisson
X * Permission for non-profit use is hereby granted.
X * All other rights reserved.
X *
X * 1987, Robert McQueer, added:
X * -w option & handling of extra legal word characters
X * -d option for alternate dictionary file
X * -p option & WORDLIST variable for alternate personal dictionary
X * -x option to suppress .bak files.
X * 8 bit text & config.h parameters
X * 1987, Geoff Kuenning, added:
X * -c option for creating suffix suggestions from raw words
X * suffixes in personal dictionary file
X * hashed personal dictionary file
X */
X
X #include <stdio.h>
X #include <ctype.h>
X #include <sys/param.h>
X #include "ispell.h"
X #include "config.h"
X
X FILE *infile;
X FILE *outfile;
X
X char hashname[MAXPATHLEN];
X
X extern struct dent *treeinsert();
X
X /*
X ** we use extended character set range specifically to allow intl.
X ** character set characters. We are being REALLY paranoid about indexing
X ** this array - explicitly cast into unsigned INTEGER, then mask
X ** If NO8BIT is set, text will be masked to ascii range.
X */
X static int Trynum;
X #ifdef NO8BIT
X static char Try[128];
X static char Checkch[128];
X #define iswordch(X) (Checkch[((unsigned)(X))&0x7f])
X #else
X static char Try[256];
X static char Checkch[256];
X #define iswordch(X) (Checkch[((unsigned)(X))&0xff])
X #endif
X
X givehelp ()
X {
X erase ();
X printf ("Whenever a word is found that is not in the dictionary,\r\n");
X printf ("it is printed on the first line of the screen. If the dictionary\r\n");
X printf ("contains any similar words, they are listed with a single digit\r\n");
X printf ("next to each one. You have the option of replacing the word\r\n");
X printf ("completely, or choosing one of the suggested words.\r\n");
X printf ("\r\n");
X printf ("Commands are:\r\n\r\n");
X printf ("R Replace the misspelled word completely.\r\n");
X printf ("Space Accept the word this time only\r\n");
X printf ("A Accept the word for the rest of this file.\r\n");
X printf ("I Accept the word, and put it in your private dictionary.\r\n");
X printf ("0-9 Replace with one of the suggested words.\r\n");
X printf ("L Look up words in system dictionary.\r\n");
X printf ("Q Write the rest of this file, ignoring misspellings, ");
X printf ( "and start next file.\r\n");
X printf ("X Exit immediately. Asks for confirmation. ");
X printf ( "Leaves file unchanged.\r\n");
X printf ("! Shell escape.\r\n");
X printf ("^L Redraw screen.\r\n");
X printf ("\r\n\r\n");
X printf ("-- Type space to continue --");
X fflush (stdout);
X getchar ();
X }
X
X
X char *getline();
X
X int cflag = 0;
X int lflag = 0;
X int aflag = 0;
X int fflag = 0;
X #ifndef USG
X int sflag = 0;
X #endif
X int xflag = 0;
X
X char *askfilename;
X
X static char *Cmd;
X
X usage ()
X {
X fprintf (stderr, "Usage: %s [-dfile | -pfile | -wchars | -x] file .....\n",Cmd);
X fprintf (stderr, " %s [-dfile | -pfile | -wchars] -l\n",Cmd);
X #ifdef USG
X fprintf (stderr, " %s [-dfile | -pfile | -ffile | -s] -a\n",Cmd);
X #else
X fprintf (stderr, " %s [-dfile | -pfile | -ffile] -a\n",Cmd);
X #endif
X fprintf (stderr, " %s [-wchars] -c\n");
X exit (1);
X }
X
X static initckch()
X {
X int c;
X
X Trynum = 0;
X #ifdef NO8BIT
X for (c = 0; c < 128; ++c) {
X #else
X for (c = 0; c < 256; ++c) {
X #endif
X if (myalpha((char) c)) {
X Checkch[c] = (char) 1;
X if (myupper((char) c)) {
X Try[Trynum] = (char) c;
X ++Trynum;
X }
X }
X else
X Checkch[c] = (char) 0;
X }
X }
X
X main (argc, argv)
X char **argv;
X {
X char *p;
X char *cpd;
X char num[4];
X unsigned mask;
X
X Cmd = *argv;
X
X initckch();
X sprintf(hashname,"%s/%s",LIBDIR,DEFHASH);
X
X cpd = NULL;
X
X argv++;
X argc--;
X while (argc && **argv == '-') {
X switch ((*argv)[1]) {
X case 'a':
X aflag++;
X break;
X case 'c':
X cflag++;
X lflag++;
X break;
X case 'x':
X xflag++;
X break;
X case 'f':
X fflag++;
X p = (*argv)+2;
X if (*p == '\0') {
X argv++; argc--;
X if (argc == 0)
X usage ();
X p = *argv;
X }
X askfilename = p;
X break;
X case 'l':
X lflag++;
X break;
X #ifndef USG
X case 's':
X sflag++;
X break;
X #endif
X case 'p':
X cpd = (*argv)+2;
X if (*cpd == '\0') {
X argv++; argc--;
X if (argc == 0)
X usage ();
X cpd = *argv;
X }
X break;
X case 'd':
X p = (*argv)+2;
X if (*p == '\0') {
X argv++; argc--;
X if (argc == 0)
X usage ();
X p = *argv;
X }
X if (*p == '/')
X strcpy(hashname,p);
X else
X sprintf(hashname,"%s/%s",LIBDIR,p);
X break;
X case 'w':
X num[3] = '\0';
X #ifdef NO8BIT
X mask = 0x7f;
X #else
X mask = 0xff;
X #endif
X p = (*argv)+2;
X if (*p == '\0') {
X argv++; argc--;
X if (argc == 0)
X usage ();
X p = *argv;
X }
X while (Trynum <= mask && *p != '\0') {
X if (*p != 'n') {
X Checkch[((unsigned)(*p))&mask] = (char) 1;
X Try[Trynum] = *p & mask;
X ++p;
X }
X else {
X ++p;
X num[0] = *p; ++p;
X num[1] = *p; ++p;
X num[2] = *p; ++p;
X Try[Trynum] = atoi(num) & mask;
X Checkch[atoi(num)&mask] = (char) 1;
X }
X ++Trynum;
X }
X break;
X default:
X usage();
X }
X argv++; argc--;
X }
X
X if (!argc && !lflag && !aflag)
X usage ();
X
X if (linit () < 0)
X exit (0);
X
X treeinit (cpd);
X
X if (aflag) {
X askmode ();
X exit (0);
X }
X
X if (lflag) {
X infile = stdin;
X checkfile ();
X exit (0);
X }
X
X terminit ();
X
X while (argc--)
X dofile (*argv++);
X
X done ();
X }
X
X char firstbuf[BUFSIZ], secondbuf[BUFSIZ];
X char *currentchar;
X char token[BUFSIZ];
X
X int quit;
X
X char *currentfile = NULL;
X
X dofile (filename)
X char *filename;
X {
X int c;
X char bakfile[256];
X
X currentfile = filename;
X
X if ((infile = fopen (filename, "r")) == NULL) {
X fprintf (stderr, "Can't open %s\r\n", filename);
X sleep (2);
X return;
X }
X
X if (access (filename, 2) < 0) {
X fprintf (stderr, "Can't write to %s\r\n", filename);
X sleep (2);
X return;
X }
X
X strcpy(tempfile, TEMPNAME);
X mktemp (tempfile);
X if ((outfile = fopen (tempfile, "w")) == NULL) {
X fprintf (stderr, "Can't create %s\r\n", tempfile);
X sleep (2);
X return;
X }
X
X quit = 0;
X
X checkfile ();
X
X fclose (infile);
X fclose (outfile);
X
X if (!cflag)
X treeoutput ();
X
X if ((infile = fopen (tempfile, "r")) == NULL) {
X fprintf (stderr, "tempoary file disappeared (%s)\r\n", tempfile);
X sleep (2);
X return;
X }
X
X sprintf(bakfile, "%s.bak", filename);
X if(link(filename, bakfile) == 0)
X unlink(filename);
X
X /* if we can't write new, preserve .bak regardless of xflag */
X if ((outfile = fopen (filename, "w")) == NULL) {
X fprintf (stderr, "can't create %s\r\n", filename);
X sleep (2);
X return;
X }
X
X while ((c = getc (infile)) != EOF)
X putc (c, outfile);
X
X fclose (infile);
X fclose (outfile);
X
X unlink (tempfile);
X if (xflag)
X unlink(bakfile);
X }
X
X checkfile ()
X {
X int c;
X char *p;
X int len;
X
X secondbuf[0] = 0;
X currentchar = secondbuf;
X
X while (1) {
X strcpy (firstbuf, secondbuf);
X if (quit) { /* quit can't be set in l mode */
X while (fgets (secondbuf, sizeof secondbuf, infile) != NULL)
X fputs (secondbuf, outfile);
X break;
X }
X
X if (fgets (secondbuf, sizeof secondbuf, infile) == NULL)
X break;
X currentchar = secondbuf;
X
X len = strlen (secondbuf) - 1;
X if (secondbuf [ len ] == '\n')
X secondbuf [ len ] = 0;
X
X /* if this is a formatter command, skip over it */
X if (*currentchar == '.') {
X while (*currentchar && !myspace (*currentchar)) {
X if (!lflag)
X putc (*currentchar, outfile);
X currentchar++;
X }
X if (*currentchar == 0) {
X if (!lflag)
X putc ('\n', outfile);
X continue;
X }
X }
X
X while (1) {
X while (*currentchar && !iswordch(*currentchar)) {
X /* formatting escape sequences */
X if (*currentchar == '\\') {
X if(currentchar[1] == 'f') {
X /* font change: \fX */
X copyout(¤tchar, 3);
X continue;
X }
X else if(currentchar[1] == 's') {
X /* size change */
X if(currentchar[2] < 6 &&
X currentchar[2] != 0)
X /* two digit size */
X copyout(¤tchar, 4);
X else
X /* one digit size */
X copyout(¤tchar, 3);
X continue;
X }
X else if(currentchar[1] == '(') {
X /* extended char set escape: \(XX */
X copyout(¤tchar, 4);
X continue;
X }
X }
X
X if (!lflag)
X putc (*currentchar, outfile);
X currentchar++;
X }
X
X if (*currentchar == 0)
X break;
X
X p = token;
X while (iswordch(*currentchar) ||
X (*currentchar == '\'' &&
X iswordch(*(currentchar + 1))))
X *p++ = *currentchar++;
X *p = 0;
X if (lflag) {
X if (!good (token) && !cflag)
X printf ("%s\r\n", token);
X } else {
X if (!quit)
X correct (token, ¤tchar);
X }
X if (!lflag)
X fprintf (outfile, "%s", token);
X }
X if (!lflag)
X putc ('\n', outfile);
X }
X }
X
X char possibilities[10][BUFSIZ];
X int pcount;
X
X correct (token, currentchar)
X char *token;
X char **currentchar;
X {
X int c;
X int i;
X char *p;
X int len;
X char *begintoken;
X
X len = strlen (token);
X begintoken = *currentchar - len;
X
X checkagain:
X if (good (token))
X return;
X
X erase ();
X printf (" %s", token);
X if (currentfile)
X printf (" File: %s", currentfile);
X printf ("\r\n\r\n");
X
X makepossibilities (token);
X
X for (i = 0; i < 10; i++) {
X if (possibilities[i][0] == 0)
X break;
X printf ("%d: %s\r\n", i, possibilities[i]);
X }
X
X move (15, 0);
X printf ("%s\r\n", firstbuf);
X
X for (p = secondbuf; p != begintoken; p++)
X putchar (*p);
X inverse ();
X for (i = strlen (token); i > 0; i--)
X putchar (*p++);
X normal ();
X while (*p)
X putchar (*p++);
X printf ("\r\n");
X
X while (1) {
X switch (c = (getchar () & NOPARITY)) {
X #ifndef USG
X case 'Z' & 037:
X stop ();
X erase ();
X goto checkagain;
X #endif
X case ' ':
X erase ();
X return;
X case 'x': case 'X':
X printf ("Are you sure you want to throw away your changes? ");
X c = (getchar () & NOPARITY);
X if (c == 'y' || c == 'Y') {
X erase ();
X done ();
X }
X putchar (7);
X goto checkagain;
X case 'i': case 'I':
X treeinsert (token, 1);
X erase ();
X return;
X case 'a': case 'A':
X treeinsert (token, 0);
X erase ();
X return;
X case 'L' & 037:
X goto checkagain;
X case '?':
X givehelp ();
X goto checkagain;
X case '!':
X {
X char buf[200];
X move (18, 0);
X putchar ('!');
X if (getline (buf) == NULL) {
X putchar (7);
X erase ();
X goto checkagain;
X }
X printf ("\r\n");
X shellescape (buf);
X erase ();
X goto checkagain;
X }
X case 'r': case 'R':
X move (18, 0);
X printf ("Replace with: ");
X if (getline (token) == NULL) {
X putchar (7);
X erase ();
X goto checkagain;
X }
X inserttoken (secondbuf, begintoken, token, currentchar);
X erase ();
X goto checkagain;
X case '0': case '1': case '2': case '3': case '4':
X case '5': case '6': case '7': case '8': case '9':
X if (possibilities[c - '0'][0] != 0) {
X strcpy (token, possibilities[c - '0']);
X inserttoken (secondbuf, begintoken, token, currentchar); erase ();
X return;
X }
X putchar (7);
X break;
X case 'l': case 'L':
X {
X char buf[100];
X move (18, 0);
X printf ("Lookup string ('*' is wildcard): ");
X if (getline (buf) == NULL) {
X putchar (7);
X erase ();
X goto checkagain;
X }
X printf ("\r\n\r\n");
X lookharder (buf);
X erase ();
X goto checkagain;
X }
X case 'q': case 'Q':
X quit = 1;
X erase ();
X return;
X default:
X putchar (7);
X break;
X }
X }
X }
X
X inserttoken (buf, start, token, currentchar)
X char *buf, *start, *token;
X char **currentchar;
X {
X char copy[BUFSIZ];
X char *p, *q;
X
X strcpy (copy, buf);
X
X for (p = buf, q = copy; p != start; p++, q++)
X *p = *q;
X while (*token)
X *p++ = *token++;
X q += *currentchar - start;
X *currentchar = p;
X while (*p++ = *q++)
X ;
X }
X
X
X makepossibilities (word)
X char word[];
X {
X int i;
X
X for (i = 0; i < 10; i++)
X possibilities[i][0] = 0;
X pcount = 0;
X
X if (pcount < 10) wrongletter (word);
X if (pcount < 10) extraletter (word);
X if (pcount < 10) missingletter (word);
X if (pcount < 10) transposedletter (word);
X
X }
X
X char *cap();
X
X insert (word)
X char *word;
X {
X int i;
X
X for (i = 0; i < pcount; i++)
X if (strcmp (possibilities[i], word) == 0)
X return (0);
X
X strcpy (possibilities[pcount++], word);
X if (pcount >= 10)
X return (-1);
X else
X return (0);
X }
X
X wrongletter (word)
X char word[];
X {
X int i, j, c, n;
X char newword[BUFSIZ];
X
X n = strlen (word);
X strcpy (newword, word);
X
X for (i = 0; i < n; i++) {
X for (j=0; j < Trynum; ++j) {
X newword[i] = Try[j];
X if (good (newword)) {
X if (insert (cap (newword, word)) < 0)
X return;
X }
X }
X newword[i] = word[i];
X }
X }
X
X extraletter (word)
X char word[];
X {
X char newword[BUFSIZ], *p, *s, *t;
X
X if (strlen (word) < 3)
X return;
X
X for (p = word; *p; p++) {
X for (s = word, t = newword; *s; s++)
X if (s != p)
X *t++ = *s;
X *t = 0;
X if (good (newword)) {
X if (insert (cap (newword, word)) < 0)
X return;
X }
X }
X }
X
X missingletter (word)
X char word[];
X {
X char newword[BUFSIZ], *p, *r, *s, *t;
X int i;
X
X for (p = word; p == word || p[-1]; p++) {
X for (s = newword, t = word; t != p; s++, t++)
X *s = *t;
X r = s++;
X while (*t)
X *s++ = *t++;
X *s = 0;
X for (i=0; i < Trynum; ++i) {
X *r = Try[i];
X if (good (newword)) {
X if (insert (cap (newword, word)) < 0)
X return;
X }
X }
X }
X }
X
X transposedletter (word)
X char word[];
X {
X char newword[BUFSIZ];
X int t;
X char *p;
X
X strcpy (newword, word);
X for (p = newword; p[1]; p++) {
X t = p[0];
X p[0] = p[1];
X p[1] = t;
X if (good (newword)) {
X if (insert (cap (newword, word)) < 0)
X return;
X }
X t = p[0];
X p[0] = p[1];
X p[1] = t;
X }
X }
X
X char *
X cap (word, pattern)
X char word[], pattern[];
X {
X static char newword[BUFSIZ];
X char *p, *q;
X
X if (*word == 0)
X return;
X
X if (myupper (pattern[0])) {
X if (myupper (pattern[1])) {
X for (p = word, q = newword; *p; p++, q++) {
X if (mylower (*p))
X *q = toupper (*p);
X else
X *q = *p;
X }
X *q = 0;
X } else {
X if (mylower (word [0]))
X newword[0] = toupper (word[0]);
X else
X newword[0] = word[0];
X
X for (p = word + 1, q = newword + 1; *p; p++, q++)
X if (myupper (*p))
X *q = tolower (*p);
X else
X *q = *p;
X
X *q = 0;
X }
X } else {
X for (p = word, q = newword; *p; p++, q++)
X if (myupper (*p))
X *q = tolower (*p);
X else
X *q = *p;
X *q = 0;
X }
X return (newword);
X }
X
X char *
X getline (s)
X char *s;
X {
X char *p;
X int c;
X
X p = s;
X
X while (1) {
X c = (getchar () & NOPARITY);
X if (c == '\\') {
X putchar ('\\');
X c = (getchar () & NOPARITY);
X backup ();
X putchar (c);
X *p++ = c;
X } else if (c == ('G' & 037)) {
X return (NULL);
X } else if (c == '\n' || c == '\r') {
X *p = 0;
X return (s);
X } else if (c == erasechar) {
X if (p != s) {
X p--;
X backup ();
X putchar (' ');
X backup ();
X }
X } else if (c == killchar) {
X while (p != s) {
X p--;
X backup ();
X putchar (' ');
X backup ();
X }
X } else {
X *p++ = c;
X putchar (c);
X }
X }
X }
X
X askmode ()
X {
X char buf[BUFSIZ];
X int i;
X
X if (fflag) {
X if (freopen (askfilename, "w", stdout) == NULL) {
X fprintf (stderr, "Can't create %s\n", askfilename);
X exit (1);
X }
X }
X
X setbuf (stdin, NULL);
X setbuf (stdout, NULL);
X
X while (gets (buf) != NULL) {
X if (good (buf)) {
X if (rootword[0] == 0) {
X printf ("*\n"); /* perfect match */
X } else {
X printf ("+ %s\n", rootword);
X }
X } else {
X makepossibilities (buf);
X if (possibilities[0][0]) {
X printf ("& ");
X for (i = 0; i < 10; i++) {
X if (possibilities[i][0] == 0)
X break;
X printf ("%s ", possibilities[i]);
X }
X printf ("\n");
X } else {
X printf ("#\n");
X }
X }
X #ifndef USG
X if (sflag) {
X stop ();
X if (fflag) {
X rewind (stdout);
X creat (askfilename, 0666);
X }
X }
X #endif
X }
X }
X
X
X copyout(cc, cnt)
X char **cc;
X {
X while (--cnt >= 0) {
X if (*(*cc) == 0)
X break;
X if (!lflag)
X putc (*(*cc), outfile);
X (*cc)++;
X }
X
X }
X
X lookharder(string)
X char *string;
X {
X char cmd[150];
X char *g, *s, grepstr[100];
X int wild = 0;
X
X g = grepstr;
X for (s = string; *s != '\0'; s++)
X if (*s == '*') {
X wild++;
X *g++ = '.';
X *g++ = '*';
X } else
X *g++ = *s;
X *g = '\0';
X if (grepstr[0]) {
X #ifdef LOOK
X if (wild)
X /* string has wild card characters */
X sprintf (cmd, "%s '^%s$' %s", EGREPCMD, grepstr, WORDS);
X else
X /* no wild, use look(1) */
X sprintf (cmd, "/usr/bin/look -df %s %s", grepstr, WORDS);
X #else
X sprintf (cmd, "%s '^%s$' %s", EGREPCMD, grepstr, WORDS);
X #endif
X shellescape (cmd);
X }
X }
SHAR_EOF
if test 16239 -ne "`wc -c < 'ispell.c'`"
then
echo shar: error transmitting "'ispell.c'" '(should have been 16239 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'ispell.h'" '(4964 characters)'
if test -f 'ispell.h'
then
echo shar: will not over-write existing file "'ispell.h'"
else
sed 's/^X //' << \SHAR_EOF > 'ispell.h'
X /* -*- Mode: Text -*- */
X
X #define LIBDIR "/tmp2/lib"
X
X struct dent {
X struct dent *next;
X char *word;
X
X unsigned short used : 1;
X
X /* bit fields for all of the flags */
X unsigned short v_flag : 1;
X /*
X "V" flag:
X ...E --> ...IVE as in CREATE --> CREATIVE
X if # .ne. E, ...# --> ...#IVE as in PREVENT --> PREVENTIVE
X */
X unsigned short n_flag : 1;
X /*
X "N" flag:
X ...E --> ...ION as in CREATE --> CREATION
X ...Y --> ...ICATION as in MULTIPLY --> MULTIPLICATION
X if # .ne. E or Y, ...# --> ...#EN as in FALL --> FALLEN
X */
X unsigned short x_flag : 1;
X /*
X "X" flag:
X ...E --> ...IONS as in CREATE --> CREATIONS
X ...Y --> ...ICATIONS as in MULTIPLY --> MULTIPLICATIONS
X if # .ne. E or Y, ...# --> ...#ENS as in WEAK --> WEAKENS
X */
X unsigned short h_flag : 1;
X /*
X "H" flag:
X ...Y --> ...IETH as in TWENTY --> TWENTIETH
X if # .ne. Y, ...# --> ...#TH as in HUNDRED --> HUNDREDTH
X */
X unsigned short y_flag : 1;
X /*
X "Y" FLAG:
X ... --> ...LY as in QUICK --> QUICKLY
X */
X unsigned short g_flag : 1;
X /*
X "G" FLAG:
X ...E --> ...ING as in FILE --> FILING
X if # .ne. E, ...# --> ...#ING as in CROSS --> CROSSING
X */
X unsigned short j_flag : 1;
X /*
X "J" FLAG"
X ...E --> ...INGS as in FILE --> FILINGS
X if # .ne. E, ...# --> ...#INGS as in CROSS --> CROSSINGS
X */
X unsigned short d_flag : 1;
X /*
X "D" FLAG:
X ...E --> ...ED as in CREATE --> CREATED
X if @ .ne. A, E, I, O, or U,
X ... at Y --> ... at IED as in IMPLY --> IMPLIED
X if # .ne. E or Y, or (# = Y and @ = A, E, I, O, or U)
X ...@# --> ...@#ED as in CROSS --> CROSSED
X or CONVEY --> CONVEYED
X */
X unsigned short t_flag : 1;
X /*
X "T" FLAG:
X ...E --> ...EST as in LATE --> LATEST
X if @ .ne. A, E, I, O, or U,
X ... at Y --> ... at IEST as in DIRTY --> DIRTIEST
X if # .ne. E or Y, or (# = Y and @ = A, E, I, O, or U)
X ...@# --> ...@#EST as in SMALL --> SMALLEST
X or GRAY --> GRAYEST
X */
X unsigned short r_flag : 1;
X /*
X "R" FLAG:
X ...E --> ...ER as in SKATE --> SKATER
X if @ .ne. A, E, I, O, or U,
X ... at Y --> ... at IER as in MULTIPLY --> MULTIPLIER
X if # .ne. E or Y, or (# = Y and @ = A, E, I, O, or U)
X ...@# --> ...@#ER as in BUILD --> BUILDER
X or CONVEY --> CONVEYER
X */
X unsigned short z_flag : 1;
X /*
X "Z FLAG:
X ...E --> ...ERS as in SKATE --> SKATERS
X if @ .ne. A, E, I, O, or U,
X ... at Y --> ... at IERS as in MULTIPLY --> MULTIPLIERS
X if # .ne. E or Y, or (# = Y and @ = A, E, I, O, or U)
X ...@# --> ...@#ERS as in BUILD --> BUILDERS
X or SLAY --> SLAYERS
X */
X unsigned short s_flag : 1;
X /*
X "S" FLAG:
X if @ .ne. A, E, I, O, or U,
X ... at Y --> ... at IES as in IMPLY --> IMPLIES
X if # .eq. S, X, Z, or H,
X ...# --> ...#ES as in FIX --> FIXES
X if # .ne. S,X,Z,H, or Y, or (# = Y and @ = A, E, I, O, or U)
X ...# --> ...#S as in BAT --> BATS
X or CONVEY --> CONVEYS
X */
X unsigned short p_flag : 1;
X /*
X "P" FLAG:
X if @ .ne. A, E, I, O, or U,
X ... at Y --> ... at INESS as in CLOUDY --> CLOUDINESS
X if # .ne. Y, or @ = A, E, I, O, or U,
X ...@# --> ...@#NESS as in LATE --> LATENESS
X or GRAY --> GRAYNESS
X */
X unsigned short m_flag : 1;
X /*
X "M" FLAG:
X ... --> ...'S as in DOG --> DOG'S
X */
X
X unsigned short keep : 1;
X
X };
X
X #define WORDLEN 30
X
X struct hashheader {
X int magic;
X int stringsize;
X int tblsize;
X };
X
X #define MAGIC 1
X
X
X /*
X * termcap variables
X */
X char *tgetstr();
X char PC; /* padding character */
X char *BC; /* backspace if not ^H */
X char *UP; /* Upline (cursor up) */
X char *cd; /* clear to end of display */
X char *ce; /* clear to end of line */
X char *cl; /* clear display */
X char *cm; /* cursor movement */
X char *dc; /* delete character */
X char *dl; /* delete line */
X char *dm; /* delete mode */
X char *ed; /* exit delete mode */
X char *ei; /* exit insert mode */
X char *ho; /* home */
X char *ic; /* insert character */
X char *il; /* insert line */
X char *im; /* insert mode */
X char *ip; /* insert padding */
X char *nd; /* non-destructive space */
X char *vb; /* visible bell */
X char *so; /* standout */
X char *se; /* standout end */
X int bs;
X int li, co; /* lines, columns */
X
X char termcap[1024];
X char termstr[1024]; /* for string values */
X char *termptr;
X
X char rootword[BUFSIZ];
X struct dent *lastdent;
X
X char *hashstrings;
X
X
X int aflag;
X int lflag;
X
X int erasechar;
X int killchar;
X
X char tempfile[200];
SHAR_EOF
if test 4964 -ne "`wc -c < 'ispell.h'`"
then
echo shar: error transmitting "'ispell.h'" '(should have been 4964 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'lookup.c'" '(2762 characters)'
if test -f 'lookup.c'
then
echo shar: will not over-write existing file "'lookup.c'"
else
sed 's/^X //' << \SHAR_EOF > 'lookup.c'
X /* -*- Mode:Text -*- */
X
X /*
X * lookup.c - see if a word appears in the dictionary
X *
X * Pace Willisson, 1983
X */
X
X #include <stdio.h>
X #include "ispell.h"
X #include "config.h"
X
X
X struct dent *hashtbl;
X int hashsize;
X
X extern char hashname[];
X
X static inited = 0;
X
X linit ()
X {
X int hashfd;
X struct hashheader hashheader;
X register int i;
X register struct dent *dp;
X
X if (inited)
X return;
X
X if ((hashfd = open (hashname, 0)) < 0) {
X fprintf (stderr, "can't open %s\r\n", hashname);
X return (-1);
X }
X
X hashsize = read (hashfd, &hashheader, sizeof hashheader);
X if (hashsize == 0) {
X /*
X * Empty file - create an empty dummy table. We
X * actually have to have one entry since the hash
X * algorithm involves a divide by the table size
X * (actually modulo, but zero is still unacceptable).
X * So we create an entry with a word of all lowercase,
X * which can't match because the comparison string has
X * been converted to uppercase by then.
X */
X close (hashfd);
X hashsize = 1; /* This prevents divides by zero */
X hashtbl = (struct dent *) calloc (1, sizeof (struct dent));
X if (hashtbl == NULL) {
X (void) fprintf (stderr,
X "Couldn't allocate space for hash table\n");
X return (-1);
X }
X hashtbl[0].word = "xxxxxxxxxxx";
X hashtbl[0].next = NULL;
X hashtbl[0].keep = 0;
X hashtbl[0].used = 1;
X /* The flag bits don't matter, but calloc cleared them. */
X inited = 1;
X return 0;
X }
X else if (hashsize < 0 || hashheader.magic != MAGIC) {
X fprintf (stderr, "Illegal format hash table\r\n");
X return (-1);
X }
X hashstrings = (char *) malloc (hashheader.stringsize);
X hashtbl = (struct dent *) malloc (hashheader.tblsize * sizeof (struct dent));
X if (hashtbl == NULL || hashstrings == NULL) {
X (void) fprintf (stderr,
X "Couldn't allocate space for hash table\n");
X return (-1);
X }
X hashsize = hashheader.tblsize;
X
X read (hashfd, hashstrings, hashheader.stringsize);
X read (hashfd, hashtbl, hashheader.tblsize * sizeof (struct dent));
X close (hashfd);
X
X for (i = hashsize, dp = hashtbl; --i >= 0; dp++) {
X dp->word = &hashstrings [ (int)(dp->word) ];
X if (dp->next == (struct dent *) -1)
X dp->next = NULL;
X else
X dp->next = &hashtbl [ (int)(dp->next) ];
X }
X
X inited = 1;
X return (0);
X }
X
X /* n is length of s */
X struct dent *
X lookup (s, n, dotree)
X register char *s;
X {
X int i;
X register struct dent *dp;
X register char *s1, *s2;
X
X dp = &hashtbl [ hash (s, n, hashsize) ];
X for ( ; dp != NULL; dp = dp->next) {
X /* quick strcmp, but only for equality */
X s1 = dp->word;
X s2 = s;
X while (*s1 == *s2++)
X if (*s1++=='\0') {
X lastdent = dp;
X return (lastdent);
X }
X }
X if (dotree) {
X i = s[n];
X s[n] = '\0';
X if ((dp = treelookup (s)) != NULL)
X lastdent = dp;
X s[n] = i;
X return dp;
X }
X else
X return NULL;
X }
X
SHAR_EOF
if test 2762 -ne "`wc -c < 'lookup.c'`"
then
echo shar: error transmitting "'lookup.c'" '(should have been 2762 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'term.c'" '(3781 characters)'
if test -f 'term.c'
then
echo shar: will not over-write existing file "'term.c'"
else
sed 's/^X //' << \SHAR_EOF > 'term.c'
X /* -*- Mode:Text -*- */
X
X /*
X * term.c - deal with termcap, and unix terminal mode settings
X *
X * Pace Willisson, 1983
X */
X
X #include <stdio.h>
X #ifdef USG
X #include <termio.h>
X #else
X #include <sgtty.h>
X #endif
X #include <signal.h>
X #include "ispell.h"
X
X int putch();
X
X erase ()
X {
X if (cl)
X tputs(cl, li, putch);
X else {
X if (ho)
X tputs(ho, 100, putch);
X else if (cm)
X tputs(tgoto(cm, 0, 0), 100, putch);
X tputs(cd, li, putch);
X }
X }
X
X move (row, col)
X {
X tputs (tgoto (cm, col, row), 100, putch);
X }
X
X inverse ()
X {
X tputs (so, 10, putch);
X }
X
X normal ()
X {
X tputs (se, 10, putch);
X }
X
X backup ()
X {
X if (BC)
X tputs (BC, 1, putch);
X else
X putchar ('\b');
X }
X
X putch (c)
X {
X putchar (c);
X }
X
X #ifdef USG
X struct termio sbuf, osbuf;
X #else
X struct sgttyb sbuf, osbuf;
X #endif
X static termchanged = 0;
X
X
X terminit ()
X {
X int done();
X #ifdef USG
X if (!isatty(0)) {
X fprintf (stderr, "Can't deal with non interactive use yet.\n");
X exit (1);
X }
X ioctl (0, TCGETA, &osbuf);
X termchanged = 1;
X
X sbuf = osbuf;
X sbuf.c_lflag &= ~(ECHO | ECHOK | ECHONL | ICANON);
X sbuf.c_oflag &= ~(OPOST);
X sbuf.c_iflag &= ~(INLCR | IGNCR | ICRNL);
X sbuf.c_cc[VMIN] = 1;
X sbuf.c_cc[VTIME] = 1;
X ioctl (0, TCSETAW, &sbuf);
X
X erasechar = osbuf.c_cc[VERASE];
X killchar = osbuf.c_cc[VKILL];
X
X signal (SIGINT, done);
X #else
X int tpgrp;
X int onstop();
X
X retry:
X sigsetmask(1<<SIGTSTP | 1<<SIGTTIN | 1<<SIGTTOU);
X if (ioctl(0, TIOCGPGRP, &tpgrp) != 0) {
X fprintf (stderr, "Can't deal with non interactive use yet.\n");
X exit (1);
X }
X if (tpgrp != getpgrp(0)) { /* not in foreground */
X sigsetmask(1<<SIGTSTP | 1<<SIGTTIN);
X signal(SIGTTOU, SIG_DFL);
X kill(0, SIGTTOU);
X /* job stops here waiting for SIGCONT */
X goto retry;
X }
X
X ioctl (0, TIOCGETP, &osbuf);
X termchanged = 1;
X
X sbuf = osbuf;
X sbuf.sg_flags &= ~ECHO;
X sbuf.sg_flags |= RAW;
X ioctl (0, TIOCSETP, &sbuf);
X
X erasechar = sbuf.sg_erase;
X killchar = sbuf.sg_kill;
X
X signal (SIGINT, done);
X
X sigsetmask(0);
X signal(SIGTTIN, onstop);
X signal(SIGTTOU, onstop);
X signal(SIGTSTP, onstop);
X #endif
X
X tgetent(termcap, getenv("TERM"));
X termptr = termstr;
X bs = tgetflag("bs");
X BC = tgetstr("bc", &termptr);
X UP = tgetstr("up", &termptr);
X cd = tgetstr("cd", &termptr);
X ce = tgetstr("ce", &termptr);
X cl = tgetstr("cl", &termptr);
X cm = tgetstr("cm", &termptr);
X dc = tgetstr("dc", &termptr);
X dl = tgetstr("dl", &termptr);
X dm = tgetstr("dm", &termptr);
X ed = tgetstr("ed", &termptr);
X ei = tgetstr("ei", &termptr);
X ho = tgetstr("ho", &termptr);
X ic = tgetstr("ic", &termptr);
X il = tgetstr("al", &termptr);
X im = tgetstr("im", &termptr);
X ip = tgetstr("ip", &termptr);
X nd = tgetstr("nd", &termptr);
X vb = tgetstr("vb", &termptr);
X so = tgetstr("so", &termptr); /* inverse video on */
X se = tgetstr("se", &termptr); /* inverse video off */
X co = tgetnum("co");
X li = tgetnum("li");
X
X }
X
X done ()
X {
X unlink (tempfile);
X if (termchanged)
X #ifdef USG
X ioctl (0, TCSETAW, &osbuf);
X #else
X ioctl (0, TIOCSETP, &osbuf);
X #endif
X exit (0);
X }
X
X #ifndef USG
X onstop(signo)
X int signo;
X {
X ioctl (0, TIOCSETP, &osbuf);
X signal(signo, SIG_DFL);
X kill(0, signo);
X /* stop here until continued */
X signal(signo, onstop);
X ioctl (0, TIOCSETP, &sbuf);
X }
X
X stop ()
X {
X onstop (SIGTSTP);
X }
X #endif
X
X shellescape (buf)
X char *buf;
X {
X #ifdef USG
X ioctl (0, TCSETAW, &osbuf);
X signal (SIGINT, SIG_IGN);
X signal (SIGQUIT, SIG_IGN);
X #else
X ioctl (0, TIOCSETP, &osbuf);
X signal (SIGINT, 1);
X signal (SIGQUIT, 1);
X signal(SIGTTIN, SIG_DFL);
X signal(SIGTTOU, SIG_DFL);
X signal(SIGTSTP, SIG_DFL);
X #endif
X
X system (buf);
X
X #ifndef USG
X signal(SIGTTIN, onstop);
X signal(SIGTTOU, onstop);
X signal(SIGTSTP, onstop);
X #endif
X signal (SIGINT, done);
X signal (SIGQUIT, SIG_DFL);
X
X #ifdef USG
X ioctl (0, TCSETAW, &sbuf);
X #else
X ioctl (0, TIOCSETP, &sbuf);
X #endif
X printf ("\n-- Type space to continue --");
X getchar ();
X }
SHAR_EOF
if test 3781 -ne "`wc -c < 'term.c'`"
then
echo shar: error transmitting "'term.c'" '(should have been 3781 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'tree.c'" '(10534 characters)'
if test -f 'tree.c'
then
echo shar: will not over-write existing file "'tree.c'"
else
sed 's/^X //' << \SHAR_EOF > 'tree.c'
X /* -*- Mode:Text -*- */
X
X /*
X * tree.c - a hash style dictionary for user's personal words
X *
X * Pace Willisson, 1983
X * Hash support added by Geoff Kuenning, 1987
X */
X
X #include <stdio.h>
X #include <ctype.h>
X #include <sys/param.h>
X #include "ispell.h"
X #include "config.h"
X
X char *getenv();
X struct dent *lookup();
X char *upcase();
X
X static int cantexpand = 0; /* NZ if an expansion fails */
X static struct dent *htab = NULL; /* Hash table for our stuff */
X static int hsize = 0; /* Space available in hash table */
X static int hcount = 0; /* Number of items in hash table */
X
X /*
X * Hash table sizes. Prime is probably a good idea, though in truth I
X * whipped the algorithm up on the spot rather than looking it up, so
X * who knows what's really best? If we overflow the table, we just
X * use a double-and-add-1 algorithm.
X *
X * The strange pattern in the table is because this table is sometimes
X * used with huge dictionaries, and we want to get the table bigger fast.
X * 23003 just happens to be such that the original dict.191 will fill
X * the table to just under 70%. 31469 is similarly selected for dict.191
X * combined with /usr/dict/words. The other numbers are on 10000-word
X * intervals starting at 30000. (The table is still valid if MAXPCT
X * is changed, but the dictionary sizes will no longer fall on neat
X * boundaries).
X */
X static int goodsizes[] = {
X 53, 223, 907,
X #if ((BIG_DICT * 100) / MAXPCT) <= 23003
X 23003, /* ~16000 words */
X #endif
X #if ((BIG_DICT * 100) / MAXPCT) <= 31469
X 31469, /* ~22000 words */
X #endif
X #if ((BIG_DICT * 100) / MAXPCT) <= 42859
X 42859, /* ~30000 words */
X #endif
X #if ((BIG_DICT * 100) / MAXPCT) <= 57143
X 57143, /* ~40000 words */
X #endif
X 71429 /* ~50000 words */
X };
X
X struct dent *treeinsert();
X struct dent *tinsert();
X struct dent *treelookup();
X
X static char personaldict[MAXPATHLEN];
X static FILE *dictf;
X static newwords = 0;
X
X extern char *index ();
X extern struct dent *hashtbl;
X extern int hashsize;
X
X treeinit (p)
X char *p;
X {
X char *h;
X char *orig;
X char buf[BUFSIZ];
X struct dent *dp;
X
X /*
X ** if p exists and begins with '/' we don't really need HOME,
X ** but it's not very likely that HOME isn't set anyway.
X */
X orig = p;
X if (p == NULL)
X p = getenv (PDICTVAR);
X if ((h = getenv ("HOME")) == NULL)
X return;
X
X if (p == NULL)
X sprintf(personaldict,"%s/%s",h,DEFPDICT);
X else {
X if (*p == '/')
X strcpy(personaldict,p);
X else {
X /*
X ** The user gave us a relative pathname. How we
X ** interpret it depends on how it was given:
X **
X ** -p switch: as-is first, then $HOME/name
X ** PDICTVAR: $HOME/name first, then as-is
X **/
X if (orig == NULL)
X sprintf (personaldict, "%s/%s", h, p);
X else /* -p switch */
X strcpy (personaldict, p);
X }
X }
X
X if ((dictf = fopen (personaldict, "r")) == NULL) {
X /* The file doesn't exist. */
X if (p != NULL) {
X /* If pathname is relative, try another place */
X if (*p != '/') {
X if (orig == NULL)
X strcpy (personaldict, p);
X else /* -p switch */
X sprintf (personaldict, "%s/%s", h, p);
X dictf = fopen (personaldict, "r");
X }
X if (dictf == NULL) {
X (void) fprintf (stderr, "Couldn't open ");
X perror (p);
X if (*p != '/') {
X /*
X ** Restore the preferred default, so
X ** that output will go th the right
X ** place.
X */
X if (orig == NULL)
X sprintf (personaldict,
X "%s/%s", h, p);
X else /* -p switch */
X strcpy (personaldict, p);
X }
X }
X }
X /* If the name wasn't specified explicitly, we don't object */
X return;
X }
X
X while (fgets (buf, sizeof buf, dictf) != NULL) {
X int len = strlen (buf) - 1;
X
X if (buf [ len ] == '\n')
X buf [ len-- ] = '\0';
X if ((h = index (buf, '/')) != NULL)
X *h++ = '\0';
X dp = treeinsert (buf, 1);
X while (h != NULL) {
X switch (*h++) {
X case 'D':
X case 'd':
X dp->d_flag = 1;
X break;
X case 'G':
X case 'g':
X dp->g_flag = 1;
X break;
X case 'H':
X case 'h':
X dp->h_flag = 1;
X break;
X case 'J':
X case 'j':
X dp->j_flag = 1;
X break;
X case 'M':
X case 'm':
X dp->m_flag = 1;
X break;
X case 'N':
X case 'n':
X dp->n_flag = 1;
X break;
X case 'P':
X case 'p':
X dp->p_flag = 1;
X break;
X case 'R':
X case 'r':
X dp->r_flag = 1;
X break;
X case 'S':
X case 's':
X dp->s_flag = 1;
X break;
X case 'T':
X case 't':
X dp->t_flag = 1;
X break;
X case 'V':
X case 'v':
X dp->v_flag = 1;
X break;
X case 'X':
X case 'x':
X dp->x_flag = 1;
X break;
X case 'Y':
X case 'y':
X dp->y_flag = 1;
X break;
X case 'Z':
X case 'z':
X dp->z_flag = 1;
X break;
X default:
X fprintf (stderr,
X "Illegal flag in personal dictionary - %c (word %s)\n",
X h[-1], buf);
X break;
X }
X /* Exit loop if no more flags */
X if (*h++ != '/')
X break;
X }
X }
X
X fclose (dictf);
X
X newwords = 0;
X
X if (!lflag && !aflag && access (personaldict, 2) < 0)
X printf ("Warning: Cannot update personal dictionary (%s)\r\n", personaldict);
X }
X
X treeprint ()
X {
X register int i;
X register struct dent *dp;
X register struct dent *cp;
X
X printf ("(");
X for (i = 0; i < hsize; i++) {
X dp = &htab[i];
X if (dp->used) {
X for (cp = dp; cp != NULL; cp = cp->next)
X printf ("%s ", cp->word);
X }
X }
X printf (")");
X }
X
X struct dent *
X treeinsert (word, keep)
X char *word;
X {
X register int i;
X struct dent *dp;
X struct dent *olddp;
X struct dent *oldhtab;
X int oldhsize;
X char nword[BUFSIZ];
X
X strcpy (nword, word);
X upcase (nword);
X if ((dp = lookup (nword, strlen (nword), 0)) != NULL) {
X if (keep)
X dp->keep = 1;
X return dp;
X }
X /*
X * Expand hash table when it is MAXPCT % full.
X */
X if (!cantexpand && (hcount * 100) / MAXPCT >= hsize) {
X oldhsize = hsize;
X oldhtab = htab;
X for (i = 0; i < sizeof goodsizes / sizeof (goodsizes[0]); i++)
X if (goodsizes[i] > hsize)
X break;
X if (i >= sizeof goodsizes / sizeof goodsizes[0])
X hsize += hsize + 1;
X else
X hsize = goodsizes[i];
X htab = (struct dent *) calloc (hsize, sizeof (struct dent));
X if (htab == NULL) {
X (void) fprintf (stderr,
X "Ran out of space for personal dictionary\n");
X /*
X * Try to continue anyway, since our overflow
X * algorithm can handle an overfull (100%+) table,
X * and the malloc very likely failed because we
X * already have such a huge table, so small mallocs
X * for overflow entries will still work.
X */
X if (oldhtab == NULL)
X exit (1); /* No old table, can't go on */
X (void) fprintf (stderr,
X "Continuing anyway (with reduced performance).\n");
X cantexpand = 1; /* Suppress further messages */
X hsize = oldhsize; /* Put this back how the were */
X htab = oldhtab; /* ... */
X newwords = 1; /* And pretend it worked */
X return tinsert (nword, (struct dent *) NULL, keep);
X }
X /*
X * Re-insert old entries into new table
X */
X for (i = 0; i < oldhsize; i++) {
X dp = &oldhtab[i];
X if (oldhtab[i].used) {
X tinsert ((char *) NULL, dp, 0);
X dp = dp->next;
X while (dp != NULL) {
X tinsert ((char *) NULL, dp, 0);
X olddp = dp;
X dp = dp->next;
X free ((char *) olddp);
X }
X }
X }
X if (oldhtab != NULL)
X free ((char *) oldhtab);
X }
X newwords = 1;
X return tinsert (nword, (struct dent *) NULL, keep);
X }
X
X static
X struct dent *
X tinsert (word, proto, keep)
X char *word; /* One of word/proto must be null */
X struct dent *proto;
X {
X int hcode;
X register struct dent *hp; /* Next trial entry in hash table */
X struct dent *php; /* Previous value of hp, for chaining */
X
X if (word == NULL)
X word = proto->word;
X hcode = hash (word, strlen (word), hsize);
X php = NULL;
X hp = &htab[hcode];
X if (hp->used) {
X while (hp != NULL) {
X if (strcmp (word, hp->word) == 0) {
X if (keep)
X hp->keep = 1;
X return hp;
X }
X php = hp;
X hp = hp->next;
X }
X hp = (struct dent *) calloc (1, sizeof (struct dent));
X if (hp == NULL) {
X (void) fprintf (stderr,
X "Ran out of space for personal dictionary\n");
X exit (1);
X }
X }
X if (proto != NULL) {
X *hp = *proto;
X if (php != NULL)
X php->next = hp;
X hp->next = NULL;
X return &htab[hcode];
X } else {
X if (php != NULL)
X php->next = hp;
X hp->word = (char *) malloc (strlen (word) + 1);
X if (hp->word == NULL) {
X (void) fprintf (stderr,
X "Ran out of space for personal dictionary\n");
X exit (1);
X }
X hp->used = 1;
X hp->next = NULL;
X hp->d_flag = 0;
X hp->g_flag = 0;
X hp->h_flag = 0;
X hp->j_flag = 0;
X hp->m_flag = 0;
X hp->n_flag = 0;
X hp->p_flag = 0;
X hp->r_flag = 0;
X hp->s_flag = 0;
X hp->t_flag = 0;
X hp->v_flag = 0;
X hp->x_flag = 0;
X hp->y_flag = 0;
X hp->z_flag = 0;
X strcpy (hp->word, word);
X hp->keep = keep;
X hcount++;
X return (hp);
X }
X }
X
X struct dent *
X treelookup (word)
X char *word;
X {
X int hcode;
X register struct dent *hp;
X char nword[BUFSIZ];
X
X if (hsize <= 0)
X return NULL;
X strcpy (nword, word);
X hcode = hash (nword, strlen (nword), hsize);
X hp = &htab[hcode];
X while (hp != NULL && hp->used) {
X if (strcmp (nword, hp->word) == 0)
X break;
X hp = hp->next;
X }
X if (hp != NULL && hp->used)
X return hp;
X else
X return NULL;
X }
X
X treeoutput ()
X {
X if (newwords == 0)
X return;
X
X if ((dictf = fopen (personaldict, "w")) == NULL) {
X fprintf (stderr, "Can't create %s\r\n", personaldict);
X return;
X }
X
X toutput1 ();
X
X fclose (dictf);
X }
X
X static
X toutput1 ()
X {
X register struct dent *cent; /* Current entry */
X register struct dent *lent; /* Linked entry */
X
X for (cent = htab; cent - htab < hsize; cent++) {
X for (lent = cent; lent != NULL; lent = lent->next) {
X if (lent->used && lent->keep)
X toutput2 (lent);
X }
X }
X for (cent = hashtbl, lent = hashtbl + hashsize;
X cent < lent;
X cent++) {
X if (cent->used && cent->keep)
X toutput2 (cent);
X }
X }
X
X static
X toutput2 (cent)
X register struct dent *cent;
X {
X fprintf (dictf, "%s", cent->word);
X if (cent->d_flag)
X fprintf (dictf, "/D");
X if (cent->g_flag)
X fprintf (dictf, "/G");
X if (cent->h_flag)
X fprintf (dictf, "/H");
X if (cent->j_flag)
X fprintf (dictf, "/J");
X if (cent->m_flag)
X fprintf (dictf, "/M");
X if (cent->n_flag)
X fprintf (dictf, "/N");
X if (cent->p_flag)
X fprintf (dictf, "/P");
X if (cent->r_flag)
X fprintf (dictf, "/R");
X if (cent->s_flag)
X fprintf (dictf, "/S");
X if (cent->t_flag)
X fprintf (dictf, "/T");
X if (cent->v_flag)
X fprintf (dictf, "/V");
X if (cent->x_flag)
X fprintf (dictf, "/X");
X if (cent->y_flag)
X fprintf (dictf, "/Y");
X if (cent->z_flag)
X fprintf (dictf, "/Z");
X fprintf (dictf, "\n");
X }
X
X char *
X upcase (s)
X register char *s;
X {
X register char *os = s;
X
X while (*s) {
X if (mylower (*s))
X *s = toupper (*s);
X s++;
X }
X return (os);
X }
SHAR_EOF
if test 10534 -ne "`wc -c < 'tree.c'`"
then
echo shar: error transmitting "'tree.c'" '(should have been 10534 characters)'
fi
fi # end of overwriting check
# End of shell archive
exit 0
--
Geoff Kuenning
{hplabs,ihnp4}!trwrb!desint!geoff
More information about the Comp.sources.unix
mailing list