1169695Skan/* memory allocation routines with error checking.
2169695Skan   Copyright 1989, 90, 91, 92, 93, 94 Free Software Foundation, Inc.
3169695Skan
4169695SkanThis file is part of the libiberty library.
5169695SkanLibiberty is free software; you can redistribute it and/or
6169695Skanmodify it under the terms of the GNU Library General Public
7169695SkanLicense as published by the Free Software Foundation; either
8169695Skanversion 2 of the License, or (at your option) any later version.
9169695Skan
10169695SkanLibiberty is distributed in the hope that it will be useful,
11169695Skanbut WITHOUT ANY WARRANTY; without even the implied warranty of
12169695SkanMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13169695SkanLibrary General Public License for more details.
14169695Skan
15169695SkanYou should have received a copy of the GNU Library General Public
16169695SkanLicense along with libiberty; see the file COPYING.LIB.  If
17169695Skannot, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
18169695SkanBoston, MA 02110-1301, USA.  */
19169695Skan
20169695Skan/*
21169695Skan
22169695Skan@deftypefn Replacement void* xmalloc (size_t)
23169695Skan
24169695SkanAllocate memory without fail.  If @code{malloc} fails, this will print
25169695Skana message to @code{stderr} (using the name set by
26169695Skan@code{xmalloc_set_program_name},
27169695Skanif any) and then call @code{xexit}.  Note that it is therefore safe for
28169695Skana program to contain @code{#define malloc xmalloc} in its source.
29169695Skan
30169695Skan@end deftypefn
31169695Skan
32169695Skan@deftypefn Replacement void* xrealloc (void *@var{ptr}, size_t @var{size})
33169695SkanReallocate memory without fail.  This routine functions like @code{realloc},
34169695Skanbut will behave the same as @code{xmalloc} if memory cannot be found.
35169695Skan
36169695Skan@end deftypefn
37169695Skan
38169695Skan@deftypefn Replacement void* xcalloc (size_t @var{nelem}, size_t @var{elsize})
39169695Skan
40169695SkanAllocate memory without fail, and set it to zero.  This routine functions
41169695Skanlike @code{calloc}, but will behave the same as @code{xmalloc} if memory
42169695Skancannot be found.
43169695Skan
44169695Skan@end deftypefn
45169695Skan
46169695Skan@deftypefn Replacement void xmalloc_set_program_name (const char *@var{name})
47169695Skan
48169695SkanYou can use this to set the name of the program used by
49169695Skan@code{xmalloc_failed} when printing a failure message.
50169695Skan
51169695Skan@end deftypefn
52169695Skan
53169695Skan@deftypefn Replacement void xmalloc_failed (size_t)
54169695Skan
55169695SkanThis function is not meant to be called by client code, and is listed
56169695Skanhere for completeness only.  If any of the allocation routines fail, this
57169695Skanfunction will be called to print an error message and terminate execution.
58169695Skan
59169695Skan@end deftypefn
60169695Skan
61169695Skan*/
62169695Skan
63169695Skan#ifdef HAVE_CONFIG_H
64169695Skan#include "config.h"
65169695Skan#endif
66169695Skan#include "ansidecl.h"
67169695Skan#include "libiberty.h"
68169695Skan
69169695Skan#include <stdio.h>
70169695Skan
71169695Skan#include <stddef.h>
72169695Skan
73169695Skan#if VMS
74169695Skan#include <stdlib.h>
75169695Skan#include <unixlib.h>
76169695Skan#else
77169695Skan/* For systems with larger pointers than ints, these must be declared.  */
78169695Skan#  if HAVE_STDLIB_H && HAVE_UNISTD_H && HAVE_DECL_MALLOC \
79169695Skan      && HAVE_DECL_REALLOC && HAVE_DECL_CALLOC && HAVE_DECL_SBRK
80169695Skan#    include <stdlib.h>
81169695Skan#    include <unistd.h>
82169695Skan#  else
83169695Skan#    ifdef __cplusplus
84169695Skanextern "C" {
85169695Skan#    endif /* __cplusplus */
86169695Skanvoid *malloc (size_t);
87169695Skanvoid *realloc (void *, size_t);
88169695Skanvoid *calloc (size_t, size_t);
89169695Skanvoid *sbrk (ptrdiff_t);
90169695Skan#    ifdef __cplusplus
91169695Skan}
92169695Skan#    endif /* __cplusplus */
93169695Skan#  endif /* HAVE_STDLIB_H ...  */
94169695Skan#endif /* VMS */
95169695Skan
96169695Skan/* The program name if set.  */
97169695Skanstatic const char *name = "";
98169695Skan
99169695Skan#ifdef HAVE_SBRK
100169695Skan/* The initial sbrk, set when the program name is set. Not used for win32
101169695Skan   ports other than cygwin32.  */
102169695Skanstatic char *first_break = NULL;
103169695Skan#endif /* HAVE_SBRK */
104169695Skan
105169695Skanvoid
106169695Skanxmalloc_set_program_name (const char *s)
107169695Skan{
108169695Skan  name = s;
109169695Skan#ifdef HAVE_SBRK
110169695Skan  /* Win32 ports other than cygwin32 don't have brk() */
111169695Skan  if (first_break == NULL)
112169695Skan    first_break = (char *) sbrk (0);
113169695Skan#endif /* HAVE_SBRK */
114169695Skan}
115169695Skan
116169695Skanvoid
117169695Skanxmalloc_failed (size_t size)
118169695Skan{
119169695Skan#ifdef HAVE_SBRK
120169695Skan  extern char **environ;
121169695Skan  size_t allocated;
122169695Skan
123169695Skan  if (first_break != NULL)
124169695Skan    allocated = (char *) sbrk (0) - first_break;
125169695Skan  else
126169695Skan    allocated = (char *) sbrk (0) - (char *) &environ;
127169695Skan  fprintf (stderr,
128169695Skan	   "\n%s%sout of memory allocating %lu bytes after a total of %lu bytes\n",
129169695Skan	   name, *name ? ": " : "",
130169695Skan	   (unsigned long) size, (unsigned long) allocated);
131169695Skan#else /* HAVE_SBRK */
132169695Skan  fprintf (stderr,
133169695Skan	   "\n%s%sout of memory allocating %lu bytes\n",
134169695Skan	   name, *name ? ": " : "",
135169695Skan	   (unsigned long) size);
136169695Skan#endif /* HAVE_SBRK */
137169695Skan  xexit (1);
138169695Skan}
139169695Skan
140169695SkanPTR
141169695Skanxmalloc (size_t size)
142169695Skan{
143169695Skan  PTR newmem;
144169695Skan
145169695Skan  if (size == 0)
146169695Skan    size = 1;
147169695Skan  newmem = malloc (size);
148169695Skan  if (!newmem)
149169695Skan    xmalloc_failed (size);
150169695Skan
151169695Skan  return (newmem);
152169695Skan}
153169695Skan
154169695SkanPTR
155169695Skanxcalloc (size_t nelem, size_t elsize)
156169695Skan{
157169695Skan  PTR newmem;
158169695Skan
159169695Skan  if (nelem == 0 || elsize == 0)
160169695Skan    nelem = elsize = 1;
161169695Skan
162169695Skan  newmem = calloc (nelem, elsize);
163169695Skan  if (!newmem)
164169695Skan    xmalloc_failed (nelem * elsize);
165169695Skan
166169695Skan  return (newmem);
167169695Skan}
168169695Skan
169169695SkanPTR
170169695Skanxrealloc (PTR oldmem, size_t size)
171169695Skan{
172169695Skan  PTR newmem;
173169695Skan
174169695Skan  if (size == 0)
175169695Skan    size = 1;
176169695Skan  if (!oldmem)
177169695Skan    newmem = malloc (size);
178169695Skan  else
179169695Skan    newmem = realloc (oldmem, size);
180169695Skan  if (!newmem)
181169695Skan    xmalloc_failed (size);
182169695Skan
183169695Skan  return (newmem);
184169695Skan}
185