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