
/*
* Here is a debug wrapper for the malloc() library routine, which  has  caused
* us  no  end of grief on a lot of systems.  It is convenient to make Malloc()
* and MallocM() default to (void*). This forces everyone to explicitly case it
* to the type they want.  Of course, this does make the code a bit wordier. It
* would be better if there were  a  way  to  return  a  universally-acceptable
* pointer,  but  modern  C  no  longer allows this, so we return a universally
* unacceptable pointer instead and force the caller to do a cast in all cases.
* Note that we use the 'M' debug flag here and in d_free() and d_realloc(), so
* the caller can easily enable the space-allocation messages.  This  might  be
* done  to  spot  memory leaks.  Debug level "M6" is the appropriate level for
* this.
*/
#include "V_M_UC.h"
#include "sys_stdlib.h"
#include "sys_malloc.h"

global char m_malloc[] = "### Can't get %d bytes for %s [Err %d=%s=%s]";

void* d_malloc(n,m)
	Sizt  n;
	char* m;
{	void* v=0;
	int   e=errno;
	Sizt  i;
	V8M "d_malloc(%d,%08X) called.",n,m D;
	if (!m) m = m_unnamed;
	V8M "d_malloc(%d,\"%s\") called.",n,m D;
	if (n <= 0) {
		errno = EINVAL;
		P2 m_nomem,pname,n,m,Errinfo D;
		Fail;
	}
	V8M "malloc: Get %d+%d bytes for %s.",n,Mfudge,m D;

	i = n + Mfudge;
	V8M "Before malloc(%u)",i D;
	v = (void*)malloc(i);
	e = errno;
	V8M "After  malloc(%d)=%04X",i,v D;
	if (!v) {
		P2 m_nomem,pname,i,m,Errinfo D;
		Fail;
	}
	V9M "malloc: Zero %d bytes at %08X...",n,v D;
	BZero(v,i);		/* Make sure it's zeroed */
	errno = e;
	V7M "malloc(%d)=%08X %d bytes [%s]",n,v,i,m D;
	if ((!v) && (errno = e))
		V5M m_malloc,n,m,Errinfo D;
fail:
	return v;
}
