/*
 * NAME
 *   MemAlloc.c
 * DESCRIPTION
 *   Routines for memory allocation with simple exception handling.
 * COPYRIGHT
 *   MemAlloc - Memory allocation routines.
 *   Copyright (C) 1995  Rene W.J. Pijlman
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation; either version 2 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program; if not, write to the Free Software
 *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 * VERSION
 *   /home/rene/sys/CVS_MasterSourceRepository/skim/MemAlloc.c,v 1.2 1995/08/14 17:06:57 rpijlman Exp
 *   Distributed with Skim version 0.6.
 */

#include "MemAlloc.h"

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


static void Terminate( size_t Size )
{
    fprintf( stderr,
    "Cannot allocate %u bytes. Terminating. Add RAM or increase swap space.\n",
             Size );
    exit( EXIT_FAILURE );
}


/*
 * DESCRIPTION
 *     Return a pointer to uninitialized memory of Size bytes. The
 *     pointer is properly aligned for any datatype.
 * REQUIRE
 * ENSURE
 *     ( Size == 0 && Result == NULL ) || Result != NULL;
 */
void * MemAlloc( size_t Size )
{
    void * Result = NULL;

    if ( Size > 0 )
    {
	Result = malloc( Size );

	if ( Result == NULL )
	{
	    Terminate( Size );
	}
    }

    assert( ( Size == 0 && Result == NULL ) || Result != NULL );

    return Result;
}


/*
 * DESCRIPTION
 *     If OldAdress is non-NULL, the size of the object pointed to by
 *     OldAddress is changed to NewSize. Otherwise, NewSize bytes are
 *     allocated. A pointer to the properly aligned new space is returned.
 *
 *     The contents, if any, will be unchanged up to the minimum of the old 
 *     and the new sizes. If the new space is larger, the new space is 
 *     unitialized.
 * REQUIRE
 * ENSURE
 *     ( NewSize == 0 && Result == NULL ) || Result != NULL;
 */
void * MemRealloc( void * OldAddress, size_t NewSize )
{
    void * Result;

    if ( NewSize > 0 )
    {
	if ( OldAddress != NULL )
	{
	    Result = realloc( OldAddress, NewSize );
	}
	else
	{
	    Result = malloc( NewSize );
	}

	if ( Result == NULL )
	{
	    Terminate( NewSize );
	}
    }
    else
    {
        if ( OldAddress != NULL )
        {
            free( OldAddress );
        }

        Result = NULL;
    }

    assert( ( NewSize == 0 && Result == NULL ) || Result != NULL );

    return Result;
}


/*
 * DESCRIPTION
 *     If Address is non-NULL, deallocates the space pointed to by Address. 
 * REQUIRE
 * ENSURE
 */
void MemFree( void * Address )
{
    if ( Address != NULL )
    {
	free( Address );
    }
}
