#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "emsg.h"
#define MAXLIST 13000
static void *list[MAXLIST];
static char *list_file[MAXLIST];
static int list_line[MAXLIST];
static int list_size[MAXLIST];
static int nlist;
static int upto;
int d_upto(void)
{
	for (;upto<MAXLIST; upto++) {
		if (list[upto]==NULL) break;
	}
	if (list[upto]!=NULL) for (upto=0;upto<MAXLIST; upto++) {
		if (list[upto]==NULL) break;
	}
	if (list[upto]!=NULL) {
		printf("DMalloc failed\n");
		exit(0);
	}
	return upto;
}
void *d_malloc(int sz, char *file, int line)
{
	void *m = malloc(sz);
	upto = d_upto();
	list_file[upto] = file;
	list_line[upto] = line;
	list_size[upto] = sz;
	list[upto] = m;
	if (nlist<=upto) nlist = upto+1;
	return m;
}
void d_free(void *x, char *file, int line)
{
	int i;
	for (i=0; i<nlist; i++) {
		if (list[i] == x) {

			free(x); list[i] = NULL; return;
		}
	}
	imsg("Invalid free for pointer %p %s:%d\n",x,file,line);
	printf("contents %s\n",x);
	abort();
}
char *d_strdup(const char *s, char *file, int line)
{
	char *x = malloc(strlen(s)+1);
	int upto = d_upto();
	list_file[upto] = file;
	list_line[upto] = line;
	list_size[upto] = strlen(s)+1;
	list[upto] = (void *) x;
	if (nlist<=upto) nlist = upto+1;
	strcpy(x,s);
	return x;
}
int d_total(void)
{
	int i;
	int t=0;
	for (i=0; i<nlist; i++) {
		if (list[i]!=NULL) {
			t += list_size[i];
		}
	}
	return t;

}
void d_check(void)
{
	int i;
	int nbad=0;
	imsg("d_check called, nlist=%d\n",nlist);
	for (i=0; i<nlist; i++) {
		if (list[i]!=NULL) {
			imsg("Unfreed memory (%p) %s:%d (%s)\n",list[i],list_file[i],list_line[i],list[i]);
			nbad++;
		}
	}
	if (nbad==0) imsg("All memory correctly freed\n");
}