geoff@desint.UUCP (03/29/87)
: : 'See below (file Patch1) for explanations and instructions' : #! /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: # Patch1 # icombine.c # munchlist.X # This archive created: Sun Mar 29 01:06:36 1987 export PATH; PATH=/bin:$PATH echo shar: extracting "'Patch1'" '(37715 characters)' if test -f 'Patch1' then echo shar: will not over-write existing file "'Patch1'" else sed 's/^X //' << \SHAR_EOF > 'Patch1' X X This is patch number 1 for the version of ispell I posted recently. My X thanks to the many people (listed in the man page) who submitted changes, X fixes, and improvements, and my apologies to Walt Buehring, whom I X inadvertently failed to credit fully in my previous posting. X X This patch consists of three parts: this file (Patch1), a new program named X icombine.c (thanks to Gary Puckering), and a replacement for the X "munchlist.sh" shell script (now called "munchlist.X" thanks to Rich Salz's X configurability improvements). X X To apply this patch: X X (1) Unshar this file by piping it through /bin/sh X (2) Remove "munchlist.sh" X (3) Type "patch < Patch1" in the ispell directory. X (4) Move all ispell.words files to ".ispell_words" after rebuilding. X X Improvements added in this patch: X X (1) Configuration is simpler. You still must edit both the Makefile X and config.h, but each variable is defined in only one place, so X there are no consistency worries. There are also a few X explanatory comments. (Rich Salz) X (2) The LOOK command is now configurable. If LOOK is defined, it is X the command to use for lookup. X (2) The install dependency now installs the manual. (Rich Salz) X (3) Buildhash is a hair faster. (Rich Salz) X (4) The dictionary file does not require slashes separating each flag. X Thus, "PLOT/G/S" can now be written "PLOT/GS". This saves a bit X of dictionary space. This format is not required, but is generated X by ispell (for the personal dictionary), icombine, and munchlist. X (Rich Salz) X (5) The default personal dictionary is now a dot file, ".ispell_words". X (6) Ispell will now offer up to 100 possible corrections, instead of X only 10. Most corrections still require only a single keystroke. X (7) Ispell now makes use of the extra lines on tall terminals. X (8) Perry Smith's region support for ispell.el has been reintegrated. X (9) Ispell now sorts the list of possible corrections. X (10) The -t switch selects TeX mode, wherein TeX-style constructs are X skipped. (Don Kark, Greg Schaffer) X (11) The troff processing has been improved somewhat so that string X and number defines are ignored. (Gary Puckering) X X Problems fixed by this patch: X X (1) The Makefile wouldn't find buildhash if "." wasn't in the path. X (Rich Salz) X (2) On BSD systems, param.h gets types.h, so buildhash.c can't X include both. (Jim Knutson) X (3) Buildhash was neglecting to initialize the "keep" flag. (Don Kark) X (4) In config.h (now config.X), there was an ifdef that used SYSV X instead of USG. (Dave Mason) X (5) Ispell's temp file was named "spell*" and was in /usr/tmp, not /tmp. X (Rich Salz) X (6) The s_ending routine in good.c had an unintended, but harmless, X fallthrough in one of the case statements. (Greg Schaffer) X (7) If the dictionary has more than 32K words, the hash routine could X generate a negative hash code. X (8) Ispell no longer generates a spurious CR on every line in -l mode. X (Gary Puckering) X (9) A missing type declaration in lookup.c could cause bugs on X pointer != int machines. (Jim Knutson, Rich Salz, Bill Randle) X (10) The startup code didn't set ospeed, so padding didn't work. X (Perry Smith) X X X X Index: Makefile X X *** Makefile.old Sun Mar 29 00:09:29 1987 X --- Makefile Sun Mar 29 00:09:32 1987 X *************** X *** 2,4 X X ! # Look over config.h before building. X # X X --- 2,4 ----- X X ! # Look over config.X before building. X # X *************** X *** 4,6 X # X ! # LIBDIR, DEFHASH, DEFDICT should match definitions in config.h. X # X X --- 4,7 ----- X # X ! # You may want to edit BINDIR, LIBDIR, DEFHASH, DEFDICT, MANDIR, and X ! # MANEXT below; the Makefile will update all other files to match. X # X *************** X *** 6,7 X # X # The ifdef NO8BIT may be used if 8 bit extended text characters X X --- 7,10 ----- X # X + # On USG systems, add -DUSG to CFLAGS. X + # X # The ifdef NO8BIT may be used if 8 bit extended text characters X *************** X *** 15,16 X CFLAGS = -O X BINDIR = /usr/local/bin X X --- 18,20 ----- X CFLAGS = -O X + # BINDIR, LIBDIR, DEFHASH, DEFDICT, MANDIR, MANEXT X BINDIR = /usr/local/bin X *************** X *** 19,20 X DEFDICT = dict.191 X X X --- 23,27 ----- X DEFDICT = dict.191 X + MANDIR = /usr/man/u_man/man1 X + MANEXT = .1l X + SHELL = /bin/sh X X *************** X *** 22,24 X TERMLIB = -ltermlib X - all: buildhash ispell $(DEFHASH) X X X --- 29,30 ----- X TERMLIB = -ltermlib X X *************** X *** 24,25 X X ispell.hash: buildhash $(DEFDICT) X X --- 30,33 ----- X X + all: buildhash ispell icombine munchlist $(DEFHASH) X + X ispell.hash: buildhash $(DEFDICT) X *************** X *** 25,27 X ispell.hash: buildhash $(DEFDICT) X ! buildhash X X X --- 33,35 ----- X ispell.hash: buildhash $(DEFDICT) X ! ./buildhash $(DEFDICT) $(DEFHASH) X X *************** X *** 27,35 X X ! install: buildhash ispell $(DEFHASH) X ! cp ispell ${BINDIR}/ispell X ! cp munchlist.sh $(BINDIR)/munchlist X ! cp ispell.hash ${LIBDIR}/${DEFHASH} X ! cp expand1.sed expand2.sed $(LIBDIR) X ! chmod 755 ${BINDIR}/ispell $(BINDIR)/munchlist X ! chmod 644 ${LIBDIR}/$(DEFHASH) $(LIBDIR)/expand1.sed \ X $(LIBDIR)/expand2.sed X X --- 35,43 ----- X X ! install: all X ! cp ispell $(BINDIR)/ispell X ! cp munchlist $(BINDIR)/munchlist X ! cp ispell.hash $(LIBDIR)/$(DEFHASH) X ! cp expand1.sed expand2.sed icombine $(LIBDIR) X ! chmod 755 $(BINDIR)/ispell $(BINDIR)/munchlist $(LIBDIR)/icombine X ! chmod 644 $(LIBDIR)/$(DEFHASH) $(LIBDIR)/expand1.sed \ X $(LIBDIR)/expand2.sed X *************** X *** 35,36 X $(LIBDIR)/expand2.sed X X X --- 43,45 ----- X $(LIBDIR)/expand2.sed X + cp ispell.1 $(MANDIR)/ispell$(MANEXT) X X *************** X *** 37,39 X buildhash: buildhash.o hash.o X ! cc -o buildhash buildhash.o hash.o X X X --- 46,48 ----- X buildhash: buildhash.o hash.o X ! $(CC) $(CFLAGS) -o buildhash buildhash.o hash.o X X *************** X *** 39,43 X X ! ispell: ispell.o term.o good.o lookup.o hash.o tree.o X ! cc $(CFLAGS) -o ispell ispell.o term.o good.o lookup.o \ X ! hash.o tree.o $(TERMLIB) X X X --- 48,51 ----- X X ! icombine: icombine.c X ! $(CC) $(CFLAGS) -o icombine icombine.c X X *************** X *** 43,44 X X clean: X X --- 51,67 ----- X X + munchlist: munchlist.X Makefile X + sed -e 's@!!LIBDIR!!@$(LIBDIR)@' -e 's@!!DEFDICT!!@$(DEFDICT)@' \ X + <munchlist.X >munchlist X + chmod +x munchlist X + X + OBJS=ispell.o term.o good.o lookup.o hash.o tree.o X + ispell: $(OBJS) X + cc $(CFLAGS) -o ispell $(OBJS) $(TERMLIB) X + X + $(OBJS) buildhash.o: config.h X + X + config.h: config.X Makefile X + sed -e 's@!!LIBDIR!!@$(LIBDIR)@' -e 's@!!DEFDICT!!@$(DEFDICT)@' \ X + -e 's@!!DEFHASH!!@$(DEFHASH)@' <config.X >config.h X + X clean: X *************** X *** 45,46 X rm -f *.o buildhash ispell core a.out mon.out hash.out \ X ! *.stat *.cnt X X --- 68,69 ----- X rm -f *.o buildhash ispell core a.out mon.out hash.out \ X ! *.stat *.cnt munchlist config.h X X X Index: buildhash.c X X *** buildhash.c.old Sun Mar 29 00:09:44 1987 X --- buildhash.c Sun Mar 29 00:09:48 1987 X *************** X *** 8,9 X #include <stdio.h> X #include <sys/types.h> X X --- 8,10 ----- X #include <stdio.h> X + #ifdef USG X #include <sys/types.h> X *************** X *** 9,10 X #include <sys/types.h> X #include <sys/stat.h> X X --- 10,12 ----- X #include <sys/types.h> X + #endif X #include <sys/stat.h> X *************** X *** 202,204 X while (fgets (lbuf, sizeof lbuf, dictf) != NULL) { X ! if (i % 1000 == 0) { X printf ("%d ", i); X X --- 204,206 ----- X while (fgets (lbuf, sizeof lbuf, dictf) != NULL) { X ! if ((i & 1023) == 0) { X printf ("%d ", i); X *************** X *** 269,270 X d->m_flag = 0; X X X --- 271,273 ----- X d->m_flag = 0; X + d->keep = 0; X X *************** X *** 282,284 X p++; X ! while (*p != NULL) { X switch (*p) { X X --- 285,287 ----- X p++; X ! while (*p != '\0' && *p != '\n') { X switch (*p) { X *************** X *** 299,301 X case 0: X ! fprintf (stderr, "no key word %s\n", lbuf); X continue; X X --- 302,304 ----- X case 0: X ! fprintf (stderr, "no flags on word %s\n", lbuf); X continue; X *************** X *** 307,314 X p++; X ! if (*p != '/' && *p != NULL && *p != '\n') { X ! fprintf (stderr, "bad format %s (%c 0%o)\n", X ! lbuf, *p, *p); X ! break; X ! } X ! if (*p) X p++; X X --- 310,312 ----- X p++; X ! if (*p == '/') /* Handle old-format dictionaries too */ X p++; X *************** X *** 314,316 X p++; X - X } X X --- 312,313 ----- X p++; X } X *************** X *** 332,337 X X ! i = 0; X ! while (fgets (buf, sizeof buf, d) != NULL) { X ! i++; X ! if (i % 1000 == 0) { X printf ("%d ", i); X X --- 329,332 ----- X X ! for (i = 0; fgets (buf, sizeof buf, d); ) X ! if ((++i & 1023) == 0) { X printf ("%d ", i); X *************** X *** 339,341 X } X - } X fclose (d); X X --- 334,335 ----- X } X fclose (d); X X X Index: config.X X X *** config.X.old Sun Mar 29 00:10:04 1987 X --- config.X Sun Mar 29 00:10:08 1987 X *************** X *** 1,2 X /* X ** library directory for hash table(s) / default hash table name X X --- 1,16 ----- X /* X + * This is the configuration file for ispell. Thanks to Bob McQueer X + * for creating it and making the necessary changes elsewhere to X + * support it. X + * Look through this file from top to bottom, and edit anything that X + * needs editing. There are also five or six variables in the X + * Makefile that you must edit. Note that the Makefile edits this X + * file (config.X) to produce config.h. If you are looking at X + * config.h, you're in the wrong file. X + * X + * Don't change the funny-looking lines with !!'s in them; see the X + * Makefile! X + */ X + X + /* X ** library directory for hash table(s) / default hash table name X *************** X *** 6,9 X */ X ! #define LIBDIR "/usr/local/lib" X ! #define DEFHASH "ispell.hash" X X X --- 20,23 ----- X */ X ! #define LIBDIR "!!LIBDIR!!" X ! #define DEFHASH "!!DEFHASH!!" X X *************** X *** 9,11 X X ! #ifdef SYSV X #define index strchr X X --- 23,25 ----- X X ! #ifdef USG X #define index strchr X *************** X *** 17,19 X /* default word list */ X ! #define DEFPDICT "ispell.words" X X X --- 31,33 ----- X /* default word list */ X ! #define DEFPDICT ".ispell_words" X X *************** X *** 20,22 X /* mktemp template for temporary file - MUST contain 6 consecutive X's */ X ! #define TEMPNAME "/usr/tmp/spellXXXXXX" X X X --- 34,36 ----- X /* mktemp template for temporary file - MUST contain 6 consecutive X's */ X ! #define TEMPNAME "/tmp/ispellXXXXXX" X X *************** X *** 23,25 X /* default dictionary file */ X ! #define DEFDICT "dict.191" X X X --- 37,39 ----- X /* default dictionary file */ X ! #define DEFDICT "!!DEFDICT!!" X X *************** X *** 26,28 X /* define LOOK if look(1) command is available */ X ! #define LOOK X X X --- 40,42 ----- X /* define LOOK if look(1) command is available */ X ! #define LOOK "/usr/bin/look -df" X X X X Index: good.c X X *** good.c.old Sun Mar 29 00:10:19 1987 X --- good.c Sun Mar 29 00:10:23 1987 X *************** X *** 385,386 X } X case 'G': /* J */ X X --- 385,387 ----- X } X + return; X case 'G': /* J */ X X X Index: hash.c X X *** hash.c.old Sun Mar 29 00:10:47 1987 X --- hash.c Sun Mar 29 00:10:49 1987 X *************** X *** 25,27 X h &= 077777; X ! return (h %= hashsize); X } X X --- 25,27 ----- X h &= 077777; X ! return (unsigned long) h % hashsize; X } X *************** X *** 27,31 X } X - X - X - X - X X --- 27 ----- X } X X X Index: ispell.1 X X *** ispell.1.old Sun Mar 29 00:11:04 1987 X --- ispell.1 Sun Mar 29 00:11:10 1987 X *************** X *** 10,11 X [ X .B \-x X X --- 10,13 ----- X [ X + .B \-t X + | X .B \-x X *************** X *** 12,13 X | X .B \-d X X --- 14,17 ----- X | X + .B \-S X + | X .B \-d X *************** X *** 21,22 X [ X .B \-d X X --- 25,28 ----- X [ X + .B \-t X + | X .B \-d X *************** X *** 31,32 X [ X .B \-d X X --- 37,40 ----- X [ X + .B \-t X + | X .B \-d X *************** X *** 74,76 X dictionary. If one of the near misses is the word you want, type the X ! corresponding number. Finally, if none of these choices is right, you X can type "R" and you will be prompted for a replacement word. X X --- 82,87 ----- X dictionary. If one of the near misses is the word you want, type the X ! corresponding number. X ! (If there are more than 10 choices, X ! you may have to type a carriage return to complete a single-digit number). X ! Finally, if none of these choices is right, you X can type "R" and you will be prompted for a replacement word. X *************** X *** 92,93 X .B \-a X is intended to be used from other programs through a pipe. In this X X --- 103,105 ----- X .B \-a X + option X is intended to be used from other programs through a pipe. In this X *************** X *** 95,97 X .I ispell X ! expects the standard input to consist of single words. Each word is X read, and a single line is written to the standard output. If the word X X --- 107,110 ----- X .I ispell X ! expects the standard input to consist of lines containing single words. X ! Each word is X read, and a single line is written to the standard output. If the word X *************** X *** 109,110 X .PP X The X X --- 122,135 ----- X .PP X + When in the X + .B \-a X + mode, X + .I ispell X + will also accept lines of single words prefixed with either a '*' or a '@'. X + A line starting with '*' tells X + .I ispell X + to insert the word into the user's dictionary (similar to the I command). X + A line starting with '@' causes X + .I ispell X + to accept this word in the future (similar to the A command). X + .PP X The X *************** X *** 118,119 X The X .B \-d X X --- 143,168 ----- X The X + .B \-S X + option suppresses X + .IR ispell "'s" X + normal behavior of sorting the list of possible replacement words. X + Some people may prefer this, since it somewhat enhances the probability X + that the correct word will be low-numbered. X + .PP X + The X + .B \-t X + option selects TeX/LaTeX input mode. X + In this mode, whenever a backslash ("\e") is found, X + .I ispell X + will skip to the next whitespace. X + Thus, for example, given X + .RS X + \echapter {This is a Ckapter} X + \ecite{SCH86} X + .RE X + will find "Ckapter" but will not look for SCH. X + The X + .B \-t X + option does not recognize the TeX comment character "%". X + .PP X + The X .B \-d X *************** X *** 226,228 X in such a way as to only support ASCII range text if desired. X ! .SH DEFAULT FILES X /usr/public/lib/ispell.hash X X --- 275,277 ----- X in such a way as to only support ASCII range text if desired. X ! .SH FILES X /usr/public/lib/ispell.hash X *************** X *** 278,280 X .br X ! Enhanced by James Woods, Bob McQueer, Bill Randle, Marc Ries, Rob McMahon, X ! and Geoff Kuenning. X X --- 327,344 ----- X .br X ! Collected, revised, and enhanced for the Usenet by Walt Buehring. X ! .br X ! Further enhanced and debugged by X ! Don Kark, X ! Jim Knutson, X ! Geoff Kuenning, X ! Dave Mason, X ! Rob McMahon, X ! Bob McQueer, X ! Gary Puckering, X ! Bill Randle, X ! Marc Ries, X ! Rich Salz, X ! Greg Schaffer, X ! Perry Smith, X ! and X ! James Woods. X X X Index: ispell.c X X *** ispell.c.old Sun Mar 29 00:11:41 1987 X --- ispell.c Sun Mar 29 00:11:47 1987 X *************** X *** 19,20 X * hashed personal dictionary file X */ X X --- 19,25 ----- X * hashed personal dictionary file X + * -S option for unsorted word lists X + * 1987, Greg Schaffer, added: X + * -T option (for TeX and LaTeX instead of troff) [later changed to -t] X + * passes over \ till next whitespace. X + * does not recognize % (comment) X */ X *************** X *** 51,52 X X givehelp () X X --- 56,59 ----- X X + static int sortit = 1; X + X givehelp () X *************** X *** 90,91 X int xflag = 0; X X X --- 97,99 ----- X int xflag = 0; X + int tflag = 0; X X *************** X *** 97,100 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 X --- 105,108 ----- X { X ! fprintf (stderr, "Usage: %s [-dfile | -pfile | -wchars | -t | -x | -S] file .....\n",Cmd); X ! fprintf (stderr, " %s [-dfile | -pfile | -wchars | -t] -l\n",Cmd); X #ifdef USG X *************** X *** 100,102 X #ifdef USG X ! fprintf (stderr, " %s [-dfile | -pfile | -ffile | -s] -a\n",Cmd); X #else X X --- 108,110 ----- X #ifdef USG X ! fprintf (stderr, " %s [-dfile | -pfile | -ffile | -t | -s] -a\n",Cmd); X #else X *************** X *** 102,104 X #else X ! fprintf (stderr, " %s [-dfile | -pfile | -ffile] -a\n",Cmd); X #endif X X --- 110,112 ----- X #else X ! fprintf (stderr, " %s [-dfile | -pfile | -ffile | -t] -a\n",Cmd); X #endif X *************** X *** 149,150 X switch ((*argv)[1]) { X case 'a': X X --- 157,161 ----- X switch ((*argv)[1]) { X + case 't': X + tflag++; X + break; X case 'a': X *************** X *** 178,179 X #endif X case 'p': X X --- 189,193 ----- X #endif X + case 'S': X + sortit = 0; X + break; X case 'p': X *************** X *** 311,313 X if ((infile = fopen (tempfile, "r")) == NULL) { X ! fprintf (stderr, "tempoary file disappeared (%s)\r\n", tempfile); X sleep (2); X X --- 325,327 ----- X if ((infile = fopen (tempfile, "r")) == NULL) { X ! fprintf (stderr, "temporary file disappeared (%s)\r\n", tempfile); X sleep (2); X *************** X *** 360,361 X len = strlen (secondbuf) - 1; X if (secondbuf [ len ] == '\n') X X --- 374,399 ----- X len = strlen (secondbuf) - 1; X + X + /* skip over .if */ X + if (strncmp(currentchar,".if t",5) == 0 X + || strncmp(currentchar,".if n",5) == 0) { X + copyout(¤tchar,5); X + while (*currentchar && isspace(*currentchar)) X + copyout(¤tchar, 1); X + } X + X + /* skip over .ds XX or .nr XX */ X + if (strncmp(currentchar,".ds ",4) == 0 X + || strncmp(currentchar,".de ",4) == 0 X + || strncmp(currentchar,".nr ",4) == 0) { X + copyout(¤tchar, 3); X + while (*currentchar && isspace(*currentchar)) X + copyout(¤tchar, 1); X + while (*currentchar && !isspace(*currentchar)) X + copyout(¤tchar, 1); X + if (*currentchar == 0) { X + if (!lflag) putc ('\n', outfile); X + continue; X + } X + } X + X if (secondbuf [ len ] == '\n') X *************** X *** 364,366 X /* if this is a formatter command, skip over it */ X ! if (*currentchar == '.') { X while (*currentchar && !myspace (*currentchar)) { X X --- 402,404 ----- X /* if this is a formatter command, skip over it */ X ! if (!tflag && *currentchar == '.') { X while (*currentchar && !myspace (*currentchar)) { X *************** X *** 379,380 X while (*currentchar && !iswordch(*currentchar)) { X /* formatting escape sequences */ X X --- 417,433 ----- X while (*currentchar && !iswordch(*currentchar)) { X + if (tflag) /* TeX or LaTeX stuff */ X + { X + if (*currentchar == '\\') { X + /* skip till whitespace */ X + while (*currentchar && X + !isspace(*currentchar)) { X + if (!lflag) X + putc(*currentchar, outfile); X + currentchar++; X + } X + continue; X + } X + } X + else X + { X /* formatting escape sequences */ X *************** X *** 403,404 X } X X X --- 456,458 ----- X } X + } X X *************** X *** 420,422 X if (!good (token) && !cflag) X ! printf ("%s\r\n", token); X } else { X X --- 474,477 ----- X if (!good (token) && !cflag) X ! if (lflag) printf ("%s\n", token); X ! else printf ("%s\r\n", token); X } else { X *************** X *** 433,435 X X ! char possibilities[10][BUFSIZ]; X int pcount; X X --- 488,492 ----- X X ! #define MAXPOSSIBLE 99 /* Max no. of possibilities to generate */ X ! X ! char possibilities[MAXPOSSIBLE][BUFSIZ]; X int pcount; X *************** X *** 435,436 X int pcount; X X X --- 492,494 ----- X int pcount; X + int maxposslen; X X *************** X *** 442,443 X int i; X char *p; X X --- 500,503 ----- X int i; X + int col_ht; X + int ncols; X char *p; X *************** X *** 461,466 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 --- 521,542 ----- X X ! /* X ! * Make sure we have enough room on the screen to hold the X ! * possibilities. Reduce the list if necessary. 80 / (maxposslen + 8) X ! * is the maximum number of columns that will fit. X ! */ X ! col_ht = li - 6; /* Height of columns of words */ X ! ncols = 80 / (maxposslen + 8); X ! if (pcount > ncols * col_ht) X ! pcount = ncols * col_ht; X ! X ! #if 0 X ! /* X ! * Equalize the column sizes. The last column will be short. X ! */ X ! col_ht = (pcount + ncols - 1) / ncols; X ! #endif X ! X ! for (i = 0; i < pcount; i++) { X ! move (2 + (i % col_ht), (maxposslen + 8) * (i / col_ht)); X ! printf ("%2d: %s", i, possibilities[i]); X } X *************** X *** 467,469 X X ! move (15, 0); X printf ("%s\r\n", firstbuf); X X --- 543,545 ----- X X ! move (li - 3, 0); X printf ("%s\r\n", firstbuf); X *************** X *** 516,518 X char buf[200]; X ! move (18, 0); X putchar ('!'); X X --- 592,594 ----- X char buf[200]; X ! move (li - 1, 0); X putchar ('!'); X *************** X *** 529,531 X case 'r': case 'R': X ! move (18, 0); X printf ("Replace with: "); X X --- 605,607 ----- X case 'r': case 'R': X ! move (li - 1, 0); X printf ("Replace with: "); X *************** X *** 541,545 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 --- 617,634 ----- X case '5': case '6': case '7': case '8': case '9': X ! i = c - '0'; X ! if (pcount > 10 X ! && i > 0 && i <= (pcount - 1) / 10) { X ! c = getchar () & NOPARITY; X ! if (c >= '0' && c <= '9') X ! i = i * 10 + c - '0'; X ! else if (c != '\r' && c != '\n') { X ! putchar (7); X ! break; X ! } X ! } X ! if (i < pcount) { X ! strcpy (token, possibilities[i]); X ! inserttoken (secondbuf, begintoken, X ! token, currentchar); X ! erase (); X return; X *************** X *** 548,549 X break; X case 'l': case 'L': X X --- 637,641 ----- X break; X + case '\r': /* This makes typing \n after single digits */ X + case '\n': /* ..less obnoxious */ X + break; X case 'l': case 'L': X *************** X *** 551,553 X char buf[100]; X ! move (18, 0); X printf ("Lookup string ('*' is wildcard): "); X X --- 643,645 ----- X char buf[100]; X ! move (li - 1, 0); X printf ("Lookup string ('*' is wildcard): "); X *************** X *** 598,599 X int i; X X X --- 690,692 ----- X int i; X + extern int strcmp (); X X *************** X *** 599,601 X X ! for (i = 0; i < 10; i++) X possibilities[i][0] = 0; X X --- 692,694 ----- X X ! for (i = 0; i < MAXPOSSIBLE; i++) X possibilities[i][0] = 0; X *************** X *** 602,603 X pcount = 0; X X X --- 695,697 ----- X pcount = 0; X + maxposslen = 0; X X *************** X *** 603,608 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 --- 697,702 ----- X X ! if (pcount < MAXPOSSIBLE) wrongletter (word); X ! if (pcount < MAXPOSSIBLE) extraletter (word); X ! if (pcount < MAXPOSSIBLE) missingletter (word); X ! if (pcount < MAXPOSSIBLE) transposedletter (word); X X *************** X *** 608,609 X X } X X --- 702,706 ----- X X + if (sortit && pcount) X + qsort ((char *) possibilities, pcount, X + sizeof (possibilities[0]), strcmp); X } X *************** X *** 622,624 X strcpy (possibilities[pcount++], word); X ! if (pcount >= 10) X return (-1); X X --- 719,724 ----- X strcpy (possibilities[pcount++], word); X ! i = strlen (word); X ! if (i > maxposslen) X ! maxposslen = i; X ! if (pcount >= MAXPOSSIBLE) X return (-1); X *************** X *** 817,819 X while (gets (buf) != NULL) { X ! if (good (buf)) { X if (rootword[0] == 0) { X X --- 917,924 ----- X while (gets (buf) != NULL) { X ! /* *line is like `i', @line is like `a' */ X ! if (buf[0] == '*' || buf[0] == '@') { X ! treeinsert(buf + 1, buf[0] == '*'); X ! printf("*\n"); X ! treeoutput (); X ! } else if (good (buf)) { X if (rootword[0] == 0) { X *************** X *** 827,829 X printf ("& "); X ! for (i = 0; i < 10; i++) { X if (possibilities[i][0] == 0) X X --- 932,934 ----- X printf ("& "); X ! for (i = 0; i < MAXPOSSIBLE; i++) { X if (possibilities[i][0] == 0) X *************** X *** 886,888 X /* no wild, use look(1) */ X ! sprintf (cmd, "/usr/bin/look -df %s %s", grepstr, WORDS); X #else X X --- 991,993 ----- X /* no wild, use look(1) */ X ! sprintf (cmd, "%s %s %s", LOOK, grepstr, WORDS); X #else X X X Index: ispell.el X X *** ispell.el.old Sun Mar 29 00:12:28 1987 X --- ispell.el Sun Mar 29 00:12:31 1987 X *************** X *** 7,8 X X ;;; Depends on the ispell program snarfed from MIT-PREP in early X X --- 7,13 ----- X X + ;;; ispell-region and associate routines added by X + ;;; Perry Smith X + ;;; pedz@bobkat X + ;;; Tue Jan 13 20:18:02 CST 1987 X + X ;;; Depends on the ispell program snarfed from MIT-PREP in early X *************** X *** 35,38 X ;; Make certain characters word constituents X ! (modify-syntax-entry ?' "w " ispell-syntax-table) X ! (modify-syntax-entry ?- "w " ispell-syntax-table) X ;; Get rid on existing word syntax on certain characters X X --- 40,43 ----- X ;; Make certain characters word constituents X ! ;; (modify-syntax-entry ?' "w " ispell-syntax-table) X ! ;; (modify-syntax-entry ?- "w " ispell-syntax-table) X ;; Get rid on existing word syntax on certain characters X *************** X *** 38,39 X ;; Get rid on existing word syntax on certain characters X (modify-syntax-entry ?$ ". " ispell-syntax-table) X X --- 43,54 ----- X ;; Get rid on existing word syntax on certain characters X + (modify-syntax-entry ?0 ". " ispell-syntax-table) X + (modify-syntax-entry ?1 ". " ispell-syntax-table) X + (modify-syntax-entry ?2 ". " ispell-syntax-table) X + (modify-syntax-entry ?3 ". " ispell-syntax-table) X + (modify-syntax-entry ?4 ". " ispell-syntax-table) X + (modify-syntax-entry ?5 ". " ispell-syntax-table) X + (modify-syntax-entry ?6 ". " ispell-syntax-table) X + (modify-syntax-entry ?7 ". " ispell-syntax-table) X + (modify-syntax-entry ?8 ". " ispell-syntax-table) X + (modify-syntax-entry ?9 ". " ispell-syntax-table) X (modify-syntax-entry ?$ ". " ispell-syntax-table) X *************** X *** 73,75 X (or quietly (message "Could Not Find %s" (upcase word)))) X ! (t (setq replace (ispell-choose poss)) X (if replace X X --- 88,90 ----- X (or quietly (message "Could Not Find %s" (upcase word)))) X ! (t (setq replace (ispell-choose poss word)) X (if replace X *************** X *** 76,80 X (progn X ! (goto-char end) X ! (delete-region start end) X ! (insert-string replace))))) X poss)) X X --- 91,95 ----- X (progn X ! (goto-char end) X ! (delete-region start end) X ! (insert-string replace))))) X poss)) X *************** X *** 82,86 X X ! (defun ispell-choose (choices) X ! "Display possible corrections from list CHOICES. Return chosen word or nil X ! if none chosen." X (unwind-protect X X --- 97,101 ----- X X ! (defun ispell-choose (choices word) X ! "Display possible corrections from list CHOICES. Return chosen word X ! if one is chosen; Return nil to keep word" X (unwind-protect X *************** X *** 89,92 X (words choices) X ! (pick -1) X ! (window-min-height 2)) X (overlay-window 3) X X --- 104,107 ----- X (words choices) X ! (window-min-height 2) X ! char num result) X (overlay-window 3) X *************** X *** 97,99 X (insert "\n")) X ! (insert "(" (+ count ?a) ") " (car words) " ") X (setq words (cdr words) X X --- 112,114 ----- X (insert "\n")) X ! (insert "(" (+ count ?1) ") " (car words) " ") X (setq words (cdr words) X *************** X *** 101,110 X (select-window (next-window)) X ! (while (eq pick -1) X ! (message "Enter letter to replace word; Space to flush") X ! (let* ((char (read-char)) X ! (num (1+ (- (upcase char) ?A)))) X ! (cond ((= char ? ) (setq pick 0)) X ! ((or (<= num 0) (> num count)) (ding)) X ! (t (setq pick num))))) X ! (and (> pick 0) (nth (1- pick) choices)))) X ;; Protected forms... X X --- 116,134 ----- X (select-window (next-window)) X ! (while (eq t X ! (setq result X ! (progn X ! (message "Enter letter to replace word; Space to flush") X ! (setq char (upcase (read-char))) X ! (setq num (- char ?1)) X ! (cond ((= char ? ) nil) X ! ((= char ?I) X ! (ispell-check (concat "*" word)) X ! nil) X ! ((= char ?A) X ! (ispell-check (concat "@" word)) X ! nil) X ! ((= char ?R) (read-string "Replacement: " nil)) X ! ((and (>= num 0) (< num count)) (nth num choices)) X ! (t (ding) t)))))) X ! result)) X ;; Protected forms... X *************** X *** 191 X X X --- 215,273 ----- X X + (defvar ispell-filter-hook "/bin/cat" X + "Filter to pass a region through before sending it to ispell. X + Typically this is set to cat, deroff, detex, etc.") X + (make-variable-buffer-local 'ispell-filter-hook) X + X + (defvar ispell-filter-hook-args nil X + "Arguments to pass to ispell-filter-hook") X + (make-variable-buffer-local 'ispell-filter-hook-args) X + X + ; This routine has certain limitations brought about by the filter X + ; hook. For example, deroff will take ``\fBcat\fR'' and spit out X + ; ``cat''. This is hard to search for since word-search-forward will X + ; not match at all and search-forward for ``cat'' will match X + ; ``concatinate'' if it happens to occur before. I attempt to X + ; minimize these problems by always searching for each word in the X + ; original buffer even if it is not misspelled. This slows things X + ; down. X + X + (defun ispell-region (start end) X + "Check a region for spelling errors interactively. The variable X + which should be buffer or mode specific ispell-filter-hook is called X + to filter out text processing commands." X + (interactive "r") X + (let ((this-buf (current-buffer)) X + (spell-buf (get-buffer-create "ispell-temp")) X + (current-syntax (syntax-table)) X + word poss replace word-start word-end) X + (unwind-protect X + (save-excursion X + (set-buffer spell-buf) X + (erase-buffer) X + (set-buffer this-buf) X + (if ispell-filter-hook-args X + (call-process-region start end ispell-filter-hook nil X + spell-buf nil ispell-filter-hook-args) X + (call-process-region start end ispell-filter-hook nil X + spell-buf nil)) X + (goto-char start) X + (set-buffer spell-buf) X + (set-syntax-table ispell-syntax-table) X + (goto-char (point-min)) X + (while (progn X + (message "Looking for a misspelled word") X + (re-search-forward "\\W*\\(\\w+\\)" nil t)) X + (setq word (buffer-substring (setq word-start (match-beginning 1)) X + (setq word-end (match-end 1)))) X + (setq poss (ispell-check word)) X + (set-buffer this-buf) X + (or (search-forward word nil t) X + (error "Can not find %s in original text" word)) X + (if (not (or (eq poss t) (stringp poss))) ;bad word X + (progn X + (sit-for 0) X + (setq replace (ispell-choose poss word)) X + (if replace X + (replace-match replace)))) X + (set-buffer spell-buf))) X + (set-syntax-table current-syntax)))) X X X Index: ispell.h X X *** ispell.h.old Sun Mar 29 00:12:45 1987 X --- ispell.h Sun Mar 29 00:12:49 1987 X *************** X *** 2,5 X X - #define LIBDIR "/tmp2/lib" X - X struct dent { X X --- 2,3 ----- X X struct dent { X X X Index: lookup.c X X *** lookup.c.old Sun Mar 29 00:12:59 1987 X --- lookup.c Sun Mar 29 00:13:02 1987 X *************** X *** 13,14 X X struct dent *hashtbl; X X --- 13,15 ----- X X + struct dent *treelookup(); X struct dent *hashtbl; X X X Index: term.c X X *** term.c.old Sun Mar 29 00:13:10 1987 X --- term.c Sun Mar 29 00:13:13 1987 X *************** X *** 94,95 X int onstop(); X X X --- 94,96 ----- X int onstop(); X + extern short ospeed; X X *************** X *** 119,120 X killchar = sbuf.sg_kill; X X X --- 120,122 ----- X killchar = sbuf.sg_kill; X + ospeed = sbuf.sg_ospeed; X X X X Index: tree.c X X *** tree.c.old Sun Mar 29 00:13:27 1987 X --- tree.c Sun Mar 29 00:13:32 1987 X *************** X *** 146,210 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 X --- 146,215 ----- X dp = treeinsert (buf, 1); X ! if (h != NULL) { X ! while (*h != '\0' && *h != '\n') { 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 ! /* Accept old-format dicts with extra slashes */ X ! if (*h == '/') X ! h++; X } X *************** X *** 210,214 X } X - /* Exit loop if no more flags */ X - if (*h++ != '/') X - break; X } X X --- 215,216 ----- X } X } X *************** X *** 312,314 X } X ! newwords = 1; X return tinsert (nword, (struct dent *) NULL, keep); X X --- 314,316 ----- X } X ! newwords |= keep; X return tinsert (nword, (struct dent *) NULL, keep); X *************** X *** 421,422 X toutput1 (); X X X --- 423,425 ----- X toutput1 (); X + newwords = 0; X X *************** X *** 445,446 X X static X X --- 448,451 ----- X X + static int hasslash; X + X static X *************** X *** 449,450 X { X fprintf (dictf, "%s", cent->word); X X --- 454,457 ----- X { X + X + hasslash = 0; X fprintf (dictf, "%s", cent->word); X *************** X *** 451,453 X if (cent->d_flag) X ! fprintf (dictf, "/D"); X if (cent->g_flag) X X --- 458,460 ----- X if (cent->d_flag) X ! flagout ('D'); X if (cent->g_flag) X *************** X *** 453,455 X if (cent->g_flag) X ! fprintf (dictf, "/G"); X if (cent->h_flag) X X --- 460,462 ----- X if (cent->g_flag) X ! flagout ('G'); X if (cent->h_flag) X *************** X *** 455,457 X if (cent->h_flag) X ! fprintf (dictf, "/H"); X if (cent->j_flag) X X --- 462,464 ----- X if (cent->h_flag) X ! flagout ('H'); X if (cent->j_flag) X *************** X *** 457,459 X if (cent->j_flag) X ! fprintf (dictf, "/J"); X if (cent->m_flag) X X --- 464,466 ----- X if (cent->j_flag) X ! flagout ('J'); X if (cent->m_flag) X *************** X *** 459,461 X if (cent->m_flag) X ! fprintf (dictf, "/M"); X if (cent->n_flag) X X --- 466,468 ----- X if (cent->m_flag) X ! flagout ('M'); X if (cent->n_flag) X *************** X *** 461,463 X if (cent->n_flag) X ! fprintf (dictf, "/N"); X if (cent->p_flag) X X --- 468,470 ----- X if (cent->n_flag) X ! flagout ('N'); X if (cent->p_flag) X *************** X *** 463,465 X if (cent->p_flag) X ! fprintf (dictf, "/P"); X if (cent->r_flag) X X --- 470,472 ----- X if (cent->p_flag) X ! flagout ('P'); X if (cent->r_flag) X *************** X *** 465,467 X if (cent->r_flag) X ! fprintf (dictf, "/R"); X if (cent->s_flag) X X --- 472,474 ----- X if (cent->r_flag) X ! flagout ('R'); X if (cent->s_flag) X *************** X *** 467,469 X if (cent->s_flag) X ! fprintf (dictf, "/S"); X if (cent->t_flag) X X --- 474,476 ----- X if (cent->s_flag) X ! flagout ('S'); X if (cent->t_flag) X *************** X *** 469,471 X if (cent->t_flag) X ! fprintf (dictf, "/T"); X if (cent->v_flag) X X --- 476,478 ----- X if (cent->t_flag) X ! flagout ('T'); X if (cent->v_flag) X *************** X *** 471,473 X if (cent->v_flag) X ! fprintf (dictf, "/V"); X if (cent->x_flag) X X --- 478,480 ----- X if (cent->v_flag) X ! flagout ('V'); X if (cent->x_flag) X *************** X *** 473,475 X if (cent->x_flag) X ! fprintf (dictf, "/X"); X if (cent->y_flag) X X --- 480,482 ----- X if (cent->x_flag) X ! flagout ('X'); X if (cent->y_flag) X *************** X *** 475,477 X if (cent->y_flag) X ! fprintf (dictf, "/Y"); X if (cent->z_flag) X X --- 482,484 ----- X if (cent->y_flag) X ! flagout ('Y'); X if (cent->z_flag) X *************** X *** 477,479 X if (cent->z_flag) X ! fprintf (dictf, "/Z"); X fprintf (dictf, "\n"); X X --- 484,486 ----- X if (cent->z_flag) X ! flagout ('Z'); X fprintf (dictf, "\n"); X *************** X *** 479,480 X fprintf (dictf, "\n"); X } X X --- 486,496 ----- X fprintf (dictf, "\n"); X + } X + X + static X + flagout (flag) X + { X + if (!hasslash) X + putc ('/', dictf); X + hasslash = 1; X + putc (flag, dictf); X } SHAR_EOF if test 37715 -ne "`wc -c < 'Patch1'`" then echo shar: error transmitting "'Patch1'" '(should have been 37715 characters)' fi fi # end of overwriting check echo shar: extracting "'icombine.c'" '(2738 characters)' if test -f 'icombine.c' then echo shar: will not over-write existing file "'icombine.c'" else sed 's/^X //' << \SHAR_EOF > 'icombine.c' X /* X icombine: combine multiple ispell dictionary entries into a single X entry with the options of all entries X X Author: Gary Puckering X Cognos, Inc. X X Written: January 29, 1987 X X Notes: Input lines consist of a word followed optionally by X by one or more flags. e.g CREATE/V/N/S X X No editing on flags is performed. X The input line is upshifted. X An improper flag, like /XN will be output as /X/N. X Flags are output in alphabetical order. X Non-letter appearing before the first "/" are retained, X those after are dropped. X */ X X #include <stdio.h> X #include <ctype.h> X X #define MAXFLAGS 26 /* letters A-Z */ X #define MAXLINE 255 /* maximum line size */ X X #define TRUE 1 X #define FALSE 0 X typedef int bool; X X bool flagtbl[MAXFLAGS]; /* array of flag options */ X X char line[MAXLINE]; /* current line */ X char lastword[MAXLINE]; /* previous word */ X char word[MAXLINE]; /* current word */ X char flags[MAXLINE]; /* current flags */ X int expand = 0; /* if NZ, expand instead of combining */ X X extern char *strcpy (); X X X char *getline() X { X char *rvalue; X char *p; X X if (rvalue=gets(line)) X { p = line; X while (*p) { if (islower(*p)) *p=toupper(*p); p++; } X } X return(rvalue); X } X X main(argc,argv) X int argc; X char *argv[]; X { X X if (argc > 1 && strcmp (argv[1], "-e") == 0) X expand = 1; X if (getline()) X { X parse(line,lastword,flags); X getflags(flags); X } X else X return 0; X X while (getline()) X { X parse(line,word,flags); X if (strcmp(word,lastword)!=0) /* different word */ X { X putword(); X strcpy(lastword,word); X } X getflags(flags); X } X putword(); X return 0; X } X X putword() X { X printf("%s",lastword); X putflags(); X } X X parse(ln,wrd,flgs) X char ln[]; X char wrd[]; X char flgs[]; X { X register char *p, *q; X X /* copy line up to first "/" or to end */ X for (p=ln,q=wrd; *p && *p != '/'; p++,q++) *q = *p; X *q = NULL; X X strcpy(flgs,p); /* copy from "/" to end */ X } X X getflags(flgs) X char *flgs; X { X register char *p; X X for (p=flgs; *p; p++) X if (*p != '/') X { X if (islower (*p)) X *p = toupper (*p); X if (isupper(*p)) X flagtbl[(*p)-'A'] = TRUE; X } X } X X putflags() X { X register int i; X int slashout = 0; X X if (expand) X putchar ('\n'); X X for (i=0; i<MAXFLAGS; i++) X if (flagtbl[i]) X { X if (expand) X printf("%s/%c\n", lastword, i + 'A'); X else X { X if (!slashout) X putchar('/'); X slashout = 1; X putchar(i+'A'); X } X flagtbl[i]=FALSE; X } X if (!expand) X putchar('\n'); X } SHAR_EOF if test 2738 -ne "`wc -c < 'icombine.c'`" then echo shar: error transmitting "'icombine.c'" '(should have been 2738 characters)' fi fi # end of overwriting check echo shar: extracting "'munchlist.X'" '(5582 characters)' if test -f 'munchlist.X' then echo shar: will not over-write existing file "'munchlist.X'" else sed 's/^X //' << \SHAR_EOF > 'munchlist.X' X : Use /bin/sh X # X # Given a list of words for ispell, generate a reduced list X # in which all possible suffixes have been collapsed. The reduced X # list will match the same list as the original. X # X # Usage: X # X # munchlist [ -d hashfile ] [ -e ] [ -w chars ] [ file ] ... X # X # Options: X # X # -d hashfile X # Remove any words that are covered by 'hashfile'. The X # default is the default ispell dictionary. The words X # will be removed only if all suffixes are covered by X # the hash file. A hashfile of /dev/null should be X # specified when the main dictionary is being munched. X # -e Economical algorithm. This will use much less temporary X # disk space, at the expense of time. Useful with large files X # (such as complete dictionaries). X # -w Passed on to ispell (specify chars that are part of a word) X # X # The given input files are merged, then processed by 'ispell -c' X # to generate possible suffix lists; these are then combined X # and reduced. The final result is written to standard output. X # X # For portability to older systems, I have avoided getopt. X # X # Geoff Kuenning X # 2/28/87 X # X LIBDIR=!!LIBDIR!! X COMBINE=${LIBDIR}/icombine X EXPAND1=${LIBDIR}/expand1.sed X EXPAND2=${LIBDIR}/expand2.sed X TDIR=${TMPDIR:-/usr/tmp} X TMP=${TDIR}/munch$$ X X cheap=no X dictopt= X wchars= X while [ $# != 0 ] X do X case "$1" in X -d) X case "$2" in X /dev/null) X dictopt=NONE X ;; X *) X dictopt="-d $2" X ;; X esac X shift X ;; X -e) X cheap=yes X ;; X -w) X wchars="-w $2" X shift X ;; X *) X break X esac X shift X done X trap "/bin/rm -f ${TMP}*; exit 1" 1 2 15 X # X # Collect all the input (cat), convert to uppercase (tr), expand all X # the suffix options (two sed's), and preserve (sorted) for later X # joining in ${TMP}a. X # X if [ $# -eq 0 ] X then X tr '[a-z]' '[A-Z]' \ X | sed -f $EXPAND1 | sed -f $EXPAND2 | sort -u > ${TMP}a X else X cat "$@" | tr '[a-z]' '[A-Z]' \ X | sed -f $EXPAND1 | sed -f $EXPAND2 | sort -u > ${TMP}a X fi X # X # Unless an explicitly null dictionary was specified, remove all X # expanded words that are covered by the dictionary. This produces X # the final list of expanded words that this dictionary must cover. X # Leave the list in ${TMP}b. X # X if [ "X$dictopt" = "XNONE" ] X then X ln ${TMP}a ${TMP}b X else X ispell -l $dictopt -p /dev/null < ${TMP}a > ${TMP}b X fi X # X # Munch the input to generate roots and suffixes (ispell -c). We are X # only interested in words that have at least one suffix (egrep /); the X # next step will pick up the rest. Some of the roots are illegal. We X # use join to restrict the output to those root words that are found X # in the original dictionary. X # X # Note: one disadvantage of this pipeline is that for a large file, X # the join and icombine may be sitting around for a long time while ispell X # and sort run. You can get rid of this by splitting the pipe, at X # the expense of more temp file space. X # X if [ $cheap = yes ] X then X ispell $wchars -c -d /dev/null -p /dev/null < ${TMP}b \ X | egrep / | sort -u -t/ +0 -1 +1 \ X | join -t/ - ${TMP}a | $COMBINE > ${TMP}c X else X ispell $wchars -c -d /dev/null -p /dev/null < ${TMP}b \ X | egrep / | sort -u -t/ +0 -1 +1 \ X | join -t/ - ${TMP}a > ${TMP}c X fi X # X # There is now one slight problem: the suffix flags X, J, and Z X # are simply the addition of an "S" to the suffixes N, G, and R, X # respectively. This produces redundant entries in the output file; X # for example, ABBREVIATE/N/X and ABBREVIATION/S. We must get rid X # of the unnecessary duplicates. The candidates are those words that X # have only an "S" flag (egrep). We strip off the "S" (sed), and X # generate a list of roots that might have made these words (ispell -c). X # Of these roots, we select those that have the N, G, or R flags, X # replacing each with the plural equivalent X, J, or Z (sed -n). X # Using join once again, we select those that have legal roots X # and put them in ${TMP}d. X # X if [ $cheap = yes ] X then X egrep '^[^/]*/S$' ${TMP}c | sed 's@/S$@@' \ X | ispell $wchars -c -d /dev/null -p /dev/null \ X | sed -n -e '/\/N/s/N$/X/p' -e '/\/G/s/G$/J/p' -e '/\/R/s/R$/Z/p' \ X | sort -u -t/ +0 -1 +1 \ X | join -t/ - ${TMP}a \ X | $COMBINE > ${TMP}d X else X egrep '^[^/]*/S$' ${TMP}c | sed 's@/S$@@' \ X | ispell $wchars -c -d /dev/null -p /dev/null \ X | sed -n -e '/\/N/s/N$/X/p' -e '/\/G/s/G$/J/p' -e '/\/R/s/R$/Z/p' \ X | sort -u -t/ +0 -1 +1 \ X | join -t/ - ${TMP}a > ${TMP}d X fi X /bin/rm -f ${TMP}a X # X # Now we have to eliminate the stuff covered by ${TMP}d from ${TMP}c. X # First, we re-expand the suffixes we just made (sed -f pair), and let X # ispell re-create the /S version (ispell -c). We select the /S versions X # only (egrep), sort them (sort) for comm, and use comm to delete these X # from ${TMP}c. The output of comm (i.e., the trimmed version of X # ${TMP}c) is combined with our special-suffixes file ${TMP}d (sort again) X # and reduced in size (icombine) to produce a final list of all words X # that have at least one suffix. X # X sed -f $EXPAND1 < ${TMP}d | sed -f $EXPAND2 \ X | ispell $wchars -c -d /dev/null -p /dev/null \ X | egrep '\/S$' | sort -u -t/ +0 -1 +1 | comm -13 - ${TMP}c \ X | sort -u -t/ +0 -1 +1 - ${TMP}d \ X | $COMBINE > ${TMP}e X /bin/rm -f ${TMP}[cd] X # X # Now a slick trick. Use ispell to select those (root) words from the original X # list (${TMP}b) that are not covered by the suffix list (${TMP}e). Then we X # merge these with the suffix list and sort it to produce the final output. X # X ispell $wchars -d /dev/null -p ${TMP}e -l < ${TMP}b \ X | sort -u -t/ +0 -1 +1 - ${TMP}e X /bin/rm -f ${TMP}* SHAR_EOF if test 5582 -ne "`wc -c < 'munchlist.X'`" then echo shar: error transmitting "'munchlist.X'" '(should have been 5582 characters)' fi chmod +x 'munchlist.X' fi # end of overwriting check # End of shell archive exit 0 -- Geoff Kuenning {hplabs,ihnp4}!trwrb!desint!geoff
geoff@desint.UUCP (04/01/87)
Sigh. I should know better than to post when I'm tired. I'm sorry about all the trouble you probably had with Patch #1. I forgot to mention a CRITICAL little detail: I changed some file names. Before applying the patch, you must mv three files: mv config.h config.X mv munchlist.sh munchlist.X mv ispell.man ispell.1 Also, on BSD systems you must edit buildhash.c to interchange the includes of stat.h and param.h. The next patch will also include a fix for this. Thanks to Ken Yap for identifying the problem. Finally, I neglected to mention that 'munchlist' is now much faster, thanks to Gary Puckering's handy 'icombine' program. -- Geoff Kuenning {hplabs,ihnp4}!trwrb!desint!geoff