void track_delete(struct Track* track) { if (track != NULL) { cdtext_delete(track_get_cdtext(track)); rem_free(track_get_rem(track)); free(track->isrc); free(track->zero_pre.name); free(track->zero_post.name); free(track->file.name); free(track); } }
void cd_delete(struct Cd* cd) { int i = 0; if (cd != NULL) { free(cd->catalog); free(cd->cdtextfile); for (i = 0; i < cd->ntrack; i++) track_delete(cd->track[i]); cdtext_delete(cd_get_cdtext(cd)); rem_free(cd_get_rem(cd)); free(cd); } }
/************************************************************* * move a block of memory from the data chain to the free chain * merge with next & previous blocks if possible */ static void release_block( register tMemHdr *tr ) { register tMemHdr *t0; register tMemHdr *t1; assert( tr == NULL || tr->next_mem == NULL || tr->next_mem->prev_mem == tr ); assert( tr == NULL || tr->prev_mem == NULL || tr->prev_mem->next_mem == tr ); assert( tr == NULL || tr->next_list == NULL || tr->next_list->prev_list == tr ); assert( tr == NULL || tr->prev_list == NULL || tr->prev_list->next_list == tr ); assert( check_block(tr) ); assert( ISDATA(tr) ); total_free += tr->size; total_used -= tr->size; *tr->pbase = NULL; /* tell application this block has been released */ tr->pbase = NULL; /* flag this block as free */ t0 = tr->prev_list; t1 = tr->next_list; if( t0 == NULL ) { head_data = t1; } else { t0->next_list = t1; } /* if */ if( t1 == NULL ) { tail_data = t0; } else { t1->prev_list = t0; } /* if */ /** block removed from data chain, now try merge with next, previous **/ t1 = tr->next_mem; if( t1 != NULL && ISFREE(t1) ) { /** we can absorb the next mem block **/ #ifdef TEST merged_next++; dprintf(( "merging block(%ld, size %ld) & following(%ld, size %ld)\n", (long)tr->data[0], (long)tr->size, (long)tr->next_mem->data[0], (long)tr->next_mem->size )); #endif rem_free( t1 ); /** remove next from free list **/ /** remove tr->next_mem from memory list **/ tr->size += t1->size + sizeof(tMemHdr); tr->next_mem = t0 = t1->next_mem; if( t0 != NULL ) { t0->prev_mem = tr; } /* if */ assert( tr->next_mem == NULL || tr->next_mem->prev_mem == tr ); assert( tr->next_mem == NULL || (uint32)tr + sizeof(tMemHdr) + tr->size == (uint32)tr->next_mem ); dprintf(( "size of merged block is %ld\n", (long)tr->size )); total_free += sizeof( tMemHdr ); nr_blocks--; } /* if */ assert( total_free + total_used + (nr_blocks-1)*sizeof(tMemHdr) == total_size ); t0 = tr->prev_mem; if( t0 != NULL && ISFREE(t0) ) { /** we can merge into the prev mem block **/ #ifdef TEST dprintf(( "merging block(%ld, size %ld) & previous(%ld, size %ld)\n", (long)tr->data[0], (long)tr->size, (long)tr->prev_mem->data[0], (long)tr->prev_mem->size )); merged_prev++; #endif rem_free( t0 ); /** remove prev from free list **/ /** remove tr from memory list **/ t1 = t0->next_mem = tr->next_mem; if( t1 != NULL ) { t1->prev_mem = t0; } /* if */ assert( t0->next_mem == NULL || t0->next_mem->prev_mem == t0 ); assert( t1 == NULL || t1->prev_mem->next_mem == t1 ); t0->size += tr->size + sizeof( tMemHdr ); total_free += sizeof( tMemHdr ); nr_blocks--; tr = t0; /* tr is adr of merged block */ dprintf(( "size of merged block is %ld\n", (long)tr->size )); assert( tr->next_mem == NULL || (uint32)tr + sizeof(tMemHdr) + tr->size == (uint32)tr->next_mem ); assert( tr->next_mem == NULL || tr->next_mem->prev_mem == tr); } /* if */ assert( total_free + total_used + (nr_blocks-1)*sizeof(tMemHdr) == total_size ); add_free( tr ); assert( check_cache() ); } /* release_block() */