1264790Sbapt/* memory allocation routines with error checking.
2264790Sbapt   Copyright 1989, 90, 91, 92, 93, 94 Free Software Foundation, Inc.
3264790Sbapt
4264790SbaptThis file is part of the libiberty library.
5264790SbaptLibiberty is free software; you can redistribute it and/or
6264790Sbaptmodify it under the terms of the GNU Library General Public
7264790SbaptLicense as published by the Free Software Foundation; either
8264790Sbaptversion 2 of the License, or (at your option) any later version.
9264790Sbapt
10264790SbaptLibiberty is distributed in the hope that it will be useful,
11264790Sbaptbut WITHOUT ANY WARRANTY; without even the implied warranty of
12264790SbaptMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13264790SbaptLibrary General Public License for more details.
14264790Sbapt
15264790SbaptYou should have received a copy of the GNU Library General Public
16264790SbaptLicense along with libiberty; see the file COPYING.LIB.  If
17264790Sbaptnot, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
18264790SbaptBoston, MA 02110-1301, USA.  */
19264790Sbapt
20264790Sbapt/*
21264790Sbapt
22264790Sbapt@deftypefn Replacement void* xmalloc (size_t)
23264790Sbapt
24264790SbaptAllocate memory without fail.  If @code{malloc} fails, this will print
25264790Sbapta message to @code{stderr} (using the name set by
26264790Sbapt@code{xmalloc_set_program_name},
27264790Sbaptif any) and then call @code{xexit}.  Note that it is therefore safe for
28264790Sbapta program to contain @code{#define malloc xmalloc} in its source.
29264790Sbapt
30264790Sbapt@end deftypefn
31264790Sbapt
32264790Sbapt@deftypefn Replacement void* xrealloc (void *@var{ptr}, size_t @var{size})
33264790SbaptReallocate memory without fail.  This routine functions like @code{realloc},
34264790Sbaptbut will behave the same as @code{xmalloc} if memory cannot be found.
35264790Sbapt
36264790Sbapt@end deftypefn
37264790Sbapt
38264790Sbapt@deftypefn Replacement void* xcalloc (size_t @var{nelem}, size_t @var{elsize})
39264790Sbapt
40264790SbaptAllocate memory without fail, and set it to zero.  This routine functions
41264790Sbaptlike @code{calloc}, but will behave the same as @code{xmalloc} if memory
42264790Sbaptcannot be found.
43264790Sbapt
44264790Sbapt@end deftypefn
45264790Sbapt
46264790Sbapt@deftypefn Replacement void xmalloc_set_program_name (const char *@var{name})
47264790Sbapt
48264790SbaptYou can use this to set the name of the program used by
49264790Sbapt@code{xmalloc_failed} when printing a failure message.
50264790Sbapt
51264790Sbapt@end deftypefn
52264790Sbapt
53264790Sbapt@deftypefn Replacement void xmalloc_failed (size_t)
54264790Sbapt
55264790SbaptThis function is not meant to be called by client code, and is listed
56264790Sbapthere for completeness only.  If any of the allocation routines fail, this
57264790Sbaptfunction will be called to print an error message and terminate execution.
58264790Sbapt
59264790Sbapt@end deftypefn
60264790Sbapt
61264790Sbapt*/
62264790Sbapt
63264790Sbapt#ifdef HAVE_CONFIG_H
64264790Sbapt#include "config.h"
65264790Sbapt#endif
66264790Sbapt#include "ansidecl.h"
67264790Sbapt#include "libiberty.h"
68264790Sbapt
69264790Sbapt#include <stdio.h>
70264790Sbapt
71264790Sbapt#include <stddef.h>
72264790Sbapt
73264790Sbapt#if VMS
74264790Sbapt#include <stdlib.h>
75264790Sbapt#include <unixlib.h>
76264790Sbapt#else
77264790Sbapt/* For systems with larger pointers than ints, these must be declared.  */
78264790Sbapt#  if HAVE_STDLIB_H && HAVE_UNISTD_H && HAVE_DECL_MALLOC \
79264790Sbapt      && HAVE_DECL_REALLOC && HAVE_DECL_CALLOC && HAVE_DECL_SBRK
80264790Sbapt#    include <stdlib.h>
81264790Sbapt#    include <unistd.h>
82264790Sbapt#  else
83264790Sbapt#    ifdef __cplusplus
84264790Sbaptextern "C" {
85264790Sbapt#    endif /* __cplusplus */
86264790Sbaptvoid *malloc (size_t);
87264790Sbaptvoid *realloc (void *, size_t);
88264790Sbaptvoid *calloc (size_t, size_t);
89264790Sbaptvoid *sbrk (ptrdiff_t);
90264790Sbapt#    ifdef __cplusplus
91264790Sbapt}
92264790Sbapt#    endif /* __cplusplus */
93264790Sbapt#  endif /* HAVE_STDLIB_H ...  */
94264790Sbapt#endif /* VMS */
95264790Sbapt
96264790Sbapt/* The program name if set.  */
97264790Sbaptstatic const char *name = "";
98264790Sbapt
99264790Sbapt#ifdef HAVE_SBRK
100264790Sbapt/* The initial sbrk, set when the program name is set. Not used for win32
101264790Sbapt   ports other than cygwin32.  */
102264790Sbaptstatic char *first_break = NULL;
103264790Sbapt#endif /* HAVE_SBRK */
104264790Sbapt
105264790Sbaptvoid
106264790Sbaptxmalloc_set_program_name (const char *s)
107264790Sbapt{
108264790Sbapt  name = s;
109264790Sbapt#ifdef HAVE_SBRK
110264790Sbapt  /* Win32 ports other than cygwin32 don't have brk() */
111264790Sbapt  if (first_break == NULL)
112264790Sbapt    first_break = (char *) sbrk (0);
113264790Sbapt#endif /* HAVE_SBRK */
114264790Sbapt}
115264790Sbapt
116264790Sbaptvoid
117264790Sbaptxmalloc_failed (size_t size)
118264790Sbapt{
119264790Sbapt#ifdef HAVE_SBRK
120264790Sbapt  extern char **environ;
121264790Sbapt  size_t allocated;
122264790Sbapt
123264790Sbapt  if (first_break != NULL)
124264790Sbapt    allocated = (char *) sbrk (0) - first_break;
125264790Sbapt  else
126264790Sbapt    allocated = (char *) sbrk (0) - (char *) &environ;
127264790Sbapt  fprintf (stderr,
128264790Sbapt	   "\n%s%sout of memory allocating %lu bytes after a total of %lu bytes\n",
129264790Sbapt	   name, *name ? ": " : "",
130264790Sbapt	   (unsigned long) size, (unsigned long) allocated);
131264790Sbapt#else /* HAVE_SBRK */
132264790Sbapt  fprintf (stderr,
133264790Sbapt	   "\n%s%sout of memory allocating %lu bytes\n",
134264790Sbapt	   name, *name ? ": " : "",
135264790Sbapt	   (unsigned long) size);
136264790Sbapt#endif /* HAVE_SBRK */
137264790Sbapt  xexit (1);
138264790Sbapt}
139264790Sbapt
140264790SbaptPTR
141264790Sbaptxmalloc (size_t size)
142264790Sbapt{
143264790Sbapt  PTR newmem;
144264790Sbapt
145264790Sbapt  if (size == 0)
146264790Sbapt    size = 1;
147264790Sbapt  newmem = malloc (size);
148264790Sbapt  if (!newmem)
149264790Sbapt    xmalloc_failed (size);
150264790Sbapt
151264790Sbapt  return (newmem);
152264790Sbapt}
153264790Sbapt
154264790SbaptPTR
155264790Sbaptxcalloc (size_t nelem, size_t elsize)
156264790Sbapt{
157264790Sbapt  PTR newmem;
158264790Sbapt
159264790Sbapt  if (nelem == 0 || elsize == 0)
160264790Sbapt    nelem = elsize = 1;
161264790Sbapt
162264790Sbapt  newmem = calloc (nelem, elsize);
163264790Sbapt  if (!newmem)
164264790Sbapt    xmalloc_failed (nelem * elsize);
165264790Sbapt
166264790Sbapt  return (newmem);
167264790Sbapt}
168264790Sbapt
169264790SbaptPTR
170264790Sbaptxrealloc (PTR oldmem, size_t size)
171264790Sbapt{
172264790Sbapt  PTR newmem;
173264790Sbapt
174264790Sbapt  if (size == 0)
175264790Sbapt    size = 1;
176264790Sbapt  if (!oldmem)
177264790Sbapt    newmem = malloc (size);
178264790Sbapt  else
179264790Sbapt    newmem = realloc (oldmem, size);
180264790Sbapt  if (!newmem)
181264790Sbapt    xmalloc_failed (size);
182264790Sbapt
183264790Sbapt  return (newmem);
184264790Sbapt}
185264790Sbapt