home *** CD-ROM | disk | FTP | other *** search
- /*
- *
- * main.c for "philspell"
- *
- * This file is Copyright (c) 1992 Phillip "Edward" Nunez. Phillip grants
- * you full permission to copy and distribute this code provided you do not
- * interfere with any of the copyrights (c)s installed therein.
- *
- * Phillip grants permission to extract portions of this code for use in
- * other code provided you give full credit to him in all documentation
- * pertaining to your program, preserve copyrights in files from which code
- * is extracted, and put his name in your program's output.
- *
- *
- * This header automatically generated by the UNIX program philcopyright,
- * Copyright (c) 1991 Phillip "Edward" Nunez. For information regarding
- * philcopyright, mail phillip@soda.berkeley.edu.
- *
- */
-
- #include <stdio.h>
- #include <ctype.h>
-
- #include "skiplist.h"
-
- static char philSCCSid[] = "@(#)main.c 1.0 Phillip `Edward' Nunez";
-
- #define DEFAULT_FILENAME "/usr/dict/words"
- #define SKIPMAX 16
-
- static char scratchbuf[BUFSIZ];
- static char *philsProgramName;
-
- static char *philExists = "Phillip \"Edward\" Nunez";
-
- typedef skipnode philSkipNode;
- typedef skipnode philSkipList;
-
- char *suffixes[] = {
- "ive", /**/ "ion", "tion", "en", /**/ "ions", "ications", "ens", /**/
- "th", "ieth", /**/ "ly", /**/ "ing", /**/ "ings", /**/ "ed", /**/
- "est", /**/ "er", /**/ "ers", /**/ "ers", /**/ "s", "es", "ies", /**/
- "ness", "iness", /****/ "ment", "al", "ally", "able", "speak"
- };
- unsigned int *suffix_lens;
-
- char *prefixes[] = {
- "non", "anti", "un", "in", "re", "en", "ex", "im", "de", "phil"
- };
- unsigned int *prefix_lens;
-
- char *muties[] = {
- "able", "tion", "sion", "tion", "ing", "ily", "ed", "ier", "ly", "tions",
- "tions", "ies", "ied"
- };
- char *mutie_results[] = {
- "e", "te", "de", "t", "e", "y", "e", "y", "le", "tion",
- "te", "y", "y"
- };
- unsigned int *mutie_lens;
-
- /*
- * Someone actually had the nerve to tell me today that the "right" way to
- * impelment all the lists of prefixes and suffixes and stuff was to use
- * a backward-indexed trie with type/data records stored at the nodes. I
- * think that's really dumb because who wants to spell all their words
- * backwards?
- *
- * She said this part of the program was really pathetic because it was O(n).
- * But I like O(N)-- N for Nunez! That starts with N and that's next to O and
- * that's next to P and that stands for "Pool" and that rhymes with "Cool!"
- *
- * -Phillip
- */
-
- #define NUMSUFFIXES (sizeof(suffixes) / sizeof(char *))
- #define NUMPREFIXES (sizeof(prefixes) / sizeof(char *))
- #define NUMMUTIES (sizeof(muties) / sizeof(char *))
-
- unsigned int funny = 0;
-
- void philPerror(char *s) {
- fprintf(stderr, "Error in Phillip's program \"%s\":\n>\t%s\n",
- philsProgramName, s);
- }
-
- char *philLowerizeAndStrdup(char *t) {
- unsigned int len = strlen(t);
- char *start, *s;
-
- start = s = (char *)malloc(len + 1);
-
- do *s++ = (isupper(*t) ? tolower(*t) : *t);
- while (*t++);
-
- return start;
- }
-
- philSkipNode philLookupNoPrefix(char *word, philSkipList list) {
- philSkipNode n;
- unsigned int i, l, m;
- char newtrybuf[BUFSIZ];
-
- n = skip_lookup(word, list, SKIPMAX, NULL);
-
- if (!n) {
- i = 0;
- l = strlen(word);
- while (!n && (i < NUMSUFFIXES)) {
- if (l > (m = suffix_lens[i])) {
- if (strcasecmp(word + (l - m), suffixes[i]) == 0) {
- strncpy(newtrybuf, word, l - m);
- newtrybuf[l - m] = '\0';
- if (funny) printf("\nTrying suffix '%s': %s -> %s\n",
- suffixes[i], word, newtrybuf);
- n = skip_lookup(newtrybuf, list, SKIPMAX, NULL);
- }
- }
- i++;
- }
- if (!n) {
- i = 0;
- while (!n && (i < NUMMUTIES)) {
- if (l > (m = mutie_lens[i])) {
- if (strcasecmp(word + (l - m), muties[i]) == 0) {
- strncpy(newtrybuf, word, l - m);
- strcpy(newtrybuf + l - m, mutie_results[i]);
- if (funny) printf("\nTrying mutie '%s/%s': %s -> %s\n",
- muties[i], mutie_results[i],
- word, newtrybuf);
- n = skip_lookup(newtrybuf, list, SKIPMAX, NULL);
- }
- }
- i++;
- }
- }
- }
- return n;
- }
-
- void philSpellCheckWord(char *word, philSkipList list) {
- philSkipNode n;
- unsigned int i, l, m;
- char newtrybuf[BUFSIZ];
-
- n = skip_lookup(word, list, SKIPMAX, NULL);
-
- if (!n) {
- i = 0;
- l = strlen(word);
- while (!n && (i < NUMPREFIXES)) {
- if (l > (m = prefix_lens[i])) {
- if (strncasecmp(word, prefixes[i], m) == 0) {
- strcpy(newtrybuf, word + m);
- if (funny) printf("\nTrying prefix '%s': %s -> %s\n",
- prefixes[i], word, newtrybuf);
- n = philLookupNoPrefix(newtrybuf, list);
- }
- }
- i++;
- }
- if (!n) n = philLookupNoPrefix(word, list);
- }
- fprintf(stdout, "%s%s", word, n ? "" : " (sic)");
- }
-
- void philSpellCheck(philSkipList list) {
- char *res;
- char wordbuf[BUFSIZ], *s;
-
- while (res = gets(scratchbuf)) {
- while (*res) {
- while (*res && !isalpha(*res)) fputc(*res++, stdout);
- s = wordbuf;
- while (isalpha(*res)) *s++ = *res++;
- *s = '\0';
- if (*wordbuf) philSpellCheckWord(wordbuf, list);
- }
- fputc('\n', stdout);
- }
- }
-
- void philLoadAndGo(FILE *f) {
- philSkipList s = skip_create(SKIPMAX);
- unsigned int i;
-
- suffix_lens = (unsigned int *)malloc(NUMSUFFIXES * sizeof(char *));
- i = 0;
- while (i < NUMSUFFIXES) (suffix_lens[i] = strlen(suffixes[i])), i++;
-
- prefix_lens = (unsigned int *)malloc(NUMPREFIXES * sizeof(char *));
- i = 0;
- while (i < NUMPREFIXES) (prefix_lens[i] = strlen(prefixes[i])), i++;
-
- mutie_lens = (unsigned int *)malloc(NUMMUTIES * sizeof(char *));
- i = 0;
- while (i < NUMMUTIES) (mutie_lens[i] = strlen(muties[i])), i++;
-
- while (fgets(scratchbuf, BUFSIZ, f)) {
- scratchbuf[strlen(scratchbuf) - 1] = '\0';
- skip_add(philLowerizeAndStrdup(scratchbuf), philExists, s, SKIPMAX);
- }
-
- fclose(f);
-
- philSpellCheck(s);
- }
-
- static char *filename = DEFAULT_FILENAME;
-
- void philParseCLA(int argc, char *argv[]) {
- unsigned int n = 1;
- char *s;
-
- while (n < argc) {
- s = argv[n];
- if (*s++ != '-') {
- sprintf(scratchbuf, "Argument #%d doesn't start with a dash.", n);
- philPerror(scratchbuf);
- } else if (*s == 'v') funny = 1;
- else if (*s == 'f') {
- n++;
- if (n == argc) philPerror("Missing filename for option f.");
- else filename = argv[n];
- } else {
- sprintf(scratchbuf, "Unknown option: %s.", s);
- philPerror(scratchbuf);
- }
- n++;
- }
- }
-
- void philMain(int argc, char *argv[]) {
- FILE *f;
-
- philsProgramName = argv[0];
-
- philParseCLA(argc, argv);
-
- f = fopen(filename, "r");
- if (f == NULL) {
- sprintf(scratchbuf, "Unable to open file \"%s\".", filename);
- philPerror(scratchbuf);
- exit(1);
- }
-
- philLoadAndGo(f);
- exit(0);
- }
-
-
- void main(int argc, char *argv[]) {
- /*
- * This is just a hook to make the
- * program work even on compilers not
- * smart enough to make philMain()
- * the entry procedure instead of
- * main(), when philMain() exists.
- * [gcc requires this, for example.]
- *
- */
- philMain(argc, argv);
- }
-