#include "jcabc2ps.h"
#include "memBlock.h"

int mempad = 0;		// Pad chars to add to mallocs

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Allocate, reallocate or free a chunk of memory.  This  is  a  debug  wrapper
* around  the  library  malloc() functions.   We now support three different ways
* of allocating memory, depending on the variable.
*/
void* memBlock(
	void*  ptr,		// Block to reallocate, if any
	size_t oldsize,	// Size of old block
	size_t newsize,	// Min size of new block
	char*  dsc)		// Description, for messages
{	void*  val=0;
	int    i;
	char*  F="memBlock";
//	V3 "%s: ptr=%X oldsize=%d newsize=%d mempad=%d \"%s\"\n"
//		,F,ptr,oldsize,newsize,mempad,dsc V;
	newsize += mempad;
	unless (ptr || newsize>0) return val;
	unless (dsc) dsc = "???";
	unless (ptr) {	// No old block; allocate a new one.
		if (newsize == 0) {
			V6 "%s: No old block; no new block requested.\n",F V;
			return val;
		}
		V6 "%s: malloc(%zu) for \"%s\"\n",F,newsize,dsc V;
		unless (val = (void*)malloc(newsize)) {
			V1 "%s: ### Can't get %zu bytes [OUT OF MEMORY]\n",F,newsize V;
			return 0;
		}
		V6 "%s: Got %08X for \"%s\"\n",F,(uint)val,dsc V;
		bzero(val,newsize);
		return val;
	}
//	if (chkchunks) chkblock(ptr,oldsize,"old memchunk");	// Sanity test
	unless (newsize > 0) {	// Just free the old block
		free(ptr);
		return val;
	}
	V5 "%s: Enlarge: %08X (%s) from %zu to %zu bytes.\n",F,(uint)ptr,dsc,oldsize,newsize V;
	unless (val = (void*)malloc(newsize)) {
		V1 "%s: ### Can't enlarge %08lX (%s) from %zu to %zu bytes [OUT OF MEMORY]\n",F,
			(ulong)ptr,dsc,oldsize,newsize V;
		return 0;
	}
	bcopy(ptr,val,oldsize);
//	if (chkchunks) chkblock(val,newsize,"new memchunk");
	bzero(ptr+oldsize,oldsize-newsize);
	V5 "%s: Enlarged %08lX (%s) from %zu to %zu bytes.\n",F,(ulong)ptr,dsc,oldsize,newsize V;
	free(ptr);
	V5 "%s: Return %08lX newsize=%zu for \"%s\"\n",F,(ulong)val,newsize,dsc V;
	return val;
}

