diff --git a/v2/engine/builtins.c b/v2/engine/builtins.c index 7685f029d..a0c2f0c42 100644 --- a/v2/engine/builtins.c +++ b/v2/engine/builtins.c @@ -1102,14 +1102,12 @@ LIST * builtin_import( FRAME * frame, int flags ) source_name = list_next( source_name ), target_name = list_next( target_name ) ) { - RULE r_; - RULE * r = &r_; + RULE * r; RULE * imported; - r_.name = source_name->value; if ( !source_module->rules || - !hashcheck( source_module->rules, (HASHDATA * *)&r ) ) - unknown_rule( frame, "IMPORT", source_module, r_.name ); + !(r = (RULE *)hash_find( source_module->rules, source_name->value ) ) ) + unknown_rule( frame, "IMPORT", source_module, source_name->value ); imported = import_rule( r, target_module, target_name->value ); if ( localize ) @@ -1153,12 +1151,10 @@ LIST * builtin_export( FRAME * frame, int flags ) for ( ; rules; rules = list_next( rules ) ) { - RULE r_; - RULE * r = &r_; - r_.name = rules->value; + RULE * r; - if ( !m->rules || !hashcheck( m->rules, (HASHDATA * *)&r ) ) - unknown_rule( frame, "EXPORT", m, r_.name ); + if ( !m->rules || !(r = (RULE *)hash_find( m->rules, rules->value ) ) ) + unknown_rule( frame, "EXPORT", m, rules->value ); r->exported = 1; } @@ -1583,10 +1579,8 @@ LIST * builtin_native_rule( FRAME * frame, int flags ) module_t * module = bindmodule( module_name->value ); - native_rule_t n; - native_rule_t * np = &n; - n.name = rule_name->value; - if ( module->native_rules && hashcheck( module->native_rules, (HASHDATA * *)&np ) ) + native_rule_t * np; + if ( module->native_rules && (np = (native_rule_t *)hash_find( module->native_rules, rule_name->value ) ) ) { args_refer( np->arguments ); new_rule_body( module, np->name, np->arguments, np->procedure, 1 ); @@ -1595,7 +1589,7 @@ LIST * builtin_native_rule( FRAME * frame, int flags ) { backtrace_line( frame->prev ); printf( "error: no native rule \"%s\" defined in module \"%s.\"\n", - object_str( n.name ), object_str( module->name ) ); + object_str( rule_name->value ), object_str( module->name ) ); backtrace( frame->prev ); exit( 1 ); } @@ -1611,10 +1605,8 @@ LIST * builtin_has_native_rule( FRAME * frame, int flags ) module_t * module = bindmodule( module_name->value ); - native_rule_t n; - native_rule_t * np = &n; - n.name = rule_name->value; - if ( module->native_rules && hashcheck( module->native_rules, (HASHDATA * *)&np ) ) + native_rule_t * np; + if ( module->native_rules && (np = (native_rule_t *)hash_find( module->native_rules, rule_name->value ) ) ) { int expected_version = atoi( object_str( version->value ) ); if ( np->version == expected_version ) diff --git a/v2/engine/class.c b/v2/engine/class.c index a74c908e1..7ef8744f3 100644 --- a/v2/engine/class.c +++ b/v2/engine/class.c @@ -19,8 +19,7 @@ static void check_defined( LIST * class_names ) { for ( ; class_names; class_names = class_names->next ) { - OBJECT * * p = &class_names->value; - if ( !hashcheck( classes, (HASHDATA * *)&p ) ) + if ( !hash_find( classes, class_names->value ) ) { printf( "Class %s is not defined\n", object_str( class_names->value ) ); abort(); @@ -118,11 +117,13 @@ OBJECT * make_class_module( LIST * xname, LIST * bases, FRAME * frame ) OBJECT * * pp = &xname->value; module_t * class_module = 0; module_t * outer_module = frame->module; + int found; if ( !classes ) classes = hashinit( sizeof( OBJECT * ), "classes" ); - if ( hashenter( classes, (HASHDATA * *)&pp ) ) + pp = (OBJECT * *)hash_insert( classes, xname->value, &found ); + if ( !found ) { *pp = object_copy( xname->value ); } diff --git a/v2/engine/compile.c b/v2/engine/compile.c index faed2f4f0..f516c024a 100644 --- a/v2/engine/compile.c +++ b/v2/engine/compile.c @@ -203,13 +203,8 @@ static void type_check } /* If the checking rule can not be found, also bail. */ - { - RULE checker_, *checker = &checker_; - - checker->name = type_name; - if ( !typecheck->rules || !hashcheck( typecheck->rules, (HASHDATA * *)&checker ) ) - return; - } + if ( !typecheck->rules || !hash_find( typecheck->rules, type_name ) ) + return; while ( values != 0 ) { diff --git a/v2/engine/debug.c b/v2/engine/debug.c index 4f4fb3e72..827356bb8 100644 --- a/v2/engine/debug.c +++ b/v2/engine/debug.c @@ -30,18 +30,25 @@ void profile_enter( OBJECT * rulename, profile_frame * frame ) if ( DEBUG_PROFILE ) { clock_t start = clock(); - profile_info info; - profile_info * p = &info; - - if ( !rulename ) p = &profile_other; + profile_info * p; if ( !profile_hash && rulename ) profile_hash = hashinit( sizeof( profile_info ), "profile" ); - info.name = rulename; - - if ( rulename && hashenter( profile_hash, (HASHDATA * *)&p ) ) - p->cumulative = p->net = p->num_entries = p->stack_count = p->memory = 0; + if ( rulename ) + { + int found; + p = (profile_info *)hash_insert( profile_hash, rulename, &found ); + if ( !found ) + { + p->name = rulename; + p->cumulative = p->net = p->num_entries = p->stack_count = p->memory = 0; + } + } + else + { + p = &profile_other; + } ++p->num_entries; ++p->stack_count; diff --git a/v2/engine/filesys.c b/v2/engine/filesys.c index 11531b03b..a4104d3b6 100644 --- a/v2/engine/filesys.c +++ b/v2/engine/filesys.c @@ -39,22 +39,23 @@ static file_info_t filecache_finfo; file_info_t * file_info( OBJECT * filename ) { file_info_t *finfo = &filecache_finfo; + int found; if ( !filecache_hash ) filecache_hash = hashinit( sizeof( file_info_t ), "file_info" ); filename = path_as_key( filename ); - finfo->name = filename; - finfo->is_file = 0; - finfo->is_dir = 0; - finfo->size = 0; - finfo->time = 0; - finfo->files = 0; - if ( hashenter( filecache_hash, (HASHDATA**)&finfo ) ) + finfo = (file_info_t *)hash_insert( filecache_hash, filename, &found ); + if ( !found ) { /* printf( "file_info: %s\n", filename ); */ - finfo->name = object_copy( finfo->name ); + finfo->name = object_copy( filename ); + finfo->is_file = 0; + finfo->is_dir = 0; + finfo->size = 0; + finfo->time = 0; + finfo->files = 0; } object_free( filename ); diff --git a/v2/engine/hash.c b/v2/engine/hash.c index 216e778cb..b18048c88 100644 --- a/v2/engine/hash.c +++ b/v2/engine/hash.c @@ -37,20 +37,9 @@ struct hashhdr struct item * next; }; -/* This structure overlays the one handed to hashenter(). Its actual size is - * given to hashinit(). - */ - -struct hashdata -{ - OBJECT * key; - /* rest of user data */ -}; - typedef struct item { struct hashhdr hdr; - struct hashdata data; } ITEM ; # define MAX_LISTS 32 @@ -105,6 +94,10 @@ static unsigned int hash_keyval( OBJECT * key ) #define hash_bucket(hp,keyval) ((hp)->tab.base + ( (keyval) % (hp)->tab.nel )) +#define hash_data_key(data) (*(OBJECT * *)(data)) +#define hash_item_data(item) ((HASHDATA *)((char *)item + sizeof(struct hashhdr))) +#define hash_item_key(item) (hash_data_key(hash_item_data(item))) + /* Find the hash item for the given data. Returns pointer to the item and if given a pointer to the item before the found item. If it's the first item in a bucket, there is no previous item, @@ -121,7 +114,7 @@ static ITEM * hash_search( for ( ; i; i = i->hdr.next ) { - if ( object_equal( i->data.key, keydata ) ) + if ( object_equal( hash_item_key( i ), keydata ) ) { if (previous) { @@ -136,52 +129,13 @@ static ITEM * hash_search( } /* - * hash_free() - remove the given item from the table if it's there. - * Returns 1 if found, 0 otherwise. - * - * NOTE: 2nd argument is HASHDATA*, not HASHDATA** as elsewhere. - */ -int -hash_free( - register struct hash *hp, - HASHDATA *data) -{ - ITEM * i = 0; - ITEM * prev = 0; - unsigned int keyval = hash_keyval(data->key); - - i = hash_search( hp, keyval, data->key, &prev ); - if (i) - { - /* mark it free so we skip it during enumeration */ - i->data.key = 0; - /* unlink the record from the hash chain */ - if (prev) prev->hdr.next = i->hdr.next; - else *hash_bucket(hp,keyval) = i->hdr.next; - /* link it into the freelist */ - i->hdr.next = hp->items.free; - hp->items.free = i; - /* we have another item */ - hp->items.more++; - - return 1; - } - return 0; -} - -/* - * hashitem() - find a record in the table, and optionally enter a new one + * hash_insert() - insert a record in the table or return the existing one */ -int -hashitem( - register struct hash *hp, - HASHDATA **data, - int enter ) +HASHDATA * hash_insert( struct hash * hp, OBJECT * key, int * found ) { - register ITEM *i; - OBJECT *b = (*data)->key; - unsigned int keyval = hash_keyval(b); + ITEM * i; + unsigned int keyval = hash_keyval( key ); #ifdef HASH_DEBUG_PROFILE profile_frame prof[1]; @@ -189,10 +143,60 @@ hashitem( profile_enter( 0, prof ); #endif - if ( enter && !hp->items.more ) + if ( !hp->items.more ) hashrehash( hp ); - if ( !enter && !hp->items.nel ) + i = hash_search( hp, keyval, key, 0 ); + if ( i ) + { + *found = 1; + } + else + { + ITEM * * base = hash_bucket( hp, keyval ); + + /* try to grab one from the free list */ + if ( hp->items.free ) + { + i = hp->items.free; + hp->items.free = i->hdr.next; + assert( hash_item_key( i ) == 0 ); + } + else + { + i = (ITEM *)hp->items.next; + hp->items.next += hp->items.size; + } + hp->items.more--; + i->hdr.next = *base; + *base = i; + *found = 0; + } + + #ifdef HASH_DEBUG_PROFILE + if ( DEBUG_PROFILE ) + profile_exit( prof ); + #endif + + return hash_item_data( i ); +} + +/* + * hash_find() - find a record in the table or NULL if none exists + */ + +HASHDATA * hash_find( struct hash *hp, OBJECT *key ) +{ + ITEM *i; + unsigned int keyval = hash_keyval(key); + + #ifdef HASH_DEBUG_PROFILE + profile_frame prof[1]; + if ( DEBUG_PROFILE ) + profile_enter( 0, prof ); + #endif + + if ( !hp->items.nel ) { #ifdef HASH_DEBUG_PROFILE if ( DEBUG_PROFILE ) @@ -201,50 +205,21 @@ hashitem( return 0; } - i = hash_search( hp, keyval, (*data)->key, 0 ); - if (i) - { - *data = &i->data; - #ifdef HASH_DEBUG_PROFILE - if ( DEBUG_PROFILE ) profile_exit( prof ); - #endif - return !0; - } - - if ( enter ) - { - ITEM * * base = hash_bucket(hp,keyval); - - /* try to grab one from the free list */ - if ( hp->items.free ) - { - i = hp->items.free; - hp->items.free = i->hdr.next; - assert( i->data.key == 0 ); - } - else - { - i = (ITEM *)hp->items.next; - hp->items.next += hp->items.size; - } - hp->items.more--; - memcpy( (char *)&i->data, (char *)*data, hp->items.datalen ); - i->hdr.next = *base; - *base = i; - *data = &i->data; - #ifdef OPT_BOEHM_GC - if (sizeof(HASHDATA) == hp->items.datalen) - { - GC_REGISTER_FINALIZER(i->data.key,&hash_mem_finalizer,hp,0,0); - } - #endif - } + i = hash_search( hp, keyval, key, 0 ); #ifdef HASH_DEBUG_PROFILE if ( DEBUG_PROFILE ) profile_exit( prof ); #endif - return 0; + + if (i) + { + return hash_item_data( i ); + } + else + { + return 0; + } } /* @@ -278,9 +253,9 @@ static void hashrehash( register struct hash *hp ) for ( ; nel--; next += hp->items.size ) { register ITEM *i = (ITEM *)next; - ITEM **ip = hp->tab.base + object_hash( i->data.key ) % hp->tab.nel; + ITEM **ip = hp->tab.base + object_hash( hash_item_key( i ) ) % hp->tab.nel; /* code currently assumes rehashing only when there are no free items */ - assert( i->data.key != 0 ); + assert( hash_item_key( i ) != 0 ); i->hdr.next = *ip; *ip = i; @@ -301,8 +276,8 @@ void hashenumerate( struct hash * hp, void (* f)( void *, void * ), void * data for ( ; nel--; next += hp->items.size ) { ITEM * i = (ITEM *)next; - if ( i->data.key != 0 ) /* DO not enumerate freed items. */ - f( &i->data, data ); + if ( hash_item_key( i ) != 0 ) /* DO not enumerate freed items. */ + f( hash_item_data( i ), data ); } } } @@ -359,45 +334,16 @@ hashdone( struct hash * hp ) hash_mem_free( hp->items.datalen, (char *)hp ); } -const char * -hashname ( struct hash * hp ) -{ - return hp->name; -} - static void * hash_mem_alloc(size_t datalen, size_t size) { - if (sizeof(HASHDATA) == datalen) - { - return BJAM_MALLOC_RAW(size); - } - else - { - return BJAM_MALLOC(size); - } + return BJAM_MALLOC(size); } static void hash_mem_free(size_t datalen, void * data) { - if (sizeof(HASHDATA) == datalen) - { - BJAM_FREE_RAW(data); - } - else - { - BJAM_FREE(data); - } + BJAM_FREE(data); } -#ifdef OPT_BOEHM_GC -static void hash_mem_finalizer(OBJECT * key, struct hash * hp) -{ - HASHDATA d; - d.key = key; - hash_free(hp,&d); -} -#endif - /* ---- */ diff --git a/v2/engine/hash.h b/v2/engine/hash.h index 4bceff4d7..8f815f58b 100644 --- a/v2/engine/hash.h +++ b/v2/engine/hash.h @@ -11,16 +11,55 @@ #ifndef BOOST_JAM_HASH_H #define BOOST_JAM_HASH_H +/* + * An opaque struct representing an item in the + * hash table. The first element of every struct + * stored in the table must be an OBJECT * which + * is treated as the key. + */ typedef struct hashdata HASHDATA; +/* + * hashinit() - initialize a hash table, returning a handle. + * datalen is the size of the items. name is used for debugging. + */ struct hash * hashinit ( int datalen, const char * name ); -int hashitem ( struct hash * hp, HASHDATA * * data, int enter ); -void hashdone ( struct hash * hp ); -void hashenumerate( struct hash * hp, void (* f)( void *, void * ), void * data ); -int hash_free ( struct hash * hp, HASHDATA * data ); -const char * hashname ( struct hash * hp ); -#define hashenter( hp, data ) ( !hashitem( hp, data, !0 ) ) -#define hashcheck( hp, data ) hashitem( hp, data, 0 ) +/* + * hashdone() - free a hash table, given its handle + */ +void hashdone ( struct hash * hp ); + +/* + * hashenumerate() - call f(i, data) on each item, i in the hash + * table. The order of the items is unspecified. + */ +void hashenumerate( struct hash * hp, void (* f)( void *, void * ), void * data ); + +/* + * hash_insert() - insert a new item in a hash table, or return an + * existing one. + * + * Preconditions: + * - hp must be a hash table created by hashinit + * - key must be an object created by object_new + * + * Postconditions: + * - if the key does not already exist in the hash + * table, *found == 0 and the result will be a + * pointer to an uninitialized item. The key + * of the new item must be set to a value equal to + * key before any further operations on the + * hash table except hashdone. + * - if the key is present then *found == 1 and + * the result is a pointer to the existing + * record. + */ +HASHDATA * hash_insert ( struct hash * hp, OBJECT * key, int * found ); + +/* + * hash_find() - find a record in the table or NULL if none exists + */ +HASHDATA * hash_find ( struct hash * hp, OBJECT * key ); #endif diff --git a/v2/engine/hcache.c b/v2/engine/hcache.c index b9d3c3e65..93b3dd354 100644 --- a/v2/engine/hcache.c +++ b/v2/engine/hcache.c @@ -174,8 +174,6 @@ void write_netstring( FILE * f, char const * s ) void hcache_init() { - HCACHEDATA cachedata; - HCACHEDATA * c; FILE * f; OBJECT * version; int header_count = 0; @@ -201,6 +199,8 @@ void hcache_init() while ( 1 ) { + HCACHEDATA cachedata; + HCACHEDATA * c; OBJECT * record_type; OBJECT * time_str; OBJECT * age_str; @@ -209,6 +209,7 @@ void hcache_init() int i; int count; LIST * l; + int found; record_type = read_netstring( f ); if ( !record_type ) @@ -225,21 +226,19 @@ void hcache_init() goto bail; } - c = &cachedata; + cachedata.boundname = read_netstring( f ); + time_str = read_netstring( f ); + age_str = read_netstring( f ); + includes_count_str = read_netstring( f ); - c->boundname = read_netstring( f ); - time_str = read_netstring( f ); - age_str = read_netstring( f ); - includes_count_str = read_netstring( f ); - - if ( !c->boundname || !time_str || !age_str || !includes_count_str ) + if ( !cachedata.boundname || !time_str || !age_str || !includes_count_str ) { fprintf( stderr, "invalid %s\n", hcachename ); goto bail; } - c->time = atoi( object_str( time_str ) ); - c->age = atoi( object_str( age_str ) ) + 1; + cachedata.time = atoi( object_str( time_str ) ); + cachedata.age = atoi( object_str( age_str ) ) + 1; count = atoi( object_str( includes_count_str ) ); for ( l = 0, i = 0; i < count; ++i ) @@ -252,7 +251,7 @@ void hcache_init() } l = list_new( l, s ); } - c->includes = l; + cachedata.includes = l; hdrscan_count_str = read_netstring( f ); if ( !includes_count_str ) @@ -273,9 +272,18 @@ void hcache_init() } l = list_new( l, s ); } - c->hdrscan = l; + cachedata.hdrscan = l; - if ( !hashenter( hcachehash, (HASHDATA * *)&c ) ) + c = (HCACHEDATA *)hash_insert( hcachehash, cachedata.boundname, &found ); + if ( !found ) + { + c->boundname = cachedata.boundname; + c->time = cachedata.time; + c->includes = cachedata.includes; + c->hdrscan = cachedata.hdrscan; + c->age = cachedata.age; + } + else { fprintf( stderr, "can't insert header cache item, bailing on %s\n", hcachename ); @@ -375,76 +383,90 @@ cleanup: LIST * hcache( TARGET * t, int rec, regexp * re[], LIST * hdrscan ) { - HCACHEDATA cachedata; - HCACHEDATA * c = &cachedata; + HCACHEDATA * c; LIST * l = 0; ++queries; - c->boundname = t->boundname; - - if (hashcheck (hcachehash, (HASHDATA **) &c)) + if ( ( c = (HCACHEDATA *)hash_find( hcachehash, t->boundname ) ) ) { - if (c->time == t->time) + if ( c->time == t->time ) + { + LIST *l1 = hdrscan, *l2 = c->hdrscan; + while ( l1 && l2 ) + { + if (l1->value != l2->value) + { + l1 = NULL; + } + else + { + l1 = list_next( l1 ); + l2 = list_next( l2 ); + } + } + if ( l1 || l2 ) + { + if (DEBUG_HEADER) + printf( "HDRSCAN out of date in cache for %s\n", + object_str( t->boundname ) ); + + printf( "HDRSCAN out of date for %s\n", + object_str( t->boundname ) ); + printf(" real : "); + list_print( hdrscan ); + printf( "\n cached: " ); + list_print( c->hdrscan ); + printf( "\n" ); + + list_free( c->includes ); + list_free( c->hdrscan ); + c->includes = 0; + c->hdrscan = 0; + } + else + { + if (DEBUG_HEADER) + printf( "using header cache for %s\n", + object_str( t->boundname ) ); + c->age = 0; + ++hits; + l = list_copy( 0, c->includes ); + return l; + } + } + else + { + if (DEBUG_HEADER) + printf ("header cache out of date for %s\n", + object_str( t->boundname ) ); + list_free( c->includes ); + list_free( c->hdrscan ); + c->includes = 0; + c->hdrscan = 0; + } + } + else { - LIST *l1 = hdrscan, *l2 = c->hdrscan; - while (l1 && l2) { - if (l1->value != l2->value) { - l1 = NULL; - } else { - l1 = list_next(l1); - l2 = list_next(l2); + int found; + c = (HCACHEDATA *)hash_insert( hcachehash, t->boundname, &found ); + if ( !found ) + { + c->boundname = object_copy( t->boundname ); + c->next = hcachelist; + hcachelist = c; } - } - if (l1 || l2) { - if (DEBUG_HEADER) - printf("HDRSCAN out of date in cache for %s\n", - object_str( t->boundname )); - - printf("HDRSCAN out of date for %s\n", object_str( t->boundname ) ); - printf(" real : "); - list_print(hdrscan); - printf("\n cached: "); - list_print(c->hdrscan); - printf("\n"); - - list_free(c->includes); - list_free(c->hdrscan); - c->includes = 0; - c->hdrscan = 0; - } else { - if (DEBUG_HEADER) - printf ("using header cache for %s\n", object_str( t->boundname ) ); - c->age = 0; - ++hits; - l = list_copy (0, c->includes); - return l; - } - } else { - if (DEBUG_HEADER) - printf ("header cache out of date for %s\n", object_str( t->boundname ) ); - list_free (c->includes); - list_free(c->hdrscan); - c->includes = 0; - c->hdrscan = 0; - } - } else { - if (hashenter (hcachehash, (HASHDATA **)&c)) { - c->boundname = object_copy( c->boundname ); - c->next = hcachelist; - hcachelist = c; - } } /* 'c' points at the cache entry. Its out of date. */ - l = headers1 (0, t->boundname, rec, re); + l = headers1( 0, t->boundname, rec, re ); c->time = t->time; c->age = 0; - c->includes = list_copy (0, l); - c->hdrscan = list_copy(0, hdrscan); + c->includes = list_copy( 0, l ); + c->hdrscan = list_copy( 0, hdrscan ); return l; } diff --git a/v2/engine/hdrmacro.c b/v2/engine/hdrmacro.c index bd57530e9..6ef2a131c 100644 --- a/v2/engine/hdrmacro.c +++ b/v2/engine/hdrmacro.c @@ -95,6 +95,7 @@ macro_headers( TARGET * t ) if ( regexec( re, buf ) && re->startp[1] ) { OBJECT * symbol; + int found; /* we detected a line that looks like "#define MACRO filename */ ((char *)re->endp[1])[0] = '\0'; ((char *)re->endp[2])[0] = '\0'; @@ -107,10 +108,11 @@ macro_headers( TARGET * t ) if ( !header_macros_hash ) header_macros_hash = hashinit( sizeof( HEADER_MACRO ), "hdrmacros" ); - v->symbol = symbol = object_new( re->startp[1] ); - v->filename = 0; - if ( hashenter( header_macros_hash, (HASHDATA **)&v ) ) + symbol = object_new( re->startp[1] ); + v = (HEADER_MACRO *)hash_insert( header_macros_hash, symbol, &found ); + if ( !found ) { + v->symbol = symbol; v->filename = object_new( re->startp[2] ); /* never freed */ } else @@ -128,12 +130,9 @@ macro_headers( TARGET * t ) OBJECT * macro_header_get( OBJECT * macro_name ) { - HEADER_MACRO var; - HEADER_MACRO * v = &var; + HEADER_MACRO * v; - v->symbol = macro_name; - - if ( header_macros_hash && hashcheck( header_macros_hash, (HASHDATA **)&v ) ) + if ( header_macros_hash && ( v = (HEADER_MACRO *)hash_find( header_macros_hash, macro_name ) ) ) { if ( DEBUG_HEADER ) printf( "### macro '%s' evaluated to '%s'\n", object_str( macro_name ), object_str( v->filename ) ); diff --git a/v2/engine/modules.c b/v2/engine/modules.c index 3fe3df990..31bda93ae 100644 --- a/v2/engine/modules.c +++ b/v2/engine/modules.c @@ -31,15 +31,14 @@ module_t * bindmodule( OBJECT * name ) { PROFILE_ENTER( BINDMODULE ); - module_t m_; - module_t * m = &m_; + module_t * m; + int found; if ( !module_hash ) module_hash = hashinit( sizeof( module_t ), "modules" ); - m->name = name; - - if ( hashenter( module_hash, (HASHDATA * *)&m ) ) + m = (module_t *)hash_insert( module_hash, name, &found ); + if ( !found ) { m->name = object_copy( name ); m->variables = 0; @@ -160,9 +159,10 @@ void import_module( LIST * module_names, module_t * target_module ) for ( ; module_names; module_names = module_names->next ) { + int found; OBJECT * s = module_names->value; - OBJECT * * ss = &s; - if( hashenter( h, (HASHDATA * *)&ss ) ) + OBJECT * * ss = (OBJECT * *)hash_insert( h, s, &found ); + if( !found ) { *ss = object_copy( s ); } diff --git a/v2/engine/native.c b/v2/engine/native.c index 29626fe98..435a81936 100644 --- a/v2/engine/native.c +++ b/v2/engine/native.c @@ -5,6 +5,7 @@ #include "native.h" #include "hash.h" #include "object.h" +#include "assert.h" void declare_native_rule( const char * module, const char * rule, const char * * args, LIST * (*f)( FRAME *, int ), int version ) @@ -20,24 +21,28 @@ void declare_native_rule( const char * module, const char * rule, const char * * { object_free( module_obj ); } - if (m->native_rules == 0) { + if (m->native_rules == 0) + { m->native_rules = hashinit( sizeof( native_rule_t ), "native rules"); } { - native_rule_t n, *np = &n; - n.name = object_new( rule ); - if (args) + native_rule_t *np; + OBJECT * name = object_new( rule ); + int found; + np = (native_rule_t *)hash_insert( m->native_rules, name, &found ); + np->name = name; + assert( !found ); + if ( args ) { - n.arguments = args_new(); - lol_build( n.arguments->data, args ); + np->arguments = args_new(); + lol_build( np->arguments->data, args ); } else { - n.arguments = 0; + np->arguments = 0; } - n.procedure = function_builtin( f, 0 ); - n.version = version; - hashenter(m->native_rules, (HASHDATA**)&np); + np->procedure = function_builtin( f, 0 ); + np->version = version; } } diff --git a/v2/engine/pathunix.c b/v2/engine/pathunix.c index 69d78bb23..a8428df8d 100644 --- a/v2/engine/pathunix.c +++ b/v2/engine/pathunix.c @@ -374,16 +374,18 @@ static struct hash * path_key_cache; static void path_write_key( char * path_, string * out ) { - struct path_key_entry e, *result = &e; + struct path_key_entry * result; OBJECT * path = object_new( path_ ); + int found; /* This is only called by path_as_key, which initializes the cache. */ assert( path_key_cache ); - result->path = path; - if ( hashenter( path_key_cache, (HASHDATA * *)&result ) ) + result = (struct path_key_entry *)hash_insert( path_key_cache, path, &found ); + if ( !found ) { /* path_ is already normalized. */ + result->path = path; ShortPathToLongPath( path_, out ); result->key = object_new( out->value ); } @@ -414,23 +416,25 @@ static void normalize_path( string * path ) void path_add_key( OBJECT * path ) { - struct path_key_entry e, *result = &e; + struct path_key_entry * result; + int found; if ( ! path_key_cache ) path_key_cache = hashinit( sizeof( struct path_key_entry ), "path to key" ); - result->path = path; - if ( hashenter( path_key_cache, (HASHDATA * *)&result ) ) + result = (struct path_key_entry *)hash_insert( path_key_cache, path, &found ); + if ( !found ) { string buf[1]; OBJECT * normalized; - struct path_key_entry ne, *nresult = ≠ + struct path_key_entry * nresult; + result->path = path; string_copy( buf, object_str( path ) ); normalize_path( buf ); normalized = object_new( buf->value ); string_free( buf ); - nresult->path = normalized; - if ( hashenter( path_key_cache, (HASHDATA * *)&nresult ) || nresult == result ) + nresult = (struct path_key_entry *)hash_insert( path_key_cache, normalized, &found ); + if ( !found || nresult == result ) { nresult->path = object_copy( normalized ); nresult->key = object_copy( path ); @@ -446,24 +450,27 @@ void path_add_key( OBJECT * path ) OBJECT * path_as_key( OBJECT * path ) { - struct path_key_entry e, *result = &e; + struct path_key_entry * result; + int found; if ( ! path_key_cache ) path_key_cache = hashinit( sizeof( struct path_key_entry ), "path to key" ); - result->path = path; - if ( hashenter( path_key_cache, (HASHDATA * *)&result ) ) + result = (struct path_key_entry *)hash_insert( path_key_cache, path, &found ); + if ( !found ) { string buf[1]; OBJECT * normalized; - struct path_key_entry ne, *nresult = ≠ + struct path_key_entry * nresult; + result->path = path; string_copy( buf, object_str( path ) ); normalize_path( buf ); normalized = object_new( buf->value ); - nresult->path = normalized; - if ( hashenter( path_key_cache, (HASHDATA * *)&nresult ) || nresult == result ) + nresult = (struct path_key_entry *)hash_insert( path_key_cache, normalized, &found ); + if ( !found || nresult == result ) { string long_path[1]; + nresult->path = normalized; string_new( long_path ); ShortPathToLongPath( buf->value, long_path ); nresult->path = object_copy( normalized ); diff --git a/v2/engine/rules.c b/v2/engine/rules.c index fe1593191..55d351367 100644 --- a/v2/engine/rules.c +++ b/v2/engine/rules.c @@ -76,12 +76,11 @@ void target_include( TARGET * including, TARGET * included ) static RULE * enter_rule( OBJECT * rulename, module_t * target_module ) { - RULE rule; - RULE * r = &rule; + int found; + RULE * r; - r->name = rulename; - - if ( hashenter( demand_rules( target_module ), (HASHDATA * *)&r ) ) + r = (RULE *)hash_insert( demand_rules(target_module), rulename, &found ); + if ( !found ) { r->name = object_copy( rulename ); r->procedure = 0; @@ -149,15 +148,14 @@ void rule_free( RULE * r ) TARGET * bindtarget( OBJECT * target_name ) { - TARGET target; - TARGET * t = ⌖ + int found; + TARGET * t; if ( !targethash ) targethash = hashinit( sizeof( TARGET ), "targets" ); - t->name = target_name; - - if ( hashenter( targethash, (HASHDATA * *)&t ) ) + t = (TARGET *)hash_insert( targethash, target_name, &found ); + if ( !found ) { memset( (char *)t, '\0', sizeof( *t ) ); t->name = object_copy( target_name ); @@ -685,35 +683,31 @@ RULE * new_rule_actions( module_t * m, OBJECT * rulename, FUNCTION * command, LI RULE * lookup_rule( OBJECT * rulename, module_t * m, int local_only ) { - RULE rule; - RULE * r = &rule; + RULE * r; RULE * result = 0; module_t * original_module = m; - r->name = rulename; - if ( m->class_module ) m = m->class_module; - if ( m->rules && hashcheck( m->rules, (HASHDATA * *)&r ) ) + if ( m->rules && ( r = (RULE *)hash_find( m->rules, rulename ) ) ) result = r; else if ( !local_only && m->imported_modules ) { /* Try splitting the name into module and rule. */ - char *p = strchr( object_str( r->name ), '.' ) ; + char *p = strchr( object_str( rulename ), '.' ) ; if ( p ) { string buf[1]; OBJECT * module_part; OBJECT * rule_part; string_new( buf ); - string_append_range( buf, object_str( r->name ), p ); + string_append_range( buf, object_str( rulename ), p ); module_part = object_new( buf->value ); rule_part = object_new( p + 1 ); - r->name = module_part; /* Now, r->name keeps the module name, and p+1 keeps the rule name. */ - if ( hashcheck( m->imported_modules, (HASHDATA * *)&r ) ) + if ( hash_find( m->imported_modules, module_part ) ) result = lookup_rule( rule_part, bindmodule( module_part ), 1 ); object_free( rule_part ); object_free( module_part ); diff --git a/v2/engine/search.c b/v2/engine/search.c index 69ad6c1e6..186c32728 100644 --- a/v2/engine/search.c +++ b/v2/engine/search.c @@ -139,7 +139,7 @@ search( { while ( varlist ) { - BINDING b, *ba = &b; + BINDING * ba; file_info_t *ff; OBJECT * key; OBJECT * test_path; @@ -159,9 +159,7 @@ search( ff = file_query( key ); timestamp( key, time ); - b.binding = key; - - if ( hashcheck( explicit_bindings, (HASHDATA**)&ba ) ) + if ( ( ba = (BINDING *)hash_find( explicit_bindings, key ) ) ) { if ( DEBUG_SEARCH ) printf(" search %s: found explicitly located target %s\n", @@ -213,15 +211,19 @@ search( if ( explicitly_located ) { - BINDING b; - BINDING * ba = &b; + int found; + BINDING * ba; OBJECT * key = path_as_key( boundname ); - b.binding = key; - b.target = target; /* CONSIDER: we probably should issue a warning is another file is explicitly bound to the same location. This might break compatibility, though. */ - if ( !hashenter( explicit_bindings, (HASHDATA * *)&ba ) ) + ba = (BINDING *)hash_insert( explicit_bindings, key, &found ); + if ( !found ) + { + ba->binding = key; + ba->target = target; + } + else { object_free( key ); } diff --git a/v2/engine/subst.c b/v2/engine/subst.c index 42199112f..4ca404dc3 100644 --- a/v2/engine/subst.c +++ b/v2/engine/subst.c @@ -20,13 +20,14 @@ static struct hash* regex_hash; regexp* regex_compile( OBJECT* pattern ) { - regex_entry entry, *e = &entry; - entry.pattern = pattern; + int found; + regex_entry * e ; if ( !regex_hash ) regex_hash = hashinit(sizeof(regex_entry), "regex"); - if ( hashenter( regex_hash, (HASHDATA **)&e ) ) + e = (regex_entry *)hash_insert( regex_hash, pattern, &found ); + if ( !found ) { e->pattern = object_copy( pattern ); e->regex = regcomp( (char*)pattern ); diff --git a/v2/engine/timestamp.c b/v2/engine/timestamp.c index 15728ec52..6e4ed7326 100644 --- a/v2/engine/timestamp.c +++ b/v2/engine/timestamp.c @@ -71,8 +71,8 @@ void timestamp( OBJECT * target, time_t * time ) PATHNAME f1; PATHNAME f2; - BINDING binding; - BINDING * b = &binding; + int found; + BINDING * b; string buf[ 1 ]; target = path_as_key( target ); @@ -83,12 +83,14 @@ void timestamp( OBJECT * target, time_t * time ) bindhash = hashinit( sizeof( BINDING ), "bindings" ); /* Quick path - is it there? */ - b->name = target; - b->time = b->flags = 0; - b->progress = BIND_INIT; - if ( hashenter( bindhash, (HASHDATA * *)&b ) ) + b = (BINDING *)hash_insert( bindhash, target, &found ); + if ( !found ) + { b->name = object_copy( target ); /* never freed */ + b->time = b->flags = 0; + b->progress = BIND_INIT; + } if ( b->progress != BIND_INIT ) goto afterscanning; @@ -100,8 +102,8 @@ void timestamp( OBJECT * target, time_t * time ) /* Scan directory if not already done so. */ { - BINDING binding; - BINDING * b = &binding; + int found; + BINDING * b; OBJECT * name; f2 = f1; @@ -109,12 +111,15 @@ void timestamp( OBJECT * target, time_t * time ) path_parent( &f2 ); path_build( &f2, buf, 0 ); - b->name = name = object_new( buf->value ); - b->time = b->flags = 0; - b->progress = BIND_INIT; + name = object_new( buf->value ); - if ( hashenter( bindhash, (HASHDATA * *)&b ) ) + b = (BINDING *)hash_insert( bindhash, name, &found ); + if ( !found ) + { b->name = object_copy( name ); + b->time = b->flags = 0; + b->progress = BIND_INIT; + } if ( !( b->flags & BIND_SCANNED ) ) { @@ -128,8 +133,8 @@ void timestamp( OBJECT * target, time_t * time ) /* Scan archive if not already done so. */ if ( f1.f_member.len ) { - BINDING binding; - BINDING * b = &binding; + int found; + BINDING * b; OBJECT * name; f2 = f1; @@ -138,12 +143,15 @@ void timestamp( OBJECT * target, time_t * time ) string_truncate( buf, 0 ); path_build( &f2, buf, 0 ); - b->name = name = object_new( buf->value ); - b->time = b->flags = 0; - b->progress = BIND_INIT; + name = object_new( buf->value ); - if ( hashenter( bindhash, (HASHDATA * *)&b ) ) + b = (BINDING *)hash_insert( bindhash, name, &found ); + if ( !found ) + { b->name = object_copy( name ); + b->time = b->flags = 0; + b->progress = BIND_INIT; + } if ( !( b->flags & BIND_SCANNED ) ) { @@ -174,17 +182,18 @@ void timestamp( OBJECT * target, time_t * time ) static void time_enter( void * closure, OBJECT * target, int found, time_t time ) { - BINDING binding; - BINDING * b = &binding; + int item_found; + BINDING * b; struct hash * bindhash = (struct hash *)closure; target = path_as_key( target ); - b->name = target; - b->flags = 0; - - if ( hashenter( bindhash, (HASHDATA * *)&b ) ) - b->name = object_copy( target ); /* never freed */ + b = (BINDING *)hash_insert( bindhash, target, &item_found ); + if ( !item_found ) + { + b->name = object_copy( target ); + b->flags = 0; + } b->time = time; b->progress = found ? BIND_FOUND : BIND_SPOTTED; diff --git a/v2/engine/variable.c b/v2/engine/variable.c index 2d32ec466..459f794fa 100644 --- a/v2/engine/variable.c +++ b/v2/engine/variable.c @@ -201,12 +201,9 @@ LIST * var_get( struct module_t * module, OBJECT * symbol ) else #endif { - VARIABLE var; - VARIABLE * v = &var; + VARIABLE * v; - v->symbol = symbol; - - if ( module->variables && hashcheck( module->variables, (HASHDATA * *)&v ) ) + if ( module->variables && ( v = (VARIABLE *)hash_find( module->variables, symbol ) ) ) { if ( DEBUG_VARGET ) var_dump( v->symbol, v->value, "get" ); @@ -279,17 +276,18 @@ LIST * var_swap( struct module_t * module, OBJECT * symbol, LIST * value ) static VARIABLE * var_enter( struct module_t * module, OBJECT * symbol ) { - VARIABLE var; - VARIABLE * v = &var; + int found; + VARIABLE * v; if ( !module->variables ) module->variables = hashinit( sizeof( VARIABLE ), "variables" ); - v->symbol = symbol; - v->value = 0; - - if ( hashenter( module->variables, (HASHDATA * *)&v ) ) + v = (VARIABLE *)hash_insert( module->variables, symbol, &found ); + if ( !found ) + { v->symbol = object_copy( symbol ); + v->value = 0; + } return v; }