#include	<stdio.h>

typedef struct memitem {
	struct memitem	*next;
	char		*location;
} MemItem;

MemItem		*firstmem = NULL;
int		debuglevel = 0;

char	*
calloctrace (items, size)
unsigned items;
unsigned size;
{
	char	*foo;
	foo = (char *) calloc (items, size);
	addmem(foo);
	return (foo);
}
	

char *
realloctrace(ptr, size)
void	*ptr;
unsigned size;
{
	char	*foo;
	foo = (char *) realloc (ptr, size);
	if (foo != ptr) {
		delmem (ptr, "Internal realloc");
		addmem(foo);
	}
	return (foo);
}

char *
malloctrace(size)
unsigned size;
{
	char	*foo;
	foo = (char *) malloc (size);
	addmem(foo);
	return (foo);
}

freetrace(foo, bar)
char	*foo;
char	*bar;
{
	delmem(foo, bar);
	if (foo)
		free(foo);
	else if (debuglevel)
		printf ("Not freeing null pointer from %s\n", bar);
}

addmem(foo)
char	*foo;
{
	MemItem	*ptr;
	if (firstmem == NULL) {
		firstmem = (MemItem *) calloc (1, sizeof (MemItem));
		ptr = firstmem;
	}
	else {
		ptr = firstmem;
		while (ptr->next)
			ptr = ptr->next;
		ptr->next = (MemItem *) calloc (1, sizeof (MemItem));
		ptr = ptr->next;
	}
	ptr->next = NULL;
	ptr->location = foo;
	if (debuglevel > 1)
		printf ("allocated %x\n",foo);
}

delmem(foo, bar)
char	*foo;
char	*bar;
{
	MemItem	*parent, *child;
	if (foo == NULL)
		return(0);
	if (firstmem == NULL) {
		printf ("ERROR!  Trying to free %x from %s when NO MEMORY has ever been allocated!!\n");
		return(0);
	}
	else {
		parent = firstmem;
		if (parent->location == foo) {
			firstmem = parent->next;
			free(parent);
			if (debuglevel > 1)
				printf ("freeing valid %x from %s\n",foo, bar);
			return(0);
		}
		while (parent->next) {
			child = parent->next;
			if (child->location == foo) {
				if (debuglevel > 1)
					printf ("freeing valid %x from %s\n",foo, bar);
				parent->next = child->next;
				free(child);
				return(0);
			}
			parent = child;
		}
		printf ("ERROR!  Freeing never-malloced %x from %s\n",foo, bar);
	}
}
