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