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