/***************************************
  $Revision: 1.9 $

  Utilities (ut). memwrap.c - memory allocation wrappers. 
                              Facilitate easy changing a memory allocation
			      library and provide uniform error codes.

  Status: NOT REVUED, TESTED, 

  Design and implementation by: Marek Bukowy

  ******************/ /******************
  Copyright (c) 1999                              RIPE NCC
 
  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 the author not be
  used in advertising or publicity pertaining to distribution of the
  software without specific, written prior permission.
  
  THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL
  AUTHOR 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 TORTIOUS ACTION, ARISING OUT OF
  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  ***************************************/

#include <stdlib.h>
#include <erroutines.h>
#include <stubs.h>
#include <glib.h>


  #define USE_LOGGING
/* */ 

/* global variable!! */
int wr_logging = 0;

void wr_log_set(int value) {
  wr_logging = (value != 0); 
}

static void
wr_alloc_log(void *ptr, int len, char* comment, int line) 
{
  if(wr_logging) {
    fprintf(stderr,"allocated %7d bytes at address %p in %s/%d\n",
	    len, ptr, comment, line);
  }
}

static void
wr_free_log(void *ptr, char* comment, int line) 
{
  if(wr_logging) {
    fprintf(stderr,"freed some memory space at address %p in %s/%d\n", 
	    ptr, comment, line); 
  }
}

static void
wr_free_list_log(void *ptr, char* comment, int line) 
{
  if(wr_logging) {
    fprintf(stderr,"freeing list + elements at address %p in %s/%d\n", 
	    ptr, comment, line); 
  }
}

er_ret_t 
wr_real_malloc(void **ptr, size_t size, char* comment, int line) 
{
  if( (*ptr = malloc(size)) == NULL ) {
    /* die; */ /* this should return an appropriate error number */
    return UT_OUTMEM;
  }
  else {
#ifdef USE_LOGGING
    wr_alloc_log(*ptr, size, comment, line); 
#endif
    return UT_OK;
  }
}

er_ret_t 
wr_real_calloc(void **ptr, size_t num, size_t size, char* comment, int line) 
{
void *newalloc;

  newalloc = calloc(num, size);

  if( newalloc == NULL ) {
    /*die; */ /* this should return an appropriate error number */
    return UT_OUTMEM;
  }
  else {
    *ptr=newalloc;
#ifdef USE_LOGGING
    wr_alloc_log(*ptr, size*num, comment, line);
#endif
    return UT_OK;
  }
}


er_ret_t  
wr_real_realloc(void **ptr, size_t size, char* comment, int line) 
{
  if( (*ptr = realloc(*ptr, size)) == NULL ) {
    /* die;  */ /* this should return an appropriate error number */
   return UT_OUTMEM;
  } 
  else {
#ifdef USE_LOGGING  
    wr_free_log(*ptr, comment, line);
    wr_alloc_log(*ptr, size, comment, line);
#endif
    return UT_OK;
  }
}

er_ret_t 
wr_real_free(void *ptr, char* comment, int line) 
{
  if( ptr == NULL ) {
    die;
  }
#ifdef USE_LOGGING
  wr_free_log(ptr, comment, line); 
#endif
  free(ptr);
  /* if we're tired of those dies, we can set the pointer to NULL after free */
  return UT_OK;
}


/* make a copy and return the pointer to the allocated area */
char *
wr_string(const char *text)
{
  char *area;
  int len =  strlen(text);

  wr_real_malloc( (void **) &area, len+1, "wr_string", len );
  
  strcpy( area, text );

  return area;
}

/* for GList's foreach */
static
void
wr_free_list_element(void *cpy, void *trash)
{
    wr_real_free(cpy,  "wr_free_list_element", 0 );
}

/* for GList's foreach */
void
wr_real_clear_list(GList **list, char* comment, int line)
{
    /* allow NULL argument */
    if( *list != NULL ) {
	
#ifdef USE_LOGGING
	wr_free_list_log(*list, comment, line); 
#endif
	g_list_foreach(*list, wr_free_list_element, NULL);
	g_list_free(*list);
	*list = NULL;
    }
}
