Generator/RB_Sort_Items [ Functions ]
FUNCTION
Sort the items in all the headers according to the order specified in the 'item order' block in the robodoc.rc file.
SYNOPSIS
static void RB_Sort_Items( struct RB_header **headers, long header_count )
SOURCE
{ int n_order = configuration.item_order.number; if ( n_order ) { int i = 0; int j = 0; int max_number_of_items = 0; struct RB_Item **items = NULL; struct RB_Item **items_sorted = NULL; RB_Say( "Sorting items in %d headers.\n", SAY_DEBUG, header_count ); /* Compute the maximum number of items in any given header */ for ( j = 0; j < header_count; ++j ) { struct RB_header *header; struct RB_Item *item; int item_count = 0; header = headers[j]; for ( item = header->items; item; item = item->next ) { ++item_count; } if ( item_count > max_number_of_items ) { max_number_of_items = item_count; } } /* Allocate an array for the items, this makes it easier to * sort. */ RB_Say( "Largest header has %d items.\n", SAY_DEBUG, max_number_of_items ); if ( max_number_of_items == 0 ) { /* No items in any of the headers, do nothing */ } else { items = calloc( max_number_of_items, sizeof( struct RB_Item * ) ); items_sorted = calloc( max_number_of_items, sizeof( struct RB_Item * ) ); /* Sort items */ for ( j = 0; j < header_count; ++j ) { struct RB_header *header = NULL; struct RB_Item *item = NULL; int item_index = 0; int sorted_item_index = 0; int item_count = 0; header = headers[j]; /* Copy item pointers to array */ for ( item = header->items; item; item = item->next, ++item_index ) { items[item_index] = item; items_sorted[item_index] = item; }; item_count = item_index; if ( item_count == 0 ) { /* No items in this header, do nothing. */ } else { assert( item_count <= max_number_of_items ); /* First copy the items in the order that is defined in * item_order[] to sorted_items[] */ sorted_item_index = 0; for ( i = 0; i < n_order; ++i ) { for ( item_index = 0; item_index < item_count; ++item_index ) { if ( items[item_index] ) { if ( strcmp ( configuration.items. names[items[item_index]->type], configuration.item_order.names[i] ) == 0 ) { /* copy to items_sorted */ items_sorted[sorted_item_index] = items[item_index]; ++sorted_item_index; items[item_index] = NULL; } } } } /* Then copy the remaining items to items_sorted[] */ for ( item_index = 0; item_index < item_count; ++item_index ) { if ( items[item_index] ) { /* copy to items_sorted */ items_sorted[sorted_item_index] = items[item_index]; ++sorted_item_index; items[item_index] = NULL; } } assert( sorted_item_index == item_count ); /* Now copy the items in items_sorted[] back into the linked list in * the header */ if ( item_count > 1 ) { /* Chain all the items */ for ( item_index = 0; item_index < item_count - 1; ++item_index ) { items_sorted[item_index]->next = items_sorted[item_index + 1]; } } assert( item_count > 0 ); items_sorted[item_count - 1]->next = NULL; /* now link the first item to the header. */ header->items = items_sorted[0]; } } free( items_sorted ); free( items ); } } RB_Say( "Done sorting items in %d headers.\n", SAY_DEBUG, header_count ); }