Annotation of early-roguelike/urogue/dictutil.c, Revision 1.1.1.1
1.1 rubenllo 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 dict_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 ( dict_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 ( dict_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 ( dict_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 ( dict_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 dict_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 ( dict_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: }
CVSweb