LIST * order( FRAME * frame, int flags ) { LIST * arg = lol_get( frame->args, 0 ); LIST * result = L0; int src; LISTITER iter = list_begin( arg ); LISTITER const end = list_end( arg ); /* We need to create a graph of order dependencies between the passed * objects. We assume there are no duplicates passed to 'add_pair'. */ int length = list_length( arg ); int * * graph = ( int * * )BJAM_CALLOC( length, sizeof( int * ) ); int * order = ( int * )BJAM_MALLOC( ( length + 1 ) * sizeof( int ) ); for ( src = 0; iter != end; iter = list_next( iter ), ++src ) { /* For all objects this one depends upon, add elements to 'graph'. */ LIST * dependencies = var_get( frame->module, list_item( iter ) ); int index = 0; LISTITER dep_iter = list_begin( dependencies ); LISTITER const dep_end = list_end( dependencies ); graph[ src ] = ( int * )BJAM_CALLOC( list_length( dependencies ) + 1, sizeof( int ) ); for ( ; dep_iter != dep_end; dep_iter = list_next( dep_iter ) ) { int const dst = list_index( arg, list_item( dep_iter ) ); if ( dst != -1 ) graph[ src ][ index++ ] = dst; } graph[ src ][ index ] = -1; } topological_sort( graph, length, order ); { int index = length - 1; for ( ; index >= 0; --index ) { int i; LISTITER iter = list_begin( arg ); LISTITER const end = list_end( arg ); for ( i = 0; i < order[ index ]; ++i, iter = list_next( iter ) ); result = list_push_back( result, object_copy( list_item( iter ) ) ); } } /* Clean up */ { int i; for ( i = 0; i < length; ++i ) BJAM_FREE( graph[ i ] ); BJAM_FREE( graph ); BJAM_FREE( order ); } return result; }
LIST *order( PARSE *parse, FRAME *frame ) { LIST* arg = lol_get( frame->args, 0 ); LIST* tmp; LIST* result = 0; int src; /* We need to create a graph of order dependencies between the passed objects. We assume that there are no duplicates passed to 'add_pair'. */ int length = list_length(arg); int** graph = (int**)BJAM_CALLOC(length, sizeof(int*)); int* order = (int*)BJAM_MALLOC((length+1)*sizeof(int)); for(tmp = arg, src = 0; tmp; tmp = tmp->next, ++src) { /* For all object this one depend upon, add elements to 'graph' */ LIST* dependencies = var_get(tmp->string); int index = 0; graph[src] = (int*)BJAM_CALLOC(list_length(dependencies)+1, sizeof(int)); for(; dependencies; dependencies = dependencies->next) { int dst = list_index(arg, dependencies->string); if (dst != -1) graph[src][index++] = dst; } graph[src][index] = -1; } topological_sort(graph, length, order); { int index = length-1; for(; index >= 0; --index) { int i; tmp = arg; for (i = 0; i < order[index]; ++i, tmp = tmp->next); result = list_new(result, tmp->string); } } /* Clean up */ { int i; for(i = 0; i < length; ++i) BJAM_FREE(graph[i]); BJAM_FREE(graph); BJAM_FREE(order); } return result; }
void topological_sort(int** graph, int num_vertices, int* result) { int i; int* colors = (int*)BJAM_CALLOC(num_vertices, sizeof(int)); for (i = 0; i < num_vertices; ++i) colors[i] = white; for(i = 0; i < num_vertices; ++i) if (colors[i] == white) do_ts(graph, i, colors, &result); BJAM_FREE(colors); }