#include<stdio.h>
#include<stdlib.h>
#include<stddef.h>

#define  align(d)       (((d)+(sizeof(void*)-1))&(~(sizeof(void*)-1)))

#define HEAPIMPLEMENTATION

typedef struct{
   struct heap_block *first;
   struct heap_block *last;
   long blocksize;
   char *top_of_heap;
}heap;

struct heap_block{
   struct heap_block *next;
   long free;
};

#include"heap.h"

heap *heap_create( long block_size )          /* allocates memory for heap */
{
   heap *HEAP;
   HEAP = ( heap * )malloc( align( block_size) + sizeof(heap)+sizeof(struct heap_block));
   if(NULL == HEAP)return(NULL);
   HEAP->first = (struct heap_block*)(HEAP+1);
   HEAP->last = HEAP->first;
   HEAP->blocksize = align( block_size );
   HEAP->top_of_heap = (char *)(HEAP->last+1); /* next free entry */
   HEAP->first->next = NULL;
   HEAP->first->free = block_size;
   return(HEAP);
}                                               /* heap_create() */


void *heap_allocate( heap *HEAP, long size ) /* allocates on heap */
{
   void *help;
   if ( HEAP->last->free < size )
   {
       if( NULL ==(HEAP->last->next = ( struct heap_block * )malloc( HEAP->blocksize+sizeof(struct heap_block))))return(NULL);
       HEAP->last = HEAP->last->next;
       HEAP->last->next = NULL;
       HEAP->last->free = HEAP->blocksize;
       HEAP->top_of_heap = (void *)(HEAP->last+1); /* next free entry */
   }
   help = HEAP->top_of_heap;
   HEAP->top_of_heap += (align(size) + sizeof(char) -1) / sizeof(char);
   HEAP->last->free -= align(size);
   return(help);
}                                                   /* heap_allocate() */
void heap_resize( heap *HEAP, void *entry, long size )
{
   HEAP->last->free += HEAP->top_of_heap - ( (char *)entry + align( size ) );
   HEAP->top_of_heap = (char *)entry + align( size );
}                                                                               /* heap_resize() */

void heap_delete( heap *HEAP )
{
   struct heap_block *this, *next;
   this = HEAP->first;
       free(HEAP);
       while(this)
       {
               next = this->next;
               free(this);
               this = next;
       }                                               /* of while(this) */
}                                                       /* of heap_delete() */