[362] | 1 | /* |
---|
| 2 | * lookup.c - see if a word appears in the dictionary |
---|
| 3 | * |
---|
| 4 | * Pace Willisson, 1983 |
---|
| 5 | */ |
---|
| 6 | |
---|
| 7 | #include <stdio.h> |
---|
| 8 | #include "ispell.h" |
---|
| 9 | #include "config.h" |
---|
| 10 | |
---|
| 11 | |
---|
| 12 | struct dent *treelookup(); |
---|
| 13 | struct dent *hashtbl; |
---|
| 14 | int hashsize; |
---|
| 15 | |
---|
| 16 | extern char hashname[]; |
---|
| 17 | |
---|
| 18 | static inited = 0; |
---|
| 19 | |
---|
| 20 | linit () |
---|
| 21 | { |
---|
| 22 | int hashfd; |
---|
| 23 | struct hashheader hashheader; |
---|
| 24 | register int i; |
---|
| 25 | register struct dent *dp; |
---|
| 26 | |
---|
| 27 | if (inited) |
---|
[1102] | 28 | return(-1); |
---|
[362] | 29 | |
---|
| 30 | if ((hashfd = open (hashname, 0)) < 0) { |
---|
| 31 | fprintf (stderr, "can't open %s\r\n", hashname); |
---|
| 32 | return (-1); |
---|
| 33 | } |
---|
| 34 | |
---|
| 35 | hashsize = read (hashfd, &hashheader, sizeof hashheader); |
---|
| 36 | if (hashsize == 0) { |
---|
| 37 | /* |
---|
| 38 | * Empty file - create an empty dummy table. We |
---|
| 39 | * actually have to have one entry since the hash |
---|
| 40 | * algorithm involves a divide by the table size |
---|
| 41 | * (actually modulo, but zero is still unacceptable). |
---|
| 42 | * So we create an entry with a word of all lowercase, |
---|
| 43 | * which can't match because the comparison string has |
---|
| 44 | * been converted to uppercase by then. |
---|
| 45 | */ |
---|
| 46 | (void) close (hashfd); |
---|
| 47 | hashsize = 1; /* This prevents divides by zero */ |
---|
| 48 | hashtbl = (struct dent *) calloc (1, sizeof (struct dent)); |
---|
| 49 | if (hashtbl == NULL) { |
---|
| 50 | (void) fprintf (stderr, |
---|
| 51 | "Couldn't allocate space for hash table\n"); |
---|
| 52 | return (-1); |
---|
| 53 | } |
---|
| 54 | hashtbl[0].word = "xxxxxxxxxxx"; |
---|
| 55 | hashtbl[0].next = NULL; |
---|
| 56 | hashtbl[0].keep = 0; |
---|
| 57 | hashtbl[0].used = 1; |
---|
| 58 | /* The flag bits don't matter, but calloc cleared them. */ |
---|
| 59 | inited = 1; |
---|
| 60 | return 0; |
---|
| 61 | } |
---|
| 62 | else if (hashsize < 0 || hashheader.magic != MAGIC) { |
---|
| 63 | fprintf (stderr, "Illegal format hash table\r\n"); |
---|
| 64 | return (-1); |
---|
| 65 | } |
---|
| 66 | hashstrings = (char *) malloc (hashheader.stringsize); |
---|
| 67 | hashtbl = (struct dent *) malloc (hashheader.tblsize * sizeof (struct dent)); |
---|
| 68 | if (hashtbl == NULL || hashstrings == NULL) { |
---|
| 69 | (void) fprintf (stderr, |
---|
| 70 | "Couldn't allocate space for hash table\n"); |
---|
| 71 | return (-1); |
---|
| 72 | } |
---|
| 73 | hashsize = hashheader.tblsize; |
---|
| 74 | |
---|
| 75 | (void) read (hashfd, hashstrings, hashheader.stringsize); |
---|
| 76 | (void) read (hashfd, hashtbl, hashheader.tblsize * sizeof (struct dent)); |
---|
| 77 | (void) close (hashfd); |
---|
| 78 | |
---|
| 79 | for (i = hashsize, dp = hashtbl; --i >= 0; dp++) { |
---|
| 80 | dp->word = &hashstrings [ (int)(dp->word) ]; |
---|
| 81 | if (dp->next == (struct dent *) -1) |
---|
| 82 | dp->next = NULL; |
---|
| 83 | else |
---|
| 84 | dp->next = &hashtbl [ (int)(dp->next) ]; |
---|
| 85 | } |
---|
| 86 | |
---|
| 87 | inited = 1; |
---|
| 88 | return (0); |
---|
| 89 | } |
---|
| 90 | |
---|
| 91 | /* n is length of s */ |
---|
| 92 | struct dent * |
---|
| 93 | lookup (s, n, dotree) |
---|
| 94 | register char *s; |
---|
| 95 | { |
---|
| 96 | int i; |
---|
| 97 | register struct dent *dp; |
---|
| 98 | register char *s1, *s2; |
---|
| 99 | |
---|
| 100 | dp = &hashtbl [ hash (s, n, hashsize) ]; |
---|
| 101 | for ( ; dp != NULL; dp = dp->next) { |
---|
| 102 | /* quick strcmp, but only for equality */ |
---|
| 103 | s1 = dp->word; |
---|
| 104 | s2 = s; |
---|
| 105 | while (*s1 == *s2++) |
---|
| 106 | if (*s1++=='\0') { |
---|
| 107 | lastdent = dp; |
---|
| 108 | return (lastdent); |
---|
| 109 | } |
---|
| 110 | } |
---|
| 111 | if (dotree) { |
---|
| 112 | i = s[n]; |
---|
| 113 | s[n] = '\0'; |
---|
| 114 | if ((dp = treelookup (s)) != NULL) |
---|
| 115 | lastdent = dp; |
---|
| 116 | s[n] = i; |
---|
| 117 | return dp; |
---|
| 118 | } |
---|
| 119 | else |
---|
| 120 | return NULL; |
---|
| 121 | } |
---|
| 122 | |
---|