xref: /original-bsd/games/boggle/boggle/word.c (revision e8eb2810)
1 /* vi: set tabstop=4 : */
2 
3 #include <stdio.h>
4 
5 #include "bog.h"
6 
7 #ifdef ATARI
8 #include <stat.h>
9 #include <osbind.h>
10 #define malloc(x)       Malloc(x)
11 #else
12 #include <sys/types.h>
13 #include <sys/stat.h>
14 #endif
15 
16 static char *dictspace, *dictend;
17 static char *sp;
18 
19 static int first = 1, lastch = 0;
20 
21 char *index();
22 long atol();
23 
24 /*
25  * Return the next word in the compressed dictionary in 'buffer' or
26  * NULL on end-of-file
27  */
28 char *
29 nextword(fp)
30 FILE *fp;
31 {
32     register int ch, pcount;
33 	register char *p;
34 	static char buf[MAXWORDLEN + 1];
35 	extern int wordlen;
36 
37 	if (fp == (FILE *) NULL) {
38 	    if (sp == dictend)
39 			return((char *) NULL);
40 
41 		p = buf + (int) *sp++;
42 
43 		/*
44 		 * The dictionary ends with a null byte
45 		 */
46 	    while (*sp >= 'a') {
47 			if ((*p++ = *sp++) == 'q')
48 				*p++ = 'u';
49 		}
50 	}
51 	else {
52     	if (first) {
53 	        if ((pcount = getc(fp)) == EOF)
54 				return((char *) NULL);
55 			first = 0;
56 		}
57 		else if ((pcount = lastch) == EOF)
58 			return((char *) NULL);
59 
60 		p = buf + pcount;
61 
62 	    while ((ch = getc(fp)) != EOF && ch >= 'a') {
63 			if ((*p++ = ch) == 'q')
64 				*p++ = 'u';
65 		}
66 	    lastch = ch;
67 	}
68 	wordlen = (int) (p - buf);
69     *p = '\0';
70     return(buf);
71 }
72 
73 /*
74  * Reset the state of nextword() and do the fseek()
75  */
76 dictseek(fp, offset, ptrname)
77 FILE *fp;
78 long offset;
79 int ptrname;
80 {
81 
82 	if (fp == (FILE *) NULL) {
83 		if ((sp = dictspace + offset) >= dictend)
84 			return(-1);
85 		return(0);
86 	}
87 
88 	first = 1;
89 	return(fseek(fp, offset, ptrname));
90 }
91 
92 FILE *
93 opendict(dict)
94 char *dict;
95 {
96 	FILE *fp;
97 
98 #ifdef ATARI
99 	if ((fp = fopen(dict, "rb")) == (FILE *) NULL)
100 		return((FILE *) NULL);
101 #else
102 	if ((fp = fopen(dict, "r")) == (FILE *) NULL)
103 		return((FILE *) NULL);
104 #endif
105 	return(fp);
106 }
107 
108 /*
109  * Load the given dictionary and initialize the pointers
110  */
111 loaddict(fp)
112 FILE *fp;
113 {
114 	int st;
115 	char *p;
116 	long n;
117 	struct stat statb;
118 
119 #ifdef ATARI
120 	if (stat(DICT, &statb) < 0) {
121 		(void) fclose(fp);
122 		return(-1);
123 	}
124 #else
125 	char *malloc();
126 
127 	if (fstat(fileno(fp), &statb) < 0) {
128 		(void) fclose(fp);
129 		return(-1);
130 	}
131 #endif
132 
133 	/*
134 	 * An extra character (a sentinel) is allocated and set to null to improve
135 	 * the expansion loop in nextword()
136 	 */
137 	if ((dictspace = (char *) malloc(statb.st_size + 1)) == (char *) NULL) {
138 		(void) fclose(fp);
139 		return(-1);
140 	}
141 	n = (long) statb.st_size;
142 	sp = dictspace;
143 	dictend = dictspace + n;
144 
145 	p = dictspace;
146 	while (n > 0 && (st = fread(p, 1, BUFSIZ, fp)) > 0) {
147 		p += st;
148 		n -= st;
149 	}
150 	if (st < 0) {
151 		(void) fclose(fp);
152 		(void) fprintf(stderr, "Error reading dictionary\n");
153 		return(-1);
154 	}
155 	*p = '\0';
156 	return(0);
157 }
158 
159 /*
160  * Dependent on the exact format of the index file:
161  * Starting offset field begins in column 1 and length field in column 9
162  * Taking the easy way out, the input buffer is made "large" and a check
163  * is made for lines that are too long
164  */
165 loadindex(indexfile)
166 char *indexfile;
167 {
168     register int i, j;
169     char buf[BUFSIZ];
170     FILE *fp;
171 	extern struct dictindex dictindex[];
172 
173     if ((fp = fopen(indexfile, "r")) == (FILE *) NULL) {
174         (void) fprintf(stderr, "Can't open '%s'\n", indexfile);
175         return(-1);
176     }
177     i = 0;
178     while (fgets(buf, sizeof(buf), fp) != (char *) NULL) {
179 		if (index(buf, '\n') == (char *) NULL) {
180 			(void) fprintf(stderr, "A line in the index file is too long\n");
181 			return(-1);
182 		}
183         j = *buf - 'a';
184         if (i != j) {
185             (void) fprintf(stderr, "Bad index order\n");
186             return(-1);
187         }
188         dictindex[j].start = atol(buf + 1);
189         dictindex[j].length = atol(buf + 9) - dictindex[j].start;
190         i++;
191     }
192     if (i != 26) {
193         (void) fprintf(stderr, "Bad index length\n");
194         return(-1);
195     }
196     (void) fclose(fp);
197 	return(0);
198 }
199 
200