comparison urogue/dictutil.c @ 256:c495a4f288c6

Import UltraRogue from the Roguelike Restoration Project (r1490)
author John "Elwin" Edwards
date Tue, 31 Jan 2017 19:56:04 -0500
parents
children c4b12d2d1dcd
comparison
equal deleted inserted replaced
253:d9badb9c0179 256:c495a4f288c6
1 /*
2 dictutil.c
3
4 UltraRogue: The Ultimate Adventure in the Dungeons of Doom
5 Copyright (C) 1995 Herb Chong
6 All rights reserved.
7
8 See the file LICENSE.TXT for full copyright and licensing information.
9 */
10
11 /*************************************************************************
12 ** Utilities for Dictionary Maintenence Functions
13 *************************************************************************/
14
15 static char sccsid[] = "%W% %G%";
16
17 #include <stdio.h>
18 #include <string.h>
19 #include <stdlib.h>
20 #if !defined(OS2) && !defined(_WIN32)
21 #include <unistd.h>
22 #else
23 #include <io.h>
24 #include <fcntl.h>
25 #endif
26
27 #include "dict.h"
28 #include "dictutil.h"
29 #include "rogue.h"
30
31 int trace;
32 FILE *ft;
33
34
35 /***********
36 ** Read 'count' characters into 'buffer' at 'offset' in a binary file
37 ** Return 0 on success; -1 on failure;
38 ***********/
39
40 int block_read( FILE *fi , char *buffer , size_t count , long offset )
41 {
42 if ( fseek(fi,offset,SEEK_SET) == -1 )
43 return( -1 );
44
45 if ( fread(buffer,1,count,fi) != count )
46 return( -1 );
47 return( 0 );
48 }
49
50 /***********
51 ** Write 'count' characters from 'buffer' to a binary file.
52 ** Return -1 on failure; 0 on success.
53 ***********/
54
55 int block_write( FILE *fo , char *buffer , size_t count )
56 {
57 if ( fwrite(buffer,1,count,fo) != count )
58 return( -1 );
59 return( 0 );
60 }
61
62 /***********
63 ** Load a dictionary table entry with id TOC_id into memory pointed to by block.
64 ** Update the dictionary TOC.
65 ** If *block=NULL, allocate the block of memory.
66 ** Return 0 on success; -1 on failure.
67 ** Set dt_entry->ptr to where the block is stored.
68 ***********/
69
70 void *dict_load_block( DICTIONARY *dict , char *toc_id ,
71 FILE *fi , void *block )
72 { DICT_TOC_ENTRY *dt_entry;
73 static void *ptr;
74 int index, ret_code;
75
76 index = dict_toc_index( dict , toc_id );
77 if ( index != -1 ) { /* Found the id */
78 dt_entry = &(dict->toc[index]);
79 } else {
80 signal_error( "dict_load_block: could not find TOC_id" , toc_id , 1 );
81 return( NULL );
82 } /* endif */
83
84 if ( block == NULL ) {
85 ptr = malloc( dt_entry->size );
86 if ( trace > 3 ) {
87 fprintf( ft , "\ndict_load_block allocates %lx bytes at location %p\n" ,
88 dt_entry->size , ptr );
89 } /* endif */
90 } else {
91 ptr = block;
92 if ( trace > 3 ) {
93 fprintf( ft , "\ndict_load_block uses memory at location %p\n" , ptr );
94 } /* endif */
95 } /* endif */
96 if ( ptr == NULL ) {
97 signal_error( "dict_load_block: alloc failed " , toc_id , 1 );
98 return( NULL );
99 } /* endif */
100
101 ret_code = block_read( fi ,
102 (char*)ptr ,
103 dt_entry->size ,
104 dt_entry->offset );
105 if ( ret_code == -1 )
106 return( NULL );
107
108 if ( dt_entry->checksum !=
109 compute_checksum( dt_entry->size , (char*)ptr ) ) {
110 signal_error( "dict_load_block: invalid checksum ", toc_id, 1);
111 return( NULL );
112 } /* endif */
113
114 dt_entry->ptr = ptr;
115
116 if ( trace > 3 ) {
117 fprintf( ft , "\nLoaded block\nTOC entry: id:%s offset:%lx size:%lx ptr:%p checksum:%lx type:%d\n" ,
118 dict->toc[index].id , dict->toc[index].offset ,
119 dict->toc[index].size , dict->toc[index].ptr ,
120 dict->toc[index].checksum , dict->toc[index].type );
121 } /* endif */
122
123 return( ptr );
124 }
125
126 /***********
127 ** Save a dictionary table entry.
128 ** Update the dictionary TOC entry offset and checksum fields.
129 ** Return 0 on success, -1 on failure.
130 ** Note: It is assumed that the size and pointer fields in TOC entry are
131 ** already up to date; i.e., that they are consistent with the current
132 ** location and size of the block being written. This is essential
133 ** because the table of contents must have already been written
134 ** into the file.
135 ***********/
136
137 BOOLEANC dict_save_block( DICTIONARY *dict , char *toc_id , FILE *fo )
138 { DICT_TOC_ENTRY *dt_entry;
139 int index, ret_code;
140 char *block;
141
142 index = dict_toc_index( dict , toc_id );
143 if ( index == -1 ) {
144 signal_error( "dict_save_block: id not found " , toc_id , 1 );
145 return( FALSE );
146 } /* endif */
147 dt_entry = &(dict->toc[index]);
148 block = (char*)(dt_entry->ptr);
149
150 if ( block == NULL ) {
151 signal_error( "dict_save_block: NULL block " , toc_id , 1 );
152 return( FALSE );
153 } /* endif */
154
155 /* dt_entry->offset = fseek( fo , 0 , SEEK_END ); */
156 dt_entry->checksum = compute_checksum( dt_entry->size , block );
157 ret_code = block_write( fo , dt_entry->ptr , dt_entry->size );
158 if ( ret_code == -1 ) {
159 signal_error( "dict_save_block: block_write failed " , toc_id , 1 );
160 return( FALSE );
161 } /* endif */
162
163 if ( trace > 3 ) {
164 fprintf( ft , "\nStored block\nTOC entry: id:%s offset:%lx size:%lx ptr:%p checksum:%lx type:%d\n" ,
165 dict->toc[index].id , dict->toc[index].offset ,
166 dict->toc[index].size , dict->toc[index].ptr ,
167 dict->toc[index].checksum , dict->toc[index].type );
168 } /* endif */
169
170 return( TRUE );
171 }
172
173 /***********
174 ** Look up and id in the table of contents.
175 ** Return its index (-1 on failure).
176 ***********/
177
178 int dict_toc_index( DICTIONARY *dict , char *toc_id )
179 { int index;
180
181 for ( index = 0 ; index < dict->sig->toc_size ; index++ ) {
182 if ( strcmp(dict->toc[index].id,toc_id) == 0 )
183 return( index );
184 } /* endfor */
185
186 return( -1 );
187 }
188
189 /***********
190 ** Compute a block checksum.
191 ** (Currently just returns 0.)
192 ***********/
193
194 unsigned long compute_checksum( size_t size , char *block )
195 {
196 NOOP(size);
197 NOOP(block);
198 return( 0 );
199 }
200
201 /***********
202 ** Create a dictionary paramter entry.
203 ***********/
204
205 DICT_PARM_ENTRY *dict_make_parm_entry( char *id , unsigned long value )
206 { static DICT_PARM_ENTRY *entry;
207
208 entry = (DICT_PARM_ENTRY *) malloc( sizeof(DICT_PARM_ENTRY) );
209 if ( entry == NULL )
210 return(NULL);
211
212 strncpy( entry->id , id , 13 );
213 entry->value = value;
214
215 return( entry );
216 }
217
218 /***********
219 ** Look up and id in the parameter array.
220 ** Return its index (-1 on failure).
221 ***********/
222
223 int dict_parm_index( DICTIONARY *dict , char *parm_id )
224 { long index;
225
226 for ( index = 0 ; index < dict->sig->nparms ; index++ ) {
227 if ( strcmp( dict->parm[index].id , parm_id ) == 0 )
228 return( (int) index );
229 } /* endfor */
230
231 return( -1 );
232 }
233
234 /***********
235 ** Reset table of contents offsets and checksums
236 ** in preparation for dict_save().
237 ***********/
238
239 BOOLEANC dict_reset_toc_offsets( DICTIONARY *dict )
240 { int i;
241 long offset;
242
243 offset = sizeof(DICT_SIG)
244 + dict->sig->toc_size * sizeof(DICT_TOC_ENTRY);
245 for ( i = 0 ; i < dict->sig->toc_size ; i++ ) {
246 dict->toc[i].offset = offset;
247 offset += dict->toc[i].size;
248 dict->toc[i].checksum =
249 compute_checksum( dict->toc[i].size , dict->toc[i].ptr );
250 } /* endfor */
251
252 return( TRUE );
253 }
254
255 /***********
256 ** Load the names of the dictionary parameters.
257 ** 14 parms
258 ***********/
259
260 BOOLEANC dict_set_parm_ids( DICTIONARY *dict )
261 {
262 if ( dict==NULL || dict->sig == NULL ) {
263 signal_error( "dict_set_parm_ids: Allocate dict and signature first." , "" , 0 );
264 return( FALSE );
265 }
266 dict->sig->nparms = 14;
267 strcpy( dict->parm[0].id , "FLAGS_______" );
268 strcpy( dict->parm[1].id , "ENTRY_COUNT_" );
269 strcpy( dict->parm[2].id , "ARRAY_SIZE__" );
270 strcpy( dict->parm[3].id , "ARRAY_USED__" );
271 strcpy( dict->parm[4].id , "ARR_GROW_CT_" );
272 strcpy( dict->parm[5].id , "STRING_MAX__" );
273 strcpy( dict->parm[6].id , "STR_GROW_CT_" );
274 strcpy( dict->parm[7].id , "LONG_CHAIN__" );
275 strcpy( dict->parm[8].id , "ALLOW_CHAIN_" );
276 strcpy( dict->parm[9].id , "HASH_TAB_SIZ" );
277 strcpy( dict->parm[10].id , "HASH_MASK___" );
278 strcpy( dict->parm[11].id , "HASH_GROW_CT" );
279 strcpy( dict->parm[12].id , "CHECK_VALUE_" );
280 strcpy( dict->parm[13].id , "SCAN_STR_IX_" );
281
282 return( TRUE );
283 }
284
285 /***********
286 ** Set the dictionary parm structure from the values in the dict structure.
287 ** 14 parms
288 ***********/
289
290 BOOLEANC dict_set_parm_values( DICTIONARY *dict )
291 { int index;
292
293 if ( (index=dict_parm_index(dict,"FLAGS_______")) == -1 )
294 return( FALSE );
295 dict->parm[index].value = (unsigned long)dict->flags;
296
297 if ( (index=dict_parm_index(dict,"ENTRY_COUNT_")) == -1 )
298 return( FALSE );
299 dict->parm[index].value = (unsigned long)dict->entry_count;
300
301 if ( (index=dict_parm_index(dict,"ARRAY_SIZE__")) == -1 )
302 return( FALSE );
303 dict->parm[index].value = (unsigned long)dict->array_size;
304
305 if ( (index=dict_parm_index(dict,"ARRAY_USED__")) == -1 )
306 return( FALSE );
307 dict->parm[index].value = (unsigned long)dict->array_used;
308
309 if ( (index=dict_parm_index(dict,"ARR_GROW_CT_")) == -1 )
310 return( FALSE );
311 dict->parm[index].value = (unsigned long)dict->array_growth_count;
312
313 if ( (index=dict_parm_index(dict,"STRING_MAX__")) == -1 )
314 return( FALSE );
315 dict->parm[index].value = (unsigned long)dict->string_max;
316
317 if ( (index=dict_parm_index(dict,"STR_GROW_CT_")) == -1 )
318 return( FALSE );
319 dict->parm[index].value = (unsigned long)dict->string_growth_count;
320
321 if ( (index=dict_parm_index(dict,"LONG_CHAIN__")) == -1 )
322 return( FALSE );
323 dict->parm[index].value = (unsigned long)dict->longest_chain_length;
324
325 if ( (index=dict_parm_index(dict,"ALLOW_CHAIN_")) == -1 )
326 return( FALSE );
327 dict->parm[index].value = (unsigned long)dict->allowable_chain_length;
328
329 if ( (index=dict_parm_index(dict,"HASH_TAB_SIZ")) == -1 )
330 return( FALSE );
331 dict->parm[index].value = (unsigned long)dict->table_size;
332
333 if ( (index=dict_parm_index(dict,"HASH_MASK___")) == -1 )
334 return( FALSE );
335 dict->parm[index].value = (unsigned long)dict->hash_mask;
336
337 if ( (index=dict_parm_index(dict,"HASH_GROW_CT")) == -1 )
338 return( FALSE );
339 dict->parm[index].value = (unsigned long)dict->hash_growth_count;
340
341 if ( (index=dict_parm_index(dict,"CHECK_VALUE_")) == -1 )
342 return( FALSE );
343 dict->parm[index].value = (unsigned long)dict->check_value;
344
345 if ( (index=dict_parm_index(dict,"SCAN_STR_IX_")) == -1 )
346 return( FALSE );
347 dict->parm[index].value = (unsigned long)dict->scan_string_index;
348
349 return( TRUE );
350 }
351
352
353 /***********
354 ** Set the values in the dict structure from the dictionary parm structure.
355 ** 14 parms
356 ***********/
357
358 BOOLEANC dict_set_parm_variables( DICTIONARY *dict )
359 { int index;
360
361 if ( (index=dict_parm_index(dict,"FLAGS_______")) == -1 )
362 return( FALSE );
363 dict->flags = (unsigned long)dict->parm[index].value;
364
365 if ( (index=dict_parm_index(dict,"ENTRY_COUNT_")) == -1 )
366 return( FALSE );
367 dict->entry_count = (long)dict->parm[index].value;
368
369 if ( (index=dict_parm_index(dict,"ARRAY_SIZE__")) == -1 )
370 return( FALSE );
371 dict->array_size = (long)dict->parm[index].value;
372
373 if ( (index=dict_parm_index(dict,"ARRAY_USED__")) == -1 )
374 return( FALSE );
375 dict->array_used = (long)dict->parm[index].value;
376
377 if ( (index=dict_parm_index(dict,"ARR_GROW_CT_")) == -1 )
378 return( FALSE );
379 dict->array_growth_count = (int)dict->parm[index].value;
380
381 if ( (index=dict_parm_index(dict,"STRING_MAX__")) == -1 )
382 return( FALSE );
383 dict->string_max = (long)dict->parm[index].value ;
384
385 if ( (index=dict_parm_index(dict,"STR_GROW_CT_")) == -1 )
386 return( FALSE );
387 dict->string_growth_count = (int)dict->parm[index].value;
388
389 if ( (index=dict_parm_index(dict,"LONG_CHAIN__")) == -1 )
390 return( FALSE );
391 dict->longest_chain_length = (int)dict->parm[index].value;
392
393 if ( (index=dict_parm_index(dict,"ALLOW_CHAIN_")) == -1 )
394 return( FALSE );
395 dict->allowable_chain_length = (int)dict->parm[index].value;
396
397 if ( (index=dict_parm_index(dict,"HASH_TAB_SIZ")) == -1 )
398 return( FALSE );
399 dict->table_size = (long)dict->parm[index].value;
400
401 if ( (index=dict_parm_index(dict,"HASH_MASK___")) == -1 )
402 return( FALSE );
403 dict->hash_mask = (unsigned long)dict->parm[index].value;
404
405 if ( (index=dict_parm_index(dict,"HASH_GROW_CT")) == -1 )
406 return( FALSE );
407 dict->hash_growth_count = (int)dict->parm[index].value;
408
409 if ( (index=dict_parm_index(dict,"CHECK_VALUE_")) == -1 )
410 return( FALSE );
411 dict->check_value = (unsigned long)dict->parm[index].value;
412
413 if ( (index=dict_parm_index(dict,"SCAN_STR_IX_")) == -1 )
414 return( FALSE );
415 dict->scan_string_index = (long)dict->parm[index].value;
416
417 return( TRUE );
418 }
419
420 /***********
421 ** If trace (global) > 0 , signal an error
422 ** If severity > 0 , abort
423 ***********/
424
425 void signal_error( char *header , char *message , int severity )
426 {
427 FILE *fpe;
428
429 if ( trace > 0 ) {
430 printf( "%s: %s\n" , header , message );
431 fpe = fopen( "ERROR.FIL" , "a" );
432 fprintf( fpe , "\n%s: %s\n" , header , message );
433 fclose( fpe );
434 } /* endif */
435
436 if ( severity > 0 )
437 abort();
438 }