Annotation of early-roguelike/urogue/dictutil.c, Revision 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