HAMIGAKI_BJAM_DECL string_list search_for_target(context& ctx) { frame& f = ctx.current_frame(); const list_of_list& args = f.arguments(); const string_list& targets = args[0]; const string_list& path = args[1]; const std::string& name = targets[0]; path_components compo; split_path(compo, name); compo.grist.clear(); compo.member.clear(); bool found = false; std::string filename; for (std::size_t i = 0, size = path.size(); i < size; ++i) { compo.root = path[i]; filename = make_path(compo); if (fs::exists(fs::path(filename))) { found = true; break; } } if (!found) { compo.root.clear(); fs::path ph(make_path(compo)); fs::path work(ctx.working_directory()); filename = fs::complete(ph, work).file_string(); } call_bind_rule(ctx, name, filename); return string_list(name); }
OBJECT * search( OBJECT * target, time_t *time, OBJECT * * another_target, int file ) { PATHNAME f[1]; LIST * varlist; string buf[1]; int found = 0; /* Will be set to 1 if target location is specified via LOCATE. */ int explicitly_located = 0; OBJECT * boundname = 0; OBJECT * varname; if ( another_target ) *another_target = 0; if (! explicit_bindings ) explicit_bindings = hashinit( sizeof(BINDING), "explicitly specified locations"); string_new( buf ); /* Parse the filename */ path_parse( object_str( target ), f ); f->f_grist.ptr = 0; f->f_grist.len = 0; varname = object_new( "LOCATE" ); varlist = var_get( varname ); object_free( varname ); if ( varlist ) { OBJECT * key; f->f_root.ptr = object_str( varlist->value ); f->f_root.len = strlen( object_str( varlist->value ) ); path_build( f, buf, 1 ); if ( DEBUG_SEARCH ) printf( "locate %s: %s\n", object_str( target ), buf->value ); explicitly_located = 1; key = object_new( buf->value ); timestamp( key, time ); object_free( key ); found = 1; } else if ( ( varname = object_new( "SEARCH" ), varlist = var_get( varname ), object_free( varname ), varlist ) ) { while ( varlist ) { BINDING b, *ba = &b; file_info_t *ff; OBJECT * key; OBJECT * test_path; f->f_root.ptr = object_str( varlist->value ); f->f_root.len = strlen( object_str( varlist->value ) ); string_truncate( buf, 0 ); path_build( f, buf, 1 ); if ( DEBUG_SEARCH ) printf( "search %s: %s\n", object_str( target ), 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 ); b.binding = key; if ( hashcheck( explicit_bindings, (HASHDATA**)&ba ) ) { if ( DEBUG_SEARCH ) printf(" search %s: found explicitly located target %s\n", 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 ) { if ( !file || ff->is_file ) { found = 1; object_free( key ); break; } } object_free( key ); varlist = list_next( varlist ); } } if ( !found ) { /* 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; string_truncate( buf, 0 ); path_build( f, buf, 1 ); if ( DEBUG_SEARCH ) printf( "search %s: %s\n", object_str( target ), buf->value ); key = object_new( buf->value ); timestamp( key, time ); object_free( key ); } boundname = object_new( buf->value ); string_free( buf ); if ( explicitly_located ) { BINDING b; BINDING * ba = &b; 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 ) ) { object_free( key ); } } /* prepare a call to BINDRULE if the variable is set */ call_bind_rule( target, boundname ); return boundname; }
TARGET* search_for_target ( char * name, LIST* search_path ) { PATHNAME f[1]; string buf[1]; LOCATED_TARGET lt, *lta = < time_t time; int found = 0; TARGET* result; string_new( buf ); path_parse( name, f ); f->f_grist.ptr = 0; f->f_grist.len = 0; while( search_path ) { f->f_root.ptr = search_path->string; f->f_root.len = strlen( search_path->string ); string_truncate( buf, 0 ); path_build( f, buf, 1 ); lt.file_name = buf->value ; if (! located_targets ) located_targets = hashinit( sizeof(LOCATED_TARGET), "located targets" ); if ( hashcheck( located_targets, (HASHDATA **)<a ) ) { return lta->target; } timestamp( buf->value, &time ); if (time) { found = 1; break; } search_path = list_next( search_path ); } if ( ! found ) { f->f_root.ptr = 0; f->f_root.len = 0; string_truncate( buf, 0 ); path_build( f, buf, 1 ); timestamp( buf->value, &time ); } result = bindtarget( name ); result->boundname = newstr( buf->value ); result->time = time; result->binding = time ? T_BIND_EXISTS : T_BIND_MISSING; call_bind_rule( result->name, result->boundname ); string_free( buf ); return result; }
OBJECT * search( OBJECT * target, time_t *time, OBJECT * * another_target, int file ) { PATHNAME f[1]; LIST * varlist; string buf[1]; int found = 0; /* Will be set to 1 if target location is specified via LOCATE. */ int explicitly_located = 0; OBJECT * boundname = 0; if ( another_target ) *another_target = 0; if (! explicit_bindings ) explicit_bindings = hashinit( sizeof(BINDING), "explicitly specified locations"); string_new( buf ); /* Parse the filename */ path_parse( object_str( target ), f ); f->f_grist.ptr = 0; f->f_grist.len = 0; 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", object_str( target ), buf->value ); explicitly_located = 1; key = object_new( buf->value ); timestamp( key, time ); object_free( key ); found = 1; } else if ( varlist = var_get( root_module(), constant_SEARCH ), !list_empty( varlist ) ) { LISTITER iter = list_begin( varlist ), end = list_end( varlist ); for ( ; iter != end; iter = list_next( iter ) ) { BINDING * ba; file_info_t *ff; OBJECT * key; OBJECT * test_path; 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", object_str( target ), 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 ( ( ba = (BINDING *)hash_find( explicit_bindings, key ) ) ) { if ( DEBUG_SEARCH ) printf(" search %s: found explicitly located target %s\n", 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 ) { if ( !file || ff->is_file ) { found = 1; object_free( key ); break; } } object_free( key ); } } if ( !found ) { /* 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; string_truncate( buf, 0 ); path_build( f, buf, 1 ); if ( DEBUG_SEARCH ) printf( "search %s: %s\n", object_str( target ), buf->value ); key = object_new( buf->value ); timestamp( key, time ); object_free( key ); } boundname = object_new( buf->value ); string_free( buf ); if ( explicitly_located ) { 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. */ 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 */ call_bind_rule( target, boundname ); return boundname; }
OBJECT * search( OBJECT * target, timestamp * const time, OBJECT * * another_target, int const file ) { PATHNAME f[ 1 ]; LIST * varlist; string buf[ 1 ]; int found = 0; OBJECT * boundname = 0; if ( another_target ) *another_target = 0; if ( !explicit_bindings ) explicit_bindings = hashinit( sizeof( BINDING ), "explicitly specified " "locations" ); string_new( buf ); /* Parse the filename. */ path_parse( object_str( target ), f ); f->f_grist.ptr = 0; f->f_grist.len = 0; 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 ); if ( DEBUG_SEARCH ) printf( "locate %s: %s\n", object_str( target ), buf->value ); key = object_new( buf->value ); timestamp_from_path( time, key ); object_free( key ); found = 1; } else if ( varlist = var_get( root_module(), constant_SEARCH ), !list_empty( varlist ) ) { LISTITER iter = list_begin( varlist ); LISTITER const end = list_end( varlist ); for ( ; iter != end; iter = list_next( iter ) ) { BINDING * ba; file_info_t * ff; OBJECT * key; OBJECT * test_path; 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 ); if ( DEBUG_SEARCH ) printf( "search %s: %s\n", object_str( target ), buf->value ); test_path = object_new( buf->value ); key = path_as_key( test_path ); object_free( test_path ); ff = file_query( key ); timestamp_from_path( time, key ); if ( ( ba = (BINDING *)hash_find( explicit_bindings, key ) ) ) { if ( DEBUG_SEARCH ) printf(" search %s: found explicitly located target %s\n", object_str( target ), object_str( ba->target ) ); if ( another_target ) *another_target = ba->target; found = 1; object_free( key ); break; } else if ( ff ) { if ( !file || ff->is_file ) { found = 1; object_free( key ); break; } } object_free( key ); } } if ( !found ) { /* 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; string_truncate( buf, 0 ); path_build( f, buf ); if ( DEBUG_SEARCH ) printf( "search %s: %s\n", object_str( target ), buf->value ); key = object_new( buf->value ); timestamp_from_path( time, key ); object_free( key ); } boundname = object_new( buf->value ); string_free( buf ); /* Prepare a call to BINDRULE if the variable is set. */ call_bind_rule( target, boundname ); return boundname; }