#include "config.h"

#ifdef MEM_CHECK

#include "externs.h"
#include "mem_check.h"

#ifdef USE_NALLOC
#include "nalloc.h"
NALLOC *glub = NULL;
#endif

MEM *my_check = NULL;

void add_check(ref)
    char *ref;
{
  MEM *loop;

#ifdef USE_NALLOC
  if(!glub)
    glub = na_open(1);
#endif
  for(loop = my_check; loop; loop = loop->next) {
    if(!string_compare(ref, loop->ref_name)) {
      loop->ref_count++;
      return;
    }
  }
#ifdef USE_NALLOC
  loop = (MEM *) na_alloc(glub, sizeof(MEM));
#else
  loop = (MEM *) malloc(sizeof(MEM));
#endif
  loop->ref_name = ref;
  loop->ref_count = 1;
  loop->next = my_check;
  my_check = loop;
  add_check("mem_check");
  return;
}

void del_check(ref)
  char *ref;
{
  MEM *loop;

#ifdef USE_NALLOC  
  if(!glub) {
    fprintf(stderr,
	    "ERROR: can't delete %s if no pointers exist.\n", ref);
    return;
  }
#endif
  for(loop = my_check; loop; loop = loop->next) {
    if(!string_compare(loop->ref_name, ref)) {
      loop->ref_count--;
      if(!loop->ref_count) {
	rebuild_check();
	del_check("mem_check");
      }
      return;
    }
  }
  fprintf(stderr,
          "ERROR: Tried deleteing a check that was never added! :%s\n", ref);
}

void rebuild_check()
{
  MEM *point, *next, *new = NULL;
  
  point = my_check;
  while (point) {
    next = point->next;
    if(point->ref_count) {
      point->next = new;
      new = point;
    } else {
#ifdef USE_NALLOC
      na_unalloc(glub, point);
#else
      free((char *)point);
#endif
    }
    point = next;
  }
  my_check = new;
}

void list_mem_check(player)
    dbref player;
{

  MEM *loop;

  for(loop = my_check; loop; loop = loop->next) {
    notify(player, tprintf("%s : %d", loop->ref_name, loop->ref_count));
  }
}

#endif /* MEM_CHECK */