/*---------------------------------------------------------------------
 * 
 *
 *             Copyright (c) 1988, Visual Edge Software Ltd.
 *
 * ALL  RIGHTS  RESERVED.  Permission  to  use,  copy,  modify,  and
 * distribute  this  software  and its documentation for any purpose
 * and  without  fee  is  hereby  granted,  provided  that the above
 * copyright  notice  appear  in  all  copies  and  that  both  that
 * copyright  notice and this permission notice appear in supporting
 * documentation,  and that  the name of Visual Edge Software not be
 * used  in advertising  or publicity  pertaining to distribution of
 * the software without specific, written prior permission. The year
 * included in the notice is the year of the creation of the work.
 *-------------------------------------------------------------------*/


/* the general memory allocator for Visual Edge products;

   This file consists of routines that should be used in place of
   malloc calls.  It eventually calls malloc to get memory, but does
   some nifty error checking.  If the system malloc call returns a NULL
   pointer (out of memory), this will abort the program.

   The memory subsystem requires catalog 
   subssytem to work.  Please refer to the docs on the 
   catalog subsystem for info on how to link with them.

   The include file "valloc.h" should be included in all your
   application programs that uses UxMalloc et al.

.VERSION
 090813		last modif KB

----------------------------------------------------------------------------*/

#include <stdlib.h>
#include <stdio.h>
#include <valloc.h>

#include "uimx_cat.h"
#include "valloc_ds.h"
#define	CGETS(x,y) UxCatGets(MC_VALLOC,(x),(y))

#define	NO_MEMORY	1

#ifdef SAFE_MALLOC
#define malloc(S) calloc((S),(size_t)1)
#endif

extern void UxStandardError();


static	char	*fmt;

/*****************************************************************************
NAME:		char *UxNoMemory(ptr, sz)
INPUT:		char	*ptr		- previous pointer when called from
					  UxRealloc
		unsigned sz		- number of bytes requested
RETURN: 	char *			- pointer to allocated space, or NULL
DESCRIPTION:	Repeatedly attempts to allocate space, requesting commands
		from the user at each step
CREATION:	4 July 1989
REVISIONS:	--
-----------------------------------------------------------------------------*/

char	*UxNoMemory(ptr, sz)
	char	 *ptr;
	unsigned sz;
{
	UxStandardError(fmt, (int)sz);
	abort();
	return(NULL);
}


/*****************************************************************************
NAME:		void *UxMalloc(sz)
DESCRIPTION:	Replaces malloc(), checks return value automatically.
CREATION:	4 July 1989
REVISIONS:	--
-----------------------------------------------------------------------------*/

void	*UxMalloc(sz)
	unsigned sz;
{
	void	 *rtrn;

	if (sz == 0)
		return NULL;

	rtrn = (void *) malloc((size_t)sz);
	if (rtrn == NULL)
		rtrn = UxNoMemory(NULL, sz);
	return(rtrn);
}

/*****************************************************************************
NAME:		void *UxCalloc(sz)
DESCRIPTION:	Replaces calloc(), checks return value automatically.
CREATION:	4 July 1989
REVISIONS:	--
-----------------------------------------------------------------------------*/

void 	*UxCalloc(n, sz)
	unsigned n, sz;
{
	void	 *rtrn;
	
	if ((sz == 0) || (n == 0))
	    	return NULL;

	rtrn = (void *) calloc(n, sz);

	if (rtrn == NULL)
		rtrn = UxNoMemory(NULL, n * sz);

	return(rtrn);
}

/*****************************************************************************
NAME:		void *UxRealloc(sz)
DESCRIPTION:	Replaces realloc(), checks return value automatically.
CREATION:	4 July 1989
REVISIONS:	--
-----------------------------------------------------------------------------*/

void 	*UxRealloc(ptr, sz)
	void 	 *ptr;
	unsigned sz;
{
	void	 *rtrn= ptr;
	
	if (sz == 0)
	    	return ptr;

	if (ptr)
		rtrn = (void *) realloc(ptr, (size_t)sz); 
	else
		rtrn = (void *) malloc((size_t)sz);

	if (rtrn == NULL)
		rtrn = UxNoMemory(ptr, sz);

	return(rtrn);
}


/*---------------------------------------------------------------------------*/

void UxFree (p)
   void *p;
{
   if (p != (void *) 0) free (p);
}
/*****************************************************************************
NAME:		void UxInitMallocMsg()
INPUT:		None
CREATION:	22/08/90
REVISIONS:	--
-----------------------------------------------------------------------------*/
void	UxInitMallocMsg()
{
	fmt = UxCopyString(CGETS(MS_VL_ATMPTOALLCBYTES, DS_MS_VL_ATMPTOALLCBYTES));
}
