diff options
Diffstat (limited to 'tools/build/v2/engine/search.c')
-rw-r--r-- | tools/build/v2/engine/search.c | 145 |
1 files changed, 87 insertions, 58 deletions
diff --git a/tools/build/v2/engine/search.c b/tools/build/v2/engine/search.c index 6c23d97a14..e3d287a679 100644 --- a/tools/build/v2/engine/search.c +++ b/tools/build/v2/engine/search.c @@ -16,7 +16,7 @@ #include "timestamp.h" #include "pathsys.h" #include "variable.h" -#include "newstr.h" +#include "object.h" #include "compile.h" #include "strings.h" #include "hash.h" @@ -26,8 +26,8 @@ typedef struct _binding { - char * binding; - char * target; + OBJECT * binding; + OBJECT * target; } BINDING; static struct hash *explicit_bindings = 0; @@ -35,22 +35,15 @@ static struct hash *explicit_bindings = 0; void call_bind_rule ( - char * target_, - char * boundname_ + OBJECT * target_, + OBJECT * boundname_ ) { - LIST * bind_rule = var_get( "BINDRULE" ); - if ( bind_rule ) + LIST * bind_rule = var_get( root_module(), constant_BINDRULE ); + if ( !list_empty( bind_rule ) ) { - /* No guarantee that the target is an allocated string, so be on the - * safe side. - */ - char * target = copystr( target_ ); - - /* Likewise, do not rely on implementation details of newstr.c: allocate - * a copy of boundname. - */ - char * boundname = copystr( boundname_ ); + OBJECT * target = object_copy( target_ ); + OBJECT * boundname = object_copy( boundname_ ); if ( boundname && target ) { /* Prepare the argument list. */ @@ -58,11 +51,11 @@ void call_bind_rule frame_init( frame ); /* First argument is the target name. */ - lol_add( frame->args, list_new( L0, target ) ); + lol_add( frame->args, list_new( target ) ); - lol_add( frame->args, list_new( L0, boundname ) ); + lol_add( frame->args, list_new( boundname ) ); if ( lol_get( frame->args, 1 ) ) - evaluate_rule( bind_rule->string, frame ); + list_free( evaluate_rule( list_front( bind_rule ), frame ) ); /* Clean up */ frame_free( frame ); @@ -70,9 +63,9 @@ void call_bind_rule else { if ( boundname ) - freestr( boundname ); + object_free( boundname ); if ( target ) - freestr( target ); + object_free( target ); } } } @@ -93,21 +86,21 @@ void call_bind_rule * the third argument. */ -char * +OBJECT * search( - char *target, + OBJECT * target, time_t *time, - char **another_target, + OBJECT * * another_target, int file ) { PATHNAME f[1]; - LIST *varlist; - string buf[1]; - int found = 0; + LIST * varlist; + string buf[1]; + int found = 0; /* Will be set to 1 if target location is specified via LOCATE. */ - int explicitly_located = 0; - char *boundname = 0; + int explicitly_located = 0; + OBJECT * boundname = 0; if ( another_target ) *another_target = 0; @@ -119,55 +112,64 @@ search( string_new( buf ); /* Parse the filename */ - path_parse( target, f ); + path_parse( object_str( target ), f ); f->f_grist.ptr = 0; f->f_grist.len = 0; - if ( ( varlist = var_get( "LOCATE" ) ) ) - { - f->f_root.ptr = varlist->string; - f->f_root.len = strlen( varlist->string ); + varlist = var_get( root_module(), constant_LOCATE ); + if ( !list_empty( varlist ) ) + { + OBJECT * key; + f->f_root.ptr = object_str( list_front( varlist ) ); + f->f_root.len = strlen( object_str( list_front( varlist ) ) ); path_build( f, buf, 1 ); if ( DEBUG_SEARCH ) - printf( "locate %s: %s\n", target, buf->value ); + printf( "locate %s: %s\n", object_str( target ), buf->value ); explicitly_located = 1; - timestamp( buf->value, time ); + key = object_new( buf->value ); + timestamp( key, time ); + object_free( key ); found = 1; } - else if ( ( varlist = var_get( "SEARCH" ) ) ) + else if ( varlist = var_get( root_module(), constant_SEARCH ), !list_empty( varlist ) ) { - while ( varlist ) + LISTITER iter = list_begin( varlist ), end = list_end( varlist ); + for ( ; iter != end; iter = list_next( iter ) ) { - BINDING b, *ba = &b; + BINDING * ba; file_info_t *ff; + OBJECT * key; + OBJECT * test_path; - f->f_root.ptr = varlist->string; - f->f_root.len = strlen( varlist->string ); + f->f_root.ptr = object_str( list_item( iter ) ); + f->f_root.len = strlen( object_str( list_item( iter ) ) ); string_truncate( buf, 0 ); path_build( f, buf, 1 ); if ( DEBUG_SEARCH ) - printf( "search %s: %s\n", target, buf->value ); - - ff = file_query(buf->value); - timestamp( buf->value, time ); + printf( "search %s: %s\n", object_str( target ), buf->value ); - b.binding = buf->value; + test_path = object_new( buf->value ); + key = path_as_key( test_path ); + object_free( test_path ); + ff = file_query( key ); + timestamp( key, time ); - 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", - target, ba->target); + object_str( target ), object_str( ba->target ) ); if ( another_target ) *another_target = ba->target; found = 1; + object_free( key ); break; } else if ( ff && ff->time ) @@ -175,11 +177,11 @@ search( if ( !file || ff->is_file ) { found = 1; + object_free( key ); break; } } - - varlist = list_next( varlist ); + object_free( key ); } } @@ -188,6 +190,7 @@ search( /* Look for the obvious */ /* This is a questionable move. Should we look in the */ /* obvious place if SEARCH is set? */ + OBJECT * key; f->f_root.ptr = 0; f->f_root.len = 0; @@ -196,24 +199,34 @@ search( path_build( f, buf, 1 ); if ( DEBUG_SEARCH ) - printf( "search %s: %s\n", target, buf->value ); + printf( "search %s: %s\n", object_str( target ), buf->value ); - timestamp( buf->value, time ); + key = object_new( buf->value ); + timestamp( key, time ); + object_free( key ); } - boundname = newstr( buf->value ); + boundname = object_new( buf->value ); string_free( buf ); if ( explicitly_located ) { - BINDING b; - BINDING * ba = &b; - b.binding = boundname; - b.target = target; + int found; + BINDING * ba; + OBJECT * key = path_as_key( boundname ); /* CONSIDER: we probably should issue a warning is another file is explicitly bound to the same location. This might break compatibility, though. */ - 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 ); + } } /* prepare a call to BINDRULE if the variable is set */ @@ -221,3 +234,19 @@ search( return boundname; } + + +static void free_binding( void * xbinding, void * data ) +{ + BINDING * binding = (BINDING *)xbinding; + object_free( binding->binding ); +} + +void search_done( void ) +{ + if ( explicit_bindings ) + { + hashenumerate( explicit_bindings, free_binding, (void *)0 ); + hashdone( explicit_bindings ); + } +} |