Back to index

cell-binutils  2.17cvs20070401
xmalloc.c
Go to the documentation of this file.
00001 /* memory allocation routines with error checking.
00002    Copyright 1989, 90, 91, 92, 93, 94 Free Software Foundation, Inc.
00003    
00004 This file is part of the libiberty library.
00005 Libiberty is free software; you can redistribute it and/or
00006 modify it under the terms of the GNU Library General Public
00007 License as published by the Free Software Foundation; either
00008 version 2 of the License, or (at your option) any later version.
00009 
00010 Libiberty is distributed in the hope that it will be useful,
00011 but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013 Library General Public License for more details.
00014 
00015 You should have received a copy of the GNU Library General Public
00016 License along with libiberty; see the file COPYING.LIB.  If
00017 not, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
00018 Boston, MA 02110-1301, USA.  */
00019 
00020 /*
00021 
00022 @deftypefn Replacement void* xmalloc (size_t)
00023 
00024 Allocate memory without fail.  If @code{malloc} fails, this will print
00025 a message to @code{stderr} (using the name set by
00026 @code{xmalloc_set_program_name},
00027 if any) and then call @code{xexit}.  Note that it is therefore safe for
00028 a program to contain @code{#define malloc xmalloc} in its source.
00029 
00030 @end deftypefn
00031 
00032 @deftypefn Replacement void* xrealloc (void *@var{ptr}, size_t @var{size})
00033 Reallocate memory without fail.  This routine functions like @code{realloc},
00034 but will behave the same as @code{xmalloc} if memory cannot be found.
00035 
00036 @end deftypefn
00037 
00038 @deftypefn Replacement void* xcalloc (size_t @var{nelem}, size_t @var{elsize})
00039 
00040 Allocate memory without fail, and set it to zero.  This routine functions
00041 like @code{calloc}, but will behave the same as @code{xmalloc} if memory
00042 cannot be found.
00043 
00044 @end deftypefn
00045 
00046 @deftypefn Replacement void xmalloc_set_program_name (const char *@var{name})
00047 
00048 You can use this to set the name of the program used by
00049 @code{xmalloc_failed} when printing a failure message.
00050 
00051 @end deftypefn
00052 
00053 @deftypefn Replacement void xmalloc_failed (size_t)
00054 
00055 This function is not meant to be called by client code, and is listed
00056 here for completeness only.  If any of the allocation routines fail, this
00057 function will be called to print an error message and terminate execution.
00058 
00059 @end deftypefn
00060 
00061 */
00062 
00063 #ifdef HAVE_CONFIG_H
00064 #include "config.h"
00065 #endif
00066 #include "ansidecl.h"
00067 #include "libiberty.h"
00068 
00069 #include <stdio.h>
00070 
00071 #include <stddef.h>
00072 
00073 #if VMS
00074 #include <stdlib.h>
00075 #include <unixlib.h>
00076 #else
00077 /* For systems with larger pointers than ints, these must be declared.  */
00078 #  if HAVE_STDLIB_H && HAVE_UNISTD_H && HAVE_DECL_MALLOC \
00079       && HAVE_DECL_REALLOC && HAVE_DECL_CALLOC && HAVE_DECL_SBRK
00080 #    include <stdlib.h>
00081 #    include <unistd.h>
00082 #  else
00083 #    ifdef __cplusplus
00084 extern "C" {
00085 #    endif /* __cplusplus */
00086 void *malloc (size_t);
00087 void *realloc (void *, size_t);
00088 void *calloc (size_t, size_t);
00089 void *sbrk (ptrdiff_t);
00090 #    ifdef __cplusplus
00091 }
00092 #    endif /* __cplusplus */
00093 #  endif /* HAVE_STDLIB_H ...  */
00094 #endif /* VMS */
00095 
00096 /* The program name if set.  */
00097 static const char *name = "";
00098 
00099 #ifdef HAVE_SBRK
00100 /* The initial sbrk, set when the program name is set. Not used for win32
00101    ports other than cygwin32.  */
00102 static char *first_break = NULL;
00103 #endif /* HAVE_SBRK */
00104 
00105 void
00106 xmalloc_set_program_name (const char *s)
00107 {
00108   name = s;
00109 #ifdef HAVE_SBRK
00110   /* Win32 ports other than cygwin32 don't have brk() */
00111   if (first_break == NULL)
00112     first_break = (char *) sbrk (0);
00113 #endif /* HAVE_SBRK */
00114 }
00115 
00116 void
00117 xmalloc_failed (size_t size)
00118 {
00119 #ifdef HAVE_SBRK
00120   extern char **environ;
00121   size_t allocated;
00122 
00123   if (first_break != NULL)
00124     allocated = (char *) sbrk (0) - first_break;
00125   else
00126     allocated = (char *) sbrk (0) - (char *) &environ;
00127   fprintf (stderr,
00128           "\n%s%sout of memory allocating %lu bytes after a total of %lu bytes\n",
00129           name, *name ? ": " : "",
00130           (unsigned long) size, (unsigned long) allocated);
00131 #else /* HAVE_SBRK */
00132   fprintf (stderr,
00133           "\n%s%sout of memory allocating %lu bytes\n",
00134           name, *name ? ": " : "",
00135           (unsigned long) size);
00136 #endif /* HAVE_SBRK */
00137   xexit (1);
00138 }  
00139 
00140 PTR
00141 xmalloc (size_t size)
00142 {
00143   PTR newmem;
00144 
00145   if (size == 0)
00146     size = 1;
00147   newmem = malloc (size);
00148   if (!newmem)
00149     xmalloc_failed (size);
00150 
00151   return (newmem);
00152 }
00153 
00154 PTR
00155 xcalloc (size_t nelem, size_t elsize)
00156 {
00157   PTR newmem;
00158 
00159   if (nelem == 0 || elsize == 0)
00160     nelem = elsize = 1;
00161 
00162   newmem = calloc (nelem, elsize);
00163   if (!newmem)
00164     xmalloc_failed (nelem * elsize);
00165 
00166   return (newmem);
00167 }
00168 
00169 PTR
00170 xrealloc (PTR oldmem, size_t size)
00171 {
00172   PTR newmem;
00173 
00174   if (size == 0)
00175     size = 1;
00176   if (!oldmem)
00177     newmem = malloc (size);
00178   else
00179     newmem = realloc (oldmem, size);
00180   if (!newmem)
00181     xmalloc_failed (size);
00182 
00183   return (newmem);
00184 }