133965Sjdp/* memory allocation routines with error checking.
233965Sjdp   Copyright 1989, 90, 91, 92, 93, 94 Free Software Foundation, Inc.
333965Sjdp
433965SjdpThis file is part of the libiberty library.
533965SjdpLibiberty is free software; you can redistribute it and/or
633965Sjdpmodify it under the terms of the GNU Library General Public
733965SjdpLicense as published by the Free Software Foundation; either
833965Sjdpversion 2 of the License, or (at your option) any later version.
933965Sjdp
1033965SjdpLibiberty is distributed in the hope that it will be useful,
1133965Sjdpbut WITHOUT ANY WARRANTY; without even the implied warranty of
1233965SjdpMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
1333965SjdpLibrary General Public License for more details.
1433965Sjdp
1533965SjdpYou should have received a copy of the GNU Library General Public
1633965SjdpLicense along with libiberty; see the file COPYING.LIB.  If
17218822Sdimnot, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
18218822SdimBoston, MA 02110-1301, USA.  */
1933965Sjdp
2089857Sobrien/*
2189857Sobrien
2289857Sobrien@deftypefn Replacement void* xmalloc (size_t)
2389857Sobrien
2489857SobrienAllocate memory without fail.  If @code{malloc} fails, this will print
2589857Sobriena message to @code{stderr} (using the name set by
2689857Sobrien@code{xmalloc_set_program_name},
2789857Sobrienif any) and then call @code{xexit}.  Note that it is therefore safe for
2889857Sobriena program to contain @code{#define malloc xmalloc} in its source.
2989857Sobrien
3089857Sobrien@end deftypefn
3189857Sobrien
3289857Sobrien@deftypefn Replacement void* xrealloc (void *@var{ptr}, size_t @var{size})
3389857SobrienReallocate memory without fail.  This routine functions like @code{realloc},
3489857Sobrienbut will behave the same as @code{xmalloc} if memory cannot be found.
3589857Sobrien
3689857Sobrien@end deftypefn
3789857Sobrien
3889857Sobrien@deftypefn Replacement void* xcalloc (size_t @var{nelem}, size_t @var{elsize})
3989857Sobrien
4089857SobrienAllocate memory without fail, and set it to zero.  This routine functions
4189857Sobrienlike @code{calloc}, but will behave the same as @code{xmalloc} if memory
4289857Sobriencannot be found.
4389857Sobrien
4489857Sobrien@end deftypefn
4589857Sobrien
4689857Sobrien@deftypefn Replacement void xmalloc_set_program_name (const char *@var{name})
4789857Sobrien
4889857SobrienYou can use this to set the name of the program used by
4989857Sobrien@code{xmalloc_failed} when printing a failure message.
5089857Sobrien
5189857Sobrien@end deftypefn
5289857Sobrien
5389857Sobrien@deftypefn Replacement void xmalloc_failed (size_t)
5489857Sobrien
5589857SobrienThis function is not meant to be called by client code, and is listed
5689857Sobrienhere for completeness only.  If any of the allocation routines fail, this
5789857Sobrienfunction will be called to print an error message and terminate execution.
5889857Sobrien
5989857Sobrien@end deftypefn
6089857Sobrien
6189857Sobrien*/
6289857Sobrien
6377298Sobrien#ifdef HAVE_CONFIG_H
6477298Sobrien#include "config.h"
6577298Sobrien#endif
6633965Sjdp#include "ansidecl.h"
6733965Sjdp#include "libiberty.h"
6833965Sjdp
6933965Sjdp#include <stdio.h>
7033965Sjdp
7133965Sjdp#include <stddef.h>
7233965Sjdp
7333965Sjdp#if VMS
7433965Sjdp#include <stdlib.h>
7533965Sjdp#include <unixlib.h>
7633965Sjdp#else
7733965Sjdp/* For systems with larger pointers than ints, these must be declared.  */
78218822Sdim#  if HAVE_STDLIB_H && HAVE_UNISTD_H && HAVE_DECL_MALLOC \
79218822Sdim      && HAVE_DECL_REALLOC && HAVE_DECL_CALLOC && HAVE_DECL_SBRK
80218822Sdim#    include <stdlib.h>
81218822Sdim#    include <unistd.h>
82218822Sdim#  else
83218822Sdim#    ifdef __cplusplus
84218822Sdimextern "C" {
85218822Sdim#    endif /* __cplusplus */
86218822Sdimvoid *malloc (size_t);
87218822Sdimvoid *realloc (void *, size_t);
88218822Sdimvoid *calloc (size_t, size_t);
89218822Sdimvoid *sbrk (ptrdiff_t);
90218822Sdim#    ifdef __cplusplus
91218822Sdim}
92218822Sdim#    endif /* __cplusplus */
93218822Sdim#  endif /* HAVE_STDLIB_H ...  */
94218822Sdim#endif /* VMS */
9533965Sjdp
9633965Sjdp/* The program name if set.  */
9733965Sjdpstatic const char *name = "";
9833965Sjdp
9960484Sobrien#ifdef HAVE_SBRK
10038889Sjdp/* The initial sbrk, set when the program name is set. Not used for win32
10138889Sjdp   ports other than cygwin32.  */
10233965Sjdpstatic char *first_break = NULL;
10360484Sobrien#endif /* HAVE_SBRK */
10433965Sjdp
10533965Sjdpvoid
106218822Sdimxmalloc_set_program_name (const char *s)
10733965Sjdp{
10833965Sjdp  name = s;
10960484Sobrien#ifdef HAVE_SBRK
11038889Sjdp  /* Win32 ports other than cygwin32 don't have brk() */
11133965Sjdp  if (first_break == NULL)
11233965Sjdp    first_break = (char *) sbrk (0);
11360484Sobrien#endif /* HAVE_SBRK */
11433965Sjdp}
11533965Sjdp
11677298Sobrienvoid
117218822Sdimxmalloc_failed (size_t size)
11877298Sobrien{
11977298Sobrien#ifdef HAVE_SBRK
12077298Sobrien  extern char **environ;
12177298Sobrien  size_t allocated;
12277298Sobrien
12377298Sobrien  if (first_break != NULL)
12477298Sobrien    allocated = (char *) sbrk (0) - first_break;
12577298Sobrien  else
12677298Sobrien    allocated = (char *) sbrk (0) - (char *) &environ;
12777298Sobrien  fprintf (stderr,
128104834Sobrien	   "\n%s%sout of memory allocating %lu bytes after a total of %lu bytes\n",
12977298Sobrien	   name, *name ? ": " : "",
13077298Sobrien	   (unsigned long) size, (unsigned long) allocated);
13177298Sobrien#else /* HAVE_SBRK */
13277298Sobrien  fprintf (stderr,
133104834Sobrien	   "\n%s%sout of memory allocating %lu bytes\n",
13477298Sobrien	   name, *name ? ": " : "",
13577298Sobrien	   (unsigned long) size);
13677298Sobrien#endif /* HAVE_SBRK */
13777298Sobrien  xexit (1);
13877298Sobrien}
13977298Sobrien
14033965SjdpPTR
141218822Sdimxmalloc (size_t size)
14233965Sjdp{
14333965Sjdp  PTR newmem;
14433965Sjdp
14533965Sjdp  if (size == 0)
14633965Sjdp    size = 1;
14733965Sjdp  newmem = malloc (size);
14833965Sjdp  if (!newmem)
14977298Sobrien    xmalloc_failed (size);
15033965Sjdp
15133965Sjdp  return (newmem);
15233965Sjdp}
15333965Sjdp
15433965SjdpPTR
155218822Sdimxcalloc (size_t nelem, size_t elsize)
15660484Sobrien{
15760484Sobrien  PTR newmem;
15860484Sobrien
15960484Sobrien  if (nelem == 0 || elsize == 0)
16060484Sobrien    nelem = elsize = 1;
16160484Sobrien
16260484Sobrien  newmem = calloc (nelem, elsize);
16360484Sobrien  if (!newmem)
16477298Sobrien    xmalloc_failed (nelem * elsize);
16560484Sobrien
16660484Sobrien  return (newmem);
16760484Sobrien}
16860484Sobrien
16960484SobrienPTR
170218822Sdimxrealloc (PTR oldmem, size_t size)
17133965Sjdp{
17233965Sjdp  PTR newmem;
17333965Sjdp
17433965Sjdp  if (size == 0)
17533965Sjdp    size = 1;
17633965Sjdp  if (!oldmem)
17733965Sjdp    newmem = malloc (size);
17833965Sjdp  else
17933965Sjdp    newmem = realloc (oldmem, size);
18033965Sjdp  if (!newmem)
18177298Sobrien    xmalloc_failed (size);
18233965Sjdp
18333965Sjdp  return (newmem);
18433965Sjdp}
185