2
0
mirror of https://github.com/boostorg/build.git synced 2026-02-15 13:02:11 +00:00

Fix alias violations in hash.

[SVN r77190]
This commit is contained in:
Steven Watanabe
2012-03-03 21:46:53 +00:00
parent b9cf446bfb
commit ceacd17a2c
17 changed files with 377 additions and 359 deletions

View File

@@ -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 )

View File

@@ -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 );
}

View File

@@ -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 )
{

View File

@@ -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;

View File

@@ -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 );

View File

@@ -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
/* ---- */

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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 ) );

View File

@@ -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 );
}

View File

@@ -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;
}
}

View File

@@ -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 = &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 @@ 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 = &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 );

View File

@@ -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 = &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 * 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 );

View File

@@ -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 );
}

View File

@@ -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 );

View File

@@ -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;

View File

@@ -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;
}