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) |
---|
28 | return(-1); |
---|
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 | |
---|