/*
 * $Id: localalloc.c,v 1.3 1992/12/01 06:10:40 proj Exp $
 */
/*
 * Copyright 1990, 1991 by OMRON Corporation
 * Copyright 1991 by Massachusetts Institute of Technology
 *
 * Permission to use, copy, modify, distribute, and sell this software and its
 * documentation for any purpose is hereby granted without fee, 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 names of OMRON and MIT not be used in
 * advertising or publicity pertaining to distribution of the software without
 * specific, written prior permission.  OMRON and MIT make no representations
 * about the suitability of this software for any purpose.  It is provided
 * "as is" without express or implied warranty.
 *
 * Wnn consortium is one of distributors of the official Wnn source code
 * release.  Wnn consortium also makes no representations about the
 * suitability of this software for any purpose.  It is provided "as is"
 * without express or implied warranty.
 *
 * OMRON, MIT AND WNN CONSORTIUM DISCLAIM ALL WARRANTIES WITH REGARD TO
 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
 * FITNESS, IN NO EVENT SHALL OMRON, MIT OR WNN CONSORTIUM BE LIABLE FOR ANY
 * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
 * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
 * CONTRACT, NEGLIGENCE OR OTHER TORTUOUS ACTION, ARISING OUT OF OR IN
 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 *	Author:	Seiji Kuwari	OMRON Corporation
 *				kuwa@omron.co.jp
 *				kuwa%omron.co.jp@uunet.uu.net
 */				

/*
 * memory allocation routines
 */
#include <stdio.h>
#include "commonhd.h"
#include "sdefine.h"
#ifdef  XJUTIL
#include "xjutil.h"
#include "sxheader.h"
#include "xext.h"
#else   /* XJUTIL */
#include "xim.h"
#include "sheader.h"
#include "ext.h"
#endif  /* XJUTIL */

extern char *malloc(), *realloc(), *calloc();
#ifdef ALLOC_DEBUG
#define DEBUG_TBL_SIZE	10000
typedef struct _alloc_debug_struct {
    char *ptr;
    int size;
} debug_tbl;

debug_tbl alloc_tbl[DEBUG_TBL_SIZE];
static int debug_initialized = 0;

void
initialize_debug()
{
    register int i;

    for (i = 0; i < DEBUG_TBL_SIZE; i++) {
	alloc_tbl[i].ptr = NULL;
	alloc_tbl[i].size = 0;
    }
    debug_initialized = 1;
}

static void
register_debug(ptr, size)
char *ptr;
int size;
{
    register int i;

    for (i = 0; i < DEBUG_TBL_SIZE; i++) {
	if (alloc_tbl[i].ptr == NULL) {
	    alloc_tbl[i].ptr = ptr;
	    alloc_tbl[i].size = size;
	    return;
	}
    }
    print_out("alloc_table over flow");
}

void
unregister_debug(ptr)
char *ptr;
{
    register int i;

    for (i = 0; i < DEBUG_TBL_SIZE; i++) {
	if (alloc_tbl[i].ptr == ptr) {
	    alloc_tbl[i].ptr = NULL;
	    alloc_tbl[i].size = 0;
	    return;
	}
    }
    print_out1("illegal calling of free ptr = %x", ptr);
}

#endif

char *Malloc(size)
unsigned size;
{
    char *ptr;
    if (size == 0) return(NULL);
    if ((ptr = malloc(size)) == NULL) {
#ifdef ALLOC_DEBUG
	print_out1("alloc failed with size = %d", size);
#endif
	return(NULL);
    }
#ifdef ALLOC_DEBUG
    if (!debug_initialized) {
	initialize_debug();
    }
    register_debug(ptr, size);
#endif
    return(ptr);
}

#ifdef nodef	/* should not use Realloc, because realloc may broke
		   old data if it fails allocation of new area */
char *Realloc(ptr, size)
char *ptr;
unsigned size;
{
    if (size == 0) return(ptr);
    if (ptr == NULL) return(Malloc(size));
#ifdef ALLOC_DEBUG
    unregister_debug(ptr);
#endif
    if ((ptr = realloc(ptr, size)) == NULL) {
	return(NULL);
    }
#ifdef ALLOC_DEBUG
    register_debug(ptr, size);
#endif
    return(ptr);
}
#endif

char *Calloc(num, size)
unsigned num, size;
{
    char *ptr;
    if (size == 0) return(NULL);
    if ((ptr = calloc(num, size)) == NULL) {
	return(NULL);
    }
#ifdef ALLOC_DEBUG
    if (!debug_initialized) {
	initialize_debug();
    }
    register_debug(ptr, size);
#endif
    return(ptr);
}

void Free(ptr)
char *ptr;
{
    if (ptr != NULL) free(ptr);
#ifdef ALLOC_DEBUG
    unregister_debug(ptr);
#endif
}


char *
alloc_and_copy(src)
register char *src;
{
    register char *ptr;
    register unsigned int n;

    if (src == NULL) return(NULL);
    if ((ptr = Malloc((n = strlen(src))+1)) == NULL) {
	malloc_error("allocation of work area");
	return(NULL);
    }
    bcopy(src, ptr, n);
    ptr[n] = '\0';
    return(ptr);
}
