/*
** Splint - annotation-assisted static program checker
** Copyright (C) 1994-2003 University of Virginia,
**         Massachusetts Institute of Technology
**
** 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.
** 
** The GNU General Public License is available from http://www.gnu.org/ or
** the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
** MA 02111-1307, USA.
**
** For information on splint: info@splint.org
** To report a bug: splint-bug@splint.org
** For more information: http://www.splint.org
*/
/*
** general.c
*/

# include "splintMacros.nf"
# include "basic.h"

# undef malloc
# undef realloc
# undef calloc

/*
** redefine undef'd memory ops
*/


/*@-mustdefine@*/

/*
** all memory should be allocated from dimalloc
*/

/*@out@*/ void *dimalloc (size_t size, const char *name, int line)
     /*@ensures maxSet(result) == (size - 1); @*/ 
{
  /* was malloc, use calloc to initialize to zero */
  void *ret = (void *) calloc (1, size);

  if (ret == NULL)
    {
      if (size == 0)
	{
	  llcontbug (message ("Zero allocation at %q.",
			      fileloc_unparseRaw (cstring_fromChars (name), line)));
	  
	  /* 
	  ** evans 2002-03-01
	  ** Return some allocated storage...hope we get lucky.
	  */

	  return dimalloc (16, name, line);
	}
      else
	{
	  /* drl fix this so message doesn't run out of memory*/
	  
	  llbuglit("Out of memory");
	  
	  llfatalerrorLoc
	    (message ("Out of memory.  Allocating %w bytes at %s:%d.", 
		      size_toLongUnsigned (size),
		      cstring_fromChars (name), line));
	  
	}
    }
      
  /*@-null@*/ /* null okay for size = 0 */
  return ret; 
  /*@=null@*/
}

void *dicalloc (size_t num, size_t size, const char *name, int line)
{
  void *ret = (void *) calloc (num, size);

  if (ret == NULL)
    {
      llfatalerrorLoc 
	(message ("Out of memory.  Allocating %w bytes at %s:%d.", 
		  size_toLongUnsigned (size),
		  cstring_fromChars (name), line));
    }
  
  return ret;
}

void *direalloc (/*@out@*/ /*@null@*/ void *x, size_t size, 
		 const char *name, int line)
{
  void *ret;

  if (x == NULL)
    {				       
      ret = (void *) dmalloc (size);
    }
  else
    {
      ret = (void *) realloc (x, size);
    }

  if (ret == NULL)
    {
      llfatalerrorLoc
	(message ("Out of memory.  Allocating %w bytes at %s:%d.", 
		  size_toLongUnsigned (size),
		  cstring_fromChars (name), line));
    }
  
  return ret;
}

void sfreeEventually (void *x)
{
  if (x != NULL)
    {
      ; /* should keep in a table */
    }
/*@-mustfree@*/
} /*@=mustfree@*/

/*@=mustdefine@*/

