home *** CD-ROM | disk | FTP | other *** search
- /* -*- Mode:Text -*- */
- /*
- * ispell.c - An interactive spelling corrector.
- *
- * Copyright (c), 1983, by Pace Willisson
- * Permission for non-profit use is hereby granted.
- * All other rights reserved.
- */
-
- #include <stdio.h>
- #include <ctype.h>
- #include "ispell.h"
-
- #define NOPARITY 0x7f
-
- FILE *infile;
- FILE *outfile;
-
- givehelp ()
- {
- erase ();
- printf ("Whenever a word is found that is not in the dictionary,\r\n");
- printf ("it is printed on the first line of the screen. If the dictionary\r\n");
- printf ("contains any similar words, they are listed with a single digit\r\n");
- printf ("next to each one. You have the option of replacing the word\r\n");
- printf ("completely, or choosing one of the suggested words.\r\n");
- printf ("\r\n");
- printf ("Commands are:\r\n\r\n");
- printf ("R Replace the misspelled word completely.\r\n");
- printf ("Space Accept the word this time only\r\n");
- printf ("A Accept the word for the rest of this file.\r\n");
- printf ("I Accept the word, and put it in your private dictionary.\r\n");
- printf ("0-9 Replace with one of the suggested words.\r\n");
- printf ("Q Write the rest of this file, ignoring misspellings, ");
- printf ( "and start next file.\r\n");
- printf ("X Exit immediately. Asks for conformation. ");
- printf ( "Leaves file unchanged.\r\n");
- printf ("! Shell escape.\r\n");
- printf ("^L Redraw screen.\r\n");
- printf ("\r\n\r\n");
- printf ("-- Type space to continue --");
- fflush (stdout);
- getchar ();
- }
-
-
- char *getline();
-
- int lflag = 0;
- int aflag = 0;
- int fflag = 0;
- int sflag = 0;
-
- char *askfilename;
-
- usage ()
- {
- fprintf (stderr, "Usage: spell [ file ... | -a | -l | -f file | -s ]\n");
- exit (1);
- }
-
- main (argc, argv)
- char **argv;
- {
- argv++;
- argc--;
- while (argc && **argv == '-') {
- switch ((*argv)[1]) {
- case 'a':
- aflag++;
- break;
- case 'f':
- fflag++;
- argv++; argc--;
- if (argc == 0)
- usage ();
- askfilename = *argv;
- break;
- case 'l':
- lflag++;
- break;
- case 's':
- sflag++;
- break;
- }
- argv++; argc--;
- }
-
- if (!argc && !lflag && !aflag)
- usage ();
-
- if (linit () < 0)
- exit (0);
-
- treeinit ();
-
- if (aflag) {
- askmode ();
- exit (0);
- }
-
- if (lflag) {
- infile = stdin;
- checkfile ();
- exit (0);
- }
-
- terminit ();
-
- while (argc--)
- dofile (*argv++);
-
- done ();
- }
-
- char firstbuf[BUFSIZ], secondbuf[BUFSIZ];
- char *currentchar;
- char token[BUFSIZ];
-
- int quit;
-
- char *currentfile = NULL;
-
- dofile (filename)
- char *filename;
- {
- int c;
- char bakfile[256];
-
- currentfile = filename;
-
- if ((infile = fopen (filename, "r")) == NULL) {
- fprintf (stderr, "Can't open %s\r\n", filename);
- sleep (2);
- return;
- }
-
- if (access (filename, 2) < 0) {
- fprintf (stderr, "Can't write to %s\r\n", filename);
- sleep (2);
- return;
- }
-
- #ifndef AMIGA
- strcpy (tempfile, "/usr/tmp/spellXXXXXX");
- #else
- strcpy(tempfile, TMPDIR);
-
- #if USEDEVICES
- strcat(tempfile, "ispellXXXXXX");
- #else
- strcat(tempfile, "/ispellXXXXXX");
- #endif
-
- #endif
- mktemp (tempfile);
- if ((outfile = fopen (tempfile, "w")) == NULL) {
- fprintf (stderr, "Can't create %s\r\n", tempfile);
- sleep (2);
- return;
- }
-
- quit = 0;
-
- checkfile ();
-
- fclose (infile);
- fclose (outfile);
-
- treeoutput ();
-
- if ((infile = fopen (tempfile, "r")) == NULL) {
- fprintf (stderr, "tempoary file disappeared (%s)\r\n", tempfile);
- sleep (2);
- return;
- }
-
- sprintf(bakfile, "%s.bak", filename);
- if(link(filename, bakfile) == 0)
- unlink(filename);
-
- if ((outfile = fopen (filename, "w")) == NULL) {
- fprintf (stderr, "can't create %s\r\n", filename);
- sleep (2);
- return;
- }
-
- while ((c = getc (infile)) != EOF)
- putc (c, outfile);
-
- fclose (infile);
- fclose (outfile);
-
- unlink (tempfile);
- }
-
- checkfile ()
- {
- int c;
- char *p;
- int len;
-
- secondbuf[0] = 0;
- currentchar = secondbuf;
-
- while (1) {
- strcpy (firstbuf, secondbuf);
- if (quit) { /* quit can't be set in l mode */
- while (fgets (secondbuf, sizeof secondbuf, infile) != NULL)
- fputs (secondbuf, outfile);
- break;
- }
-
- if (fgets (secondbuf, sizeof secondbuf, infile) == NULL)
- break;
- currentchar = secondbuf;
-
- len = strlen (secondbuf) - 1;
- if (secondbuf [ len ] == '\n')
- secondbuf [ len ] = 0;
-
- /* if this is a formatter command, skip over it */
- if (*currentchar == '.') {
- while (*currentchar && !isspace (*currentchar)) {
- if (!lflag)
- putc (*currentchar, outfile);
- currentchar++;
- }
- if (*currentchar == 0) {
- putc ('\n', outfile);
- continue;
- }
- }
-
- while (1) {
- while (*currentchar && !isalpha (*currentchar)) {
- /* formatting escape sequences */
- if (*currentchar == '\\') {
- if(currentchar[1] == 'f') {
- /* font change: \fX */
- copyout(¤tchar, 3);
- continue;
- }
- else if(currentchar[1] == 's') {
- /* size change */
- if(currentchar[2] < 6 &&
- currentchar[2] != 0)
- /* two digit size */
- copyout(¤tchar, 4);
- else
- /* one digit size */
- copyout(¤tchar, 3);
- continue;
- }
- else if(currentchar[1] == '(') {
- /* extended char set escape: \(XX */
- copyout(¤tchar, 4);
- continue;
- }
- }
-
- if (!lflag)
- putc (*currentchar, outfile);
- currentchar++;
- }
-
- if (*currentchar == 0)
- break;
-
- p = token;
- while (isalpha (*currentchar))
- *p++ = *currentchar++;
- *p = 0;
- if (lflag) {
- if (!good (token))
- printf ("%s\r\n", token);
- } else {
- if (!quit)
- correct (token, ¤tchar);
- }
- if (!lflag)
- fprintf (outfile, "%s", token);
- }
- putc ('\n', outfile);
- }
- }
-
- char possibilities[10][BUFSIZ];
- int pcount;
-
- correct (token, currentchar)
- char *token;
- char **currentchar;
- {
- int c;
- int i;
- char *p;
- int len;
- char *begintoken;
-
- len = strlen (token);
- begintoken = *currentchar - len;
-
- checkagain:
- if (good (token))
- return;
-
- erase ();
- printf (" %s", token);
- if (currentfile)
- printf (" File: %s", currentfile);
- printf ("\r\n\r\n");
-
- makepossibilities (token);
-
- for (i = 0; i < 10; i++) {
- if (possibilities[i][0] == 0)
- break;
- printf ("%d: %s\r\n", i, possibilities[i]);
- }
-
- move (15, 0);
- printf ("%s\r\n", firstbuf);
-
- for (p = secondbuf; p != begintoken; p++)
- putchar (*p);
- inverse ();
- for (i = strlen (token); i > 0; i--)
- putchar (*p++);
- normal ();
- while (*p)
- putchar (*p++);
- printf ("\r\n");
-
- while (1) {
- switch (c = (getchar () & NOPARITY)) {
- case 'Z' & 037:
- stop ();
- erase ();
- goto checkagain;
- case ' ':
- erase ();
- return;
- case 'x': case 'X':
- printf ("Are you sure you want to throw away your changes? ");
- c = (getchar () & NOPARITY);
- if (c == 'y' || c == 'Y') {
- erase ();
- done ();
- }
- putchar (7);
- goto checkagain;
- case 'i': case 'I':
- treeinsert (token, 1);
- erase ();
- return;
- case 'a': case 'A':
- treeinsert (token, 0);
- erase ();
- return;
- case 'L' & 037:
- goto checkagain;
- case '?':
- givehelp ();
- goto checkagain;
- case '!':
- {
- char buf[200];
- move (18, 0);
- putchar ('!');
- if (getline (buf) == NULL) {
- putchar (7);
- erase ();
- goto checkagain;
- }
- printf ("\r\n");
- shellescape (buf);
- erase ();
- goto checkagain;
- }
- case 'r': case 'R':
- move (18, 0);
- printf ("Replace with: ");
- if (getline (token) == NULL) {
- putchar (7);
- erase ();
- goto checkagain;
- }
- inserttoken (secondbuf, begintoken, token, currentchar);
- erase ();
- goto checkagain;
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- if (possibilities[c - '0'][0] != 0) {
- strcpy (token, possibilities[c - '0']);
- inserttoken (secondbuf, begintoken, token, currentchar); erase ();
- return;
- }
- putchar (7);
- break;
- case 'q': case 'Q':
- quit = 1;
- erase ();
- return;
- default:
- putchar (7);
- break;
- }
- }
- }
-
- inserttoken (buf, start, token, currentchar)
- char *buf, *start, *token;
- char **currentchar;
- {
- char copy[BUFSIZ];
- char *p, *q;
-
- strcpy (copy, buf);
-
- for (p = buf, q = copy; p != start; p++, q++)
- *p = *q;
- while (*token)
- *p++ = *token++;
- q += *currentchar - start;
- *currentchar = p;
- while (*p++ = *q++)
- ;
- }
-
-
- makepossibilities (word)
- char word[];
- {
- int i;
-
- for (i = 0; i < 10; i++)
- possibilities[i][0] = 0;
- pcount = 0;
-
- if (pcount < 10) wrongletter (word);
- if (pcount < 10) extraletter (word);
- if (pcount < 10) missingletter (word);
- if (pcount < 10) transposedletter (word);
-
- }
-
- char *cap();
-
- insert (word)
- char *word;
- {
- int i;
-
- for (i = 0; i < pcount; i++)
- if (strcmp (possibilities[i], word) == 0)
- return (0);
-
- strcpy (possibilities[pcount++], word);
- if (pcount >= 10)
- return (-1);
- else
- return (0);
- }
-
- wrongletter (word)
- char word[];
- {
- int i, c, n;
- char newword[BUFSIZ];
-
- n = strlen (word);
- strcpy (newword, word);
-
- for (i = 0; i < n; i++) {
- for (newword[i] = 'A'; newword[i] <= 'Z'; newword[i]++) {
- if (good (newword)) {
- if (insert (cap (newword, word)) < 0)
- return;
- }
- }
- newword[i] = word[i];
- }
- }
-
- extraletter (word)
- char word[];
- {
- char newword[BUFSIZ], *p, *s, *t;
-
- if (strlen (word) < 3)
- return;
-
- for (p = word; *p; p++) {
- for (s = word, t = newword; *s; s++)
- if (s != p)
- *t++ = *s;
- *t = 0;
- if (good (newword)) {
- if (insert (cap (newword, word)) < 0)
- return;
- }
- }
- }
-
- missingletter (word)
- char word[];
- {
- char newword[BUFSIZ], *p, *r, *s, *t;
-
- for (p = word; p == word || p[-1]; p++) {
- for (s = newword, t = word; t != p; s++, t++)
- *s = *t;
- r = s++;
- while (*t)
- *s++ = *t++;
- *s = 0;
- for (*r = 'A'; *r <= 'Z'; (*r)++) {
- if (good (newword)) {
- if (insert (cap (newword, word)) < 0)
- return;
- }
- }
- }
- }
-
- transposedletter (word)
- char word[];
- {
- char newword[BUFSIZ];
- int t;
- char *p;
-
- strcpy (newword, word);
- for (p = newword; p[1]; p++) {
- t = p[0];
- p[0] = p[1];
- p[1] = t;
- if (good (newword)) {
- if (insert (cap (newword, word)) < 0)
- return;
- }
- t = p[0];
- p[0] = p[1];
- p[1] = t;
- }
- }
-
- char *
- cap (word, pattern)
- char word[], pattern[];
- {
- static char newword[BUFSIZ];
- char *p, *q;
-
- if (*word == 0)
- return;
-
- if (isupper (pattern[0])) {
- if (isupper (pattern[1])) {
- for (p = word, q = newword; *p; p++, q++) {
- if (islower (*p))
- *q = toupper (*p);
- else
- *q = *p;
- }
- *q = 0;
- } else {
- if (islower (word [0]))
- newword[0] = toupper (word[0]);
- else
- newword[0] = word[0];
-
- for (p = word + 1, q = newword + 1; *p; p++, q++)
- if (isupper (*p))
- *q = tolower (*p);
- else
- *q = *p;
-
- *q = 0;
- }
- } else {
- for (p = word, q = newword; *p; p++, q++)
- if (isupper (*p))
- *q = tolower (*p);
- else
- *q = *p;
- *q = 0;
- }
- return (newword);
- }
-
- char *
- getline (s)
- char *s;
- {
- char *p;
- int c;
-
- p = s;
-
- while (1) {
- c = (getchar () & NOPARITY);
- if (c == '\\') {
- putchar ('\\');
- c = (getchar () & NOPARITY);
- backup ();
- putchar (c);
- *p++ = c;
- } else if (c == ('G' & 037)) {
- return (NULL);
- } else if (c == '\n' || c == '\r') {
- *p = 0;
- return (s);
- } else if (c == erasechar) {
- if (p != s) {
- p--;
- backup ();
- putchar (' ');
- backup ();
- }
- } else if (c == killchar) {
- while (p != s) {
- p--;
- backup ();
- putchar (' ');
- backup ();
- }
- } else {
- *p++ = c;
- putchar (c);
- }
- }
- }
-
- askmode ()
- {
- char buf[BUFSIZ];
- int i;
-
- if (fflag) {
- if (freopen (askfilename, "w", stdout) == NULL) {
- fprintf (stderr, "Can't create %s\n", askfilename);
- exit (1);
- }
- }
-
- setbuf (stdin, NULL);
- setbuf (stdout, NULL);
-
- while (gets (buf) != NULL) {
- if (good (buf)) {
- if (rootword[0] == 0) {
- printf ("*\n"); /* perfect match */
- } else {
- printf ("+ %s\n", rootword);
- }
- } else {
- makepossibilities (buf);
- if (possibilities[0][0]) {
- printf ("& ");
- for (i = 0; i < 10; i++) {
- if (possibilities[i][0] == 0)
- break;
- printf ("%s ", possibilities[i]);
- }
- printf ("\n");
- } else {
- printf ("#\n");
- }
- }
- if (sflag) {
- stop ();
- if (fflag) {
- rewind (stdout);
- creat (askfilename, 0666);
- }
- }
- }
- }
-
-
- copyout(cc, cnt)
- char **cc;
- {
- while (--cnt >= 0) {
- if (*(*cc) == 0)
- break;
- if (!lflag)
- putc (*(*cc), outfile);
- (*cc)++;
- }
-
- }
-