1 /* -*- buffer-read-only: t -*- vi: set ro: */
2 /* DO NOT EDIT! GENERATED AUTOMATICALLY! */
3 /* xalloc.h -- malloc with out-of-memory checking
4 
5    Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
6    1999, 2000, 2003, 2004, 2006, 2007, 2008 Free Software Foundation, Inc.
7 
8    This program is free software: you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 3 of the License, or
11    (at your option) any later version.
12 
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17 
18    You should have received a copy of the GNU General Public License
19    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
20 
21 #ifndef XALLOC_H_
22 # define XALLOC_H_
23 
24 # include <stddef.h>
25 
26 
27 # ifdef __cplusplus
28 extern "C" {
29 # endif
30 
31 
32 # ifndef __attribute__
33 #  if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8)
34 #   define __attribute__(x)
35 #  endif
36 # endif
37 
38 # ifndef ATTRIBUTE_NORETURN
39 #  define ATTRIBUTE_NORETURN __attribute__ ((__noreturn__))
40 # endif
41 
42 # ifndef ATTRIBUTE_MALLOC
43 #  if __GNUC__ >= 3
44 #   define ATTRIBUTE_MALLOC __attribute__ ((__malloc__))
45 #  else
46 #   define ATTRIBUTE_MALLOC
47 #  endif
48 # endif
49 
50 /* This function is always triggered when memory is exhausted.
51    It must be defined by the application, either explicitly
52    or by using gnulib's xalloc-die module.  This is the
53    function to call when one wants the program to die because of a
54    memory allocation failure.  */
55 extern void xalloc_die (void) ATTRIBUTE_NORETURN;
56 
57 void *xmalloc (size_t s) ATTRIBUTE_MALLOC;
58 void *xzalloc (size_t s) ATTRIBUTE_MALLOC;
59 void *xcalloc (size_t n, size_t s) ATTRIBUTE_MALLOC;
60 void *xrealloc (void *p, size_t s);
61 void *x2realloc (void *p, size_t *pn);
62 void *xmemdup (void const *p, size_t s) ATTRIBUTE_MALLOC;
63 char *xstrdup (char const *str) ATTRIBUTE_MALLOC;
64 
65 /* Return 1 if an array of N objects, each of size S, cannot exist due
66    to size arithmetic overflow.  S must be positive and N must be
67    nonnegative.  This is a macro, not an inline function, so that it
68    works correctly even when SIZE_MAX < N.
69 
70    By gnulib convention, SIZE_MAX represents overflow in size
71    calculations, so the conservative dividend to use here is
72    SIZE_MAX - 1, since SIZE_MAX might represent an overflowed value.
73    However, malloc (SIZE_MAX) fails on all known hosts where
74    sizeof (ptrdiff_t) <= sizeof (size_t), so do not bother to test for
75    exactly-SIZE_MAX allocations on such hosts; this avoids a test and
76    branch when S is known to be 1.  */
77 # define xalloc_oversized(n, s) \
78     ((size_t) (sizeof (ptrdiff_t) <= sizeof (size_t) ? -1 : -2) / (s) < (n))
79 
80 
81 /* In the following macros, T must be an elementary or structure/union or
82    typedef'ed type, or a pointer to such a type.  To apply one of the
83    following macros to a function pointer or array type, you need to typedef
84    it first and use the typedef name.  */
85 
86 /* Allocate an object of type T dynamically, with error checking.  */
87 /* extern t *XMALLOC (typename t); */
88 # define XMALLOC(t) ((t *) xmalloc (sizeof (t)))
89 
90 /* Allocate memory for N elements of type T, with error checking.  */
91 /* extern t *XNMALLOC (size_t n, typename t); */
92 # define XNMALLOC(n, t) \
93     ((t *) (sizeof (t) == 1 ? xmalloc (n) : xnmalloc (n, sizeof (t))))
94 
95 /* Allocate an object of type T dynamically, with error checking,
96    and zero it.  */
97 /* extern t *XZALLOC (typename t); */
98 # define XZALLOC(t) ((t *) xzalloc (sizeof (t)))
99 
100 /* Allocate memory for N elements of type T, with error checking,
101    and zero it.  */
102 /* extern t *XCALLOC (size_t n, typename t); */
103 # define XCALLOC(n, t) \
104     ((t *) (sizeof (t) == 1 ? xzalloc (n) : xcalloc (n, sizeof (t))))
105 
106 
107 # if HAVE_INLINE
108 #  define static_inline static inline
109 # else
110    void *xnmalloc (size_t n, size_t s) ATTRIBUTE_MALLOC;
111    void *xnrealloc (void *p, size_t n, size_t s);
112    void *x2nrealloc (void *p, size_t *pn, size_t s);
113    char *xcharalloc (size_t n) ATTRIBUTE_MALLOC;
114 # endif
115 
116 # ifdef static_inline
117 
118 /* Allocate an array of N objects, each with S bytes of memory,
119    dynamically, with error checking.  S must be nonzero.  */
120 
121 static_inline void *xnmalloc (size_t n, size_t s) ATTRIBUTE_MALLOC;
122 static_inline void *
xnmalloc(size_t n,size_t s)123 xnmalloc (size_t n, size_t s)
124 {
125   if (xalloc_oversized (n, s))
126     xalloc_die ();
127   return xmalloc (n * s);
128 }
129 
130 /* Change the size of an allocated block of memory P to an array of N
131    objects each of S bytes, with error checking.  S must be nonzero.  */
132 
133 static_inline void *
xnrealloc(void * p,size_t n,size_t s)134 xnrealloc (void *p, size_t n, size_t s)
135 {
136   if (xalloc_oversized (n, s))
137     xalloc_die ();
138   return xrealloc (p, n * s);
139 }
140 
141 /* If P is null, allocate a block of at least *PN such objects;
142    otherwise, reallocate P so that it contains more than *PN objects
143    each of S bytes.  *PN must be nonzero unless P is null, and S must
144    be nonzero.  Set *PN to the new number of objects, and return the
145    pointer to the new block.  *PN is never set to zero, and the
146    returned pointer is never null.
147 
148    Repeated reallocations are guaranteed to make progress, either by
149    allocating an initial block with a nonzero size, or by allocating a
150    larger block.
151 
152    In the following implementation, nonzero sizes are increased by a
153    factor of approximately 1.5 so that repeated reallocations have
154    O(N) overall cost rather than O(N**2) cost, but the
155    specification for this function does not guarantee that rate.
156 
157    Here is an example of use:
158 
159      int *p = NULL;
160      size_t used = 0;
161      size_t allocated = 0;
162 
163      void
164      append_int (int value)
165        {
166 	 if (used == allocated)
167 	   p = x2nrealloc (p, &allocated, sizeof *p);
168 	 p[used++] = value;
169        }
170 
171    This causes x2nrealloc to allocate a block of some nonzero size the
172    first time it is called.
173 
174    To have finer-grained control over the initial size, set *PN to a
175    nonzero value before calling this function with P == NULL.  For
176    example:
177 
178      int *p = NULL;
179      size_t used = 0;
180      size_t allocated = 0;
181      size_t allocated1 = 1000;
182 
183      void
184      append_int (int value)
185        {
186 	 if (used == allocated)
187 	   {
188 	     p = x2nrealloc (p, &allocated1, sizeof *p);
189 	     allocated = allocated1;
190 	   }
191 	 p[used++] = value;
192        }
193 
194    */
195 
196 static_inline void *
x2nrealloc(void * p,size_t * pn,size_t s)197 x2nrealloc (void *p, size_t *pn, size_t s)
198 {
199   size_t n = *pn;
200 
201   if (! p)
202     {
203       if (! n)
204 	{
205 	  /* The approximate size to use for initial small allocation
206 	     requests, when the invoking code specifies an old size of
207 	     zero.  64 bytes is the largest "small" request for the
208 	     GNU C library malloc.  */
209 	  enum { DEFAULT_MXFAST = 64 };
210 
211 	  n = DEFAULT_MXFAST / s;
212 	  n += !n;
213 	}
214     }
215   else
216     {
217       /* Set N = ceil (1.5 * N) so that progress is made if N == 1.
218 	 Check for overflow, so that N * S stays in size_t range.
219 	 The check is slightly conservative, but an exact check isn't
220 	 worth the trouble.  */
221       if ((size_t) -1 / 3 * 2 / s <= n)
222 	xalloc_die ();
223       n += (n + 1) / 2;
224     }
225 
226   *pn = n;
227   return xrealloc (p, n * s);
228 }
229 
230 /* Return a pointer to a new buffer of N bytes.  This is like xmalloc,
231    except it returns char *.  */
232 
233 static_inline char *xcharalloc (size_t n) ATTRIBUTE_MALLOC;
234 static_inline char *
xcharalloc(size_t n)235 xcharalloc (size_t n)
236 {
237   return XNMALLOC (n, char);
238 }
239 
240 # endif
241 
242 # ifdef __cplusplus
243 }
244 
245 /* C++ does not allow conversions from void * to other pointer types
246    without a cast.  Use templates to work around the problem when
247    possible.  */
248 
249 template <typename T> inline T *
xrealloc(T * p,size_t s)250 xrealloc (T *p, size_t s)
251 {
252   return (T *) xrealloc ((void *) p, s);
253 }
254 
255 template <typename T> inline T *
xnrealloc(T * p,size_t n,size_t s)256 xnrealloc (T *p, size_t n, size_t s)
257 {
258   return (T *) xnrealloc ((void *) p, n, s);
259 }
260 
261 template <typename T> inline T *
x2realloc(T * p,size_t * pn)262 x2realloc (T *p, size_t *pn)
263 {
264   return (T *) x2realloc ((void *) p, pn);
265 }
266 
267 template <typename T> inline T *
x2nrealloc(T * p,size_t * pn,size_t s)268 x2nrealloc (T *p, size_t *pn, size_t s)
269 {
270   return (T *) x2nrealloc ((void *) p, pn, s);
271 }
272 
273 template <typename T> inline T *
xmemdup(T const * p,size_t s)274 xmemdup (T const *p, size_t s)
275 {
276   return (T *) xmemdup ((void const *) p, s);
277 }
278 
279 # endif
280 
281 
282 #endif /* !XALLOC_H_ */
283