|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T i
Length: 16239 (0x3f6f) Types: TextFile Names: »ispell.c«
└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki └─⟦this⟧ »EUUGD11/euug-87hel/sec1/ispell/ispell.c«
/* -*- 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. * * 1987, Robert McQueer, added: * -w option & handling of extra legal word characters * -d option for alternate dictionary file * -p option & WORDLIST variable for alternate personal dictionary * -x option to suppress .bak files. * 8 bit text & config.h parameters * 1987, Geoff Kuenning, added: * -c option for creating suffix suggestions from raw words * suffixes in personal dictionary file * hashed personal dictionary file */ #include <stdio.h> #include <ctype.h> #include <sys/param.h> #include "ispell.h" #include "config.h" FILE *infile; FILE *outfile; char hashname[MAXPATHLEN]; extern struct dent *treeinsert(); /* ** we use extended character set range specifically to allow intl. ** character set characters. We are being REALLY paranoid about indexing ** this array - explicitly cast into unsigned INTEGER, then mask ** If NO8BIT is set, text will be masked to ascii range. */ static int Trynum; #ifdef NO8BIT static char Try[128]; static char Checkch[128]; #define iswordch(X) (Checkch[((unsigned)(X))&0x7f]) #else static char Try[256]; static char Checkch[256]; #define iswordch(X) (Checkch[((unsigned)(X))&0xff]) #endif 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 ("L Look up words in system dictionary.\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 confirmation. "); 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 cflag = 0; int lflag = 0; int aflag = 0; int fflag = 0; #ifndef USG int sflag = 0; #endif int xflag = 0; char *askfilename; static char *Cmd; usage () { fprintf (stderr, "Usage: %s [-dfile | -pfile | -wchars | -x] file .....\n",Cmd); fprintf (stderr, " %s [-dfile | -pfile | -wchars] -l\n",Cmd); #ifdef USG fprintf (stderr, " %s [-dfile | -pfile | -ffile | -s] -a\n",Cmd); #else fprintf (stderr, " %s [-dfile | -pfile | -ffile] -a\n",Cmd); #endif fprintf (stderr, " %s [-wchars] -c\n"); exit (1); } static initckch() { int c; Trynum = 0; #ifdef NO8BIT for (c = 0; c < 128; ++c) { #else for (c = 0; c < 256; ++c) { #endif if (myalpha((char) c)) { Checkch[c] = (char) 1; if (myupper((char) c)) { Try[Trynum] = (char) c; ++Trynum; } } else Checkch[c] = (char) 0; } } main (argc, argv) char **argv; { char *p; char *cpd; char num[4]; unsigned mask; Cmd = *argv; initckch(); sprintf(hashname,"%s/%s",LIBDIR,DEFHASH); cpd = NULL; argv++; argc--; while (argc && **argv == '-') { switch ((*argv)[1]) { case 'a': aflag++; break; case 'c': cflag++; lflag++; break; case 'x': xflag++; break; case 'f': fflag++; p = (*argv)+2; if (*p == '\0') { argv++; argc--; if (argc == 0) usage (); p = *argv; } askfilename = p; break; case 'l': lflag++; break; #ifndef USG case 's': sflag++; break; #endif case 'p': cpd = (*argv)+2; if (*cpd == '\0') { argv++; argc--; if (argc == 0) usage (); cpd = *argv; } break; case 'd': p = (*argv)+2; if (*p == '\0') { argv++; argc--; if (argc == 0) usage (); p = *argv; } if (*p == '/') strcpy(hashname,p); else sprintf(hashname,"%s/%s",LIBDIR,p); break; case 'w': num[3] = '\0'; #ifdef NO8BIT mask = 0x7f; #else mask = 0xff; #endif p = (*argv)+2; if (*p == '\0') { argv++; argc--; if (argc == 0) usage (); p = *argv; } while (Trynum <= mask && *p != '\0') { if (*p != 'n') { Checkch[((unsigned)(*p))&mask] = (char) 1; Try[Trynum] = *p & mask; ++p; } else { ++p; num[0] = *p; ++p; num[1] = *p; ++p; num[2] = *p; ++p; Try[Trynum] = atoi(num) & mask; Checkch[atoi(num)&mask] = (char) 1; } ++Trynum; } break; default: usage(); } argv++; argc--; } if (!argc && !lflag && !aflag) usage (); if (linit () < 0) exit (0); treeinit (cpd); 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; } strcpy(tempfile, TEMPNAME); 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); if (!cflag) 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 we can't write new, preserve .bak regardless of xflag */ 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); if (xflag) unlink(bakfile); } 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 && !myspace (*currentchar)) { if (!lflag) putc (*currentchar, outfile); currentchar++; } if (*currentchar == 0) { if (!lflag) putc ('\n', outfile); continue; } } while (1) { while (*currentchar && !iswordch(*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 (iswordch(*currentchar) || (*currentchar == '\'' && iswordch(*(currentchar + 1)))) *p++ = *currentchar++; *p = 0; if (lflag) { if (!good (token) && !cflag) printf ("%s\r\n", token); } else { if (!quit) correct (token, ¤tchar); } if (!lflag) fprintf (outfile, "%s", token); } if (!lflag) 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)) { #ifndef USG case 'Z' & 037: stop (); erase (); goto checkagain; #endif 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 'l': case 'L': { char buf[100]; move (18, 0); printf ("Lookup string ('*' is wildcard): "); if (getline (buf) == NULL) { putchar (7); erase (); goto checkagain; } printf ("\r\n\r\n"); lookharder (buf); erase (); goto checkagain; } 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, j, c, n; char newword[BUFSIZ]; n = strlen (word); strcpy (newword, word); for (i = 0; i < n; i++) { for (j=0; j < Trynum; ++j) { newword[i] = Try[j]; 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; int i; 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 (i=0; i < Trynum; ++i) { *r = Try[i]; 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 (myupper (pattern[0])) { if (myupper (pattern[1])) { for (p = word, q = newword; *p; p++, q++) { if (mylower (*p)) *q = toupper (*p); else *q = *p; } *q = 0; } else { if (mylower (word [0])) newword[0] = toupper (word[0]); else newword[0] = word[0]; for (p = word + 1, q = newword + 1; *p; p++, q++) if (myupper (*p)) *q = tolower (*p); else *q = *p; *q = 0; } } else { for (p = word, q = newword; *p; p++, q++) if (myupper (*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"); } } #ifndef USG if (sflag) { stop (); if (fflag) { rewind (stdout); creat (askfilename, 0666); } } #endif } } copyout(cc, cnt) char **cc; { while (--cnt >= 0) { if (*(*cc) == 0) break; if (!lflag) putc (*(*cc), outfile); (*cc)++; } } lookharder(string) char *string; { char cmd[150]; char *g, *s, grepstr[100]; int wild = 0; g = grepstr; for (s = string; *s != '\0'; s++) if (*s == '*') { wild++; *g++ = '.'; *g++ = '*'; } else *g++ = *s; *g = '\0'; if (grepstr[0]) { #ifdef LOOK if (wild) /* string has wild card characters */ sprintf (cmd, "%s '^%s$' %s", EGREPCMD, grepstr, WORDS); else /* no wild, use look(1) */ sprintf (cmd, "/usr/bin/look -df %s %s", grepstr, WORDS); #else sprintf (cmd, "%s '^%s$' %s", EGREPCMD, grepstr, WORDS); #endif shellescape (cmd); } }