Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r77190 - trunk/tools/build/v2/engine
From: steven_at_[hidden]
Date: 2012-03-03 16:46:55


Author: steven_watanabe
Date: 2012-03-03 16:46:53 EST (Sat, 03 Mar 2012)
New Revision: 77190
URL: http://svn.boost.org/trac/boost/changeset/77190

Log:
Fix alias violations in hash.
Text files modified:
   trunk/tools/build/v2/engine/builtins.c | 30 ++----
   trunk/tools/build/v2/engine/class.c | 7
   trunk/tools/build/v2/engine/compile.c | 9 -
   trunk/tools/build/v2/engine/debug.c | 23 +++-
   trunk/tools/build/v2/engine/filesys.c | 17 +-
   trunk/tools/build/v2/engine/hash.c | 186 ++++++++++++++-------------------------
   trunk/tools/build/v2/engine/hash.h | 49 +++++++++-
   trunk/tools/build/v2/engine/hcache.c | 162 +++++++++++++++++++---------------
   trunk/tools/build/v2/engine/hdrmacro.c | 15 +-
   trunk/tools/build/v2/engine/modules.c | 14 +-
   trunk/tools/build/v2/engine/native.c | 25 +++--
   trunk/tools/build/v2/engine/pathunix.c | 37 ++++---
   trunk/tools/build/v2/engine/rules.c | 32 ++----
   trunk/tools/build/v2/engine/search.c | 20 ++-
   trunk/tools/build/v2/engine/subst.c | 7
   trunk/tools/build/v2/engine/timestamp.c | 59 +++++++-----
   trunk/tools/build/v2/engine/variable.c | 20 +--
   17 files changed, 365 insertions(+), 347 deletions(-)

Modified: trunk/tools/build/v2/engine/builtins.c
==============================================================================
--- trunk/tools/build/v2/engine/builtins.c (original)
+++ trunk/tools/build/v2/engine/builtins.c 2012-03-03 16:46:53 EST (Sat, 03 Mar 2012)
@@ -1102,14 +1102,12 @@
           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 @@
 
     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 @@
 
     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 @@
     {
         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 @@
 
     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 )

Modified: trunk/tools/build/v2/engine/class.c
==============================================================================
--- trunk/tools/build/v2/engine/class.c (original)
+++ trunk/tools/build/v2/engine/class.c 2012-03-03 16:46:53 EST (Sat, 03 Mar 2012)
@@ -19,8 +19,7 @@
 {
     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 * * 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 );
     }

Modified: trunk/tools/build/v2/engine/compile.c
==============================================================================
--- trunk/tools/build/v2/engine/compile.c (original)
+++ trunk/tools/build/v2/engine/compile.c 2012-03-03 16:46:53 EST (Sat, 03 Mar 2012)
@@ -203,13 +203,8 @@
     }
 
     /* 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 )
     {

Modified: trunk/tools/build/v2/engine/debug.c
==============================================================================
--- trunk/tools/build/v2/engine/debug.c (original)
+++ trunk/tools/build/v2/engine/debug.c 2012-03-03 16:46:53 EST (Sat, 03 Mar 2012)
@@ -30,18 +30,25 @@
     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;

Modified: trunk/tools/build/v2/engine/filesys.c
==============================================================================
--- trunk/tools/build/v2/engine/filesys.c (original)
+++ trunk/tools/build/v2/engine/filesys.c 2012-03-03 16:46:53 EST (Sat, 03 Mar 2012)
@@ -39,22 +39,23 @@
 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 );

Modified: trunk/tools/build/v2/engine/hash.c
==============================================================================
--- trunk/tools/build/v2/engine/hash.c (original)
+++ trunk/tools/build/v2/engine/hash.c 2012-03-03 16:46:53 EST (Sat, 03 Mar 2012)
@@ -37,20 +37,9 @@
     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 @@
 
 #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 @@
 
     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 @@
 }
 
 /*
- * 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 )
-{
- register ITEM *i;
- OBJECT *b = (*data)->key;
- unsigned int keyval = hash_keyval(b);
+HASHDATA * hash_insert( struct hash * hp, OBJECT * key, int * found )
+{
+ ITEM * i;
+ unsigned int keyval = hash_keyval( key );
 
     #ifdef HASH_DEBUG_PROFILE
     profile_frame prof[1];
@@ -189,38 +143,24 @@
         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 )
     {
- #ifdef HASH_DEBUG_PROFILE
- if ( DEBUG_PROFILE )
- profile_exit( prof );
- #endif
- return 0;
+ *found = 1;
     }
-
- 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 )
+ else
     {
- ITEM * * base = hash_bucket(hp,keyval);
+ 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 );
+ assert( hash_item_key( i ) == 0 );
         }
         else
         {
@@ -228,23 +168,58 @@
             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);
- }
+ *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 )
+ profile_exit( prof );
         #endif
+ return 0;
     }
 
+ 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 @@
         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 @@
         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 @@
     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
-
 
 /* ---- */
 

Modified: trunk/tools/build/v2/engine/hash.h
==============================================================================
--- trunk/tools/build/v2/engine/hash.h (original)
+++ trunk/tools/build/v2/engine/hash.h 2012-03-03 16:46:53 EST (Sat, 03 Mar 2012)
@@ -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 );
+
+/*
+ * 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 );
-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 )
+/*
+ * 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

Modified: trunk/tools/build/v2/engine/hcache.c
==============================================================================
--- trunk/tools/build/v2/engine/hcache.c (original)
+++ trunk/tools/build/v2/engine/hcache.c 2012-03-03 16:46:53 EST (Sat, 03 Mar 2012)
@@ -174,8 +174,6 @@
 
 void hcache_init()
 {
- HCACHEDATA cachedata;
- HCACHEDATA * c;
     FILE * f;
     OBJECT * version;
     int header_count = 0;
@@ -201,6 +199,8 @@
 
     while ( 1 )
     {
+ HCACHEDATA cachedata;
+ HCACHEDATA * c;
         OBJECT * record_type;
         OBJECT * time_str;
         OBJECT * age_str;
@@ -209,6 +209,7 @@
         int i;
         int count;
         LIST * l;
+ int found;
 
         record_type = read_netstring( f );
         if ( !record_type )
@@ -225,21 +226,19 @@
             goto bail;
         }
 
- c = &cachedata;
-
- c->boundname = read_netstring( f );
- time_str = read_netstring( f );
- age_str = read_netstring( f );
- includes_count_str = read_netstring( f );
+ cachedata.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 @@
             }
             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 @@
             }
             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 @@
 
 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)
- {
- 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 {
- if (hashenter (hcachehash, (HASHDATA **)&c)) {
- c->boundname = object_copy( c->boundname );
- c->next = hcachelist;
- hcachelist = c;
+ 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
+ {
+ int found;
+ c = (HCACHEDATA *)hash_insert( hcachehash, t->boundname, &found );
+ if ( !found )
+ {
+ c->boundname = object_copy( t->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;
 }

Modified: trunk/tools/build/v2/engine/hdrmacro.c
==============================================================================
--- trunk/tools/build/v2/engine/hdrmacro.c (original)
+++ trunk/tools/build/v2/engine/hdrmacro.c 2012-03-03 16:46:53 EST (Sat, 03 Mar 2012)
@@ -95,6 +95,7 @@
         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 @@
             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 @@
 
 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 ) );

Modified: trunk/tools/build/v2/engine/modules.c
==============================================================================
--- trunk/tools/build/v2/engine/modules.c (original)
+++ trunk/tools/build/v2/engine/modules.c 2012-03-03 16:46:53 EST (Sat, 03 Mar 2012)
@@ -31,15 +31,14 @@
     {
         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 @@
 
     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 );
         }

Modified: trunk/tools/build/v2/engine/native.c
==============================================================================
--- trunk/tools/build/v2/engine/native.c (original)
+++ trunk/tools/build/v2/engine/native.c 2012-03-03 16:46:53 EST (Sat, 03 Mar 2012)
@@ -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 @@
     {
         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;
     }
 }

Modified: trunk/tools/build/v2/engine/pathunix.c
==============================================================================
--- trunk/tools/build/v2/engine/pathunix.c (original)
+++ trunk/tools/build/v2/engine/pathunix.c 2012-03-03 16:46:53 EST (Sat, 03 Mar 2012)
@@ -374,16 +374,18 @@
 
 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 @@
 
 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 = &ne;
+ 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 @@
 
 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 = &ne;
+ 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 );

Modified: trunk/tools/build/v2/engine/rules.c
==============================================================================
--- trunk/tools/build/v2/engine/rules.c (original)
+++ trunk/tools/build/v2/engine/rules.c 2012-03-03 16:46:53 EST (Sat, 03 Mar 2012)
@@ -76,12 +76,11 @@
 
 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 @@
 
 TARGET * bindtarget( OBJECT * target_name )
 {
- TARGET target;
- TARGET * t = &target;
+ 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 * 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 );

Modified: trunk/tools/build/v2/engine/search.c
==============================================================================
--- trunk/tools/build/v2/engine/search.c (original)
+++ trunk/tools/build/v2/engine/search.c 2012-03-03 16:46:53 EST (Sat, 03 Mar 2012)
@@ -139,7 +139,7 @@
     {
         while ( varlist )
         {
- BINDING b, *ba = &b;
+ BINDING * ba;
             file_info_t *ff;
             OBJECT * key;
             OBJECT * test_path;
@@ -159,9 +159,7 @@
             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 @@
 
     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 );
         }

Modified: trunk/tools/build/v2/engine/subst.c
==============================================================================
--- trunk/tools/build/v2/engine/subst.c (original)
+++ trunk/tools/build/v2/engine/subst.c 2012-03-03 16:46:53 EST (Sat, 03 Mar 2012)
@@ -20,13 +20,14 @@
 
 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 );

Modified: trunk/tools/build/v2/engine/timestamp.c
==============================================================================
--- trunk/tools/build/v2/engine/timestamp.c (original)
+++ trunk/tools/build/v2/engine/timestamp.c 2012-03-03 16:46:53 EST (Sat, 03 Mar 2012)
@@ -71,8 +71,8 @@
 
     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 @@
         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 @@
 
     /* Scan directory if not already done so. */
     {
- BINDING binding;
- BINDING * b = &binding;
+ int found;
+ BINDING * b;
         OBJECT * name;
 
         f2 = f1;
@@ -109,12 +111,15 @@
         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 @@
     /* 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 @@
         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 @@
 
 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;

Modified: trunk/tools/build/v2/engine/variable.c
==============================================================================
--- trunk/tools/build/v2/engine/variable.c (original)
+++ trunk/tools/build/v2/engine/variable.c 2012-03-03 16:46:53 EST (Sat, 03 Mar 2012)
@@ -201,12 +201,9 @@
     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 @@
 
 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;
 }


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk