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:
@@ -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 )
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
|
||||
@@ -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 )
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 );
|
||||
|
||||
208
v2/engine/hash.c
208
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
|
||||
|
||||
|
||||
/* ---- */
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 ) );
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user