Import upstream version 1.28
[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-2014 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 #include "xalloc-oversized.h"
26
27 #ifndef _GL_INLINE_HEADER_BEGIN
28  #error "Please include config.h first."
29 #endif
30 _GL_INLINE_HEADER_BEGIN
31 #ifndef XALLOC_INLINE
32 # define XALLOC_INLINE _GL_INLINE
33 #endif
34
35 #ifdef __cplusplus
36 extern "C" {
37 #endif
38
39
40 #if __GNUC__ >= 3
41 # define _GL_ATTRIBUTE_MALLOC __attribute__ ((__malloc__))
42 #else
43 # define _GL_ATTRIBUTE_MALLOC
44 #endif
45
46 #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)
47 # define _GL_ATTRIBUTE_ALLOC_SIZE(args) __attribute__ ((__alloc_size__ args))
48 #else
49 # define _GL_ATTRIBUTE_ALLOC_SIZE(args)
50 #endif
51
52 /* This function is always triggered when memory is exhausted.
53    It must be defined by the application, either explicitly
54    or by using gnulib's xalloc-die module.  This is the
55    function to call when one wants the program to die because of a
56    memory allocation failure.  */
57 extern _Noreturn void xalloc_die (void);
58
59 void *xmalloc (size_t s)
60       _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_ALLOC_SIZE ((1));
61 void *xzalloc (size_t s)
62       _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_ALLOC_SIZE ((1));
63 void *xcalloc (size_t n, size_t s)
64       _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_ALLOC_SIZE ((1, 2));
65 void *xrealloc (void *p, size_t s)
66       _GL_ATTRIBUTE_ALLOC_SIZE ((2));
67 void *x2realloc (void *p, size_t *pn);
68 void *xmemdup (void const *p, size_t s)
69       _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_ALLOC_SIZE ((2));
70 char *xstrdup (char const *str)
71       _GL_ATTRIBUTE_MALLOC;
72
73 /* In the following macros, T must be an elementary or structure/union or
74    typedef'ed type, or a pointer to such a type.  To apply one of the
75    following macros to a function pointer or array type, you need to typedef
76    it first and use the typedef name.  */
77
78 /* Allocate an object of type T dynamically, with error checking.  */
79 /* extern t *XMALLOC (typename t); */
80 #define XMALLOC(t) ((t *) xmalloc (sizeof (t)))
81
82 /* Allocate memory for N elements of type T, with error checking.  */
83 /* extern t *XNMALLOC (size_t n, typename t); */
84 #define XNMALLOC(n, t) \
85    ((t *) (sizeof (t) == 1 ? xmalloc (n) : xnmalloc (n, sizeof (t))))
86
87 /* Allocate an object of type T dynamically, with error checking,
88    and zero it.  */
89 /* extern t *XZALLOC (typename t); */
90 #define XZALLOC(t) ((t *) xzalloc (sizeof (t)))
91
92 /* Allocate memory for N elements of type T, with error checking,
93    and zero it.  */
94 /* extern t *XCALLOC (size_t n, typename t); */
95 #define XCALLOC(n, t) \
96    ((t *) (sizeof (t) == 1 ? xzalloc (n) : xcalloc (n, sizeof (t))))
97
98
99 /* Allocate an array of N objects, each with S bytes of memory,
100    dynamically, with error checking.  S must be nonzero.  */
101
102 XALLOC_INLINE void *xnmalloc (size_t n, size_t s)
103                     _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_ALLOC_SIZE ((1, 2));
104 XALLOC_INLINE void *
105 xnmalloc (size_t n, size_t s)
106 {
107   if (xalloc_oversized (n, s))
108     xalloc_die ();
109   return xmalloc (n * s);
110 }
111
112 /* Change the size of an allocated block of memory P to an array of N
113    objects each of S bytes, with error checking.  S must be nonzero.  */
114
115 XALLOC_INLINE void *xnrealloc (void *p, size_t n, size_t s)
116                     _GL_ATTRIBUTE_ALLOC_SIZE ((2, 3));
117 XALLOC_INLINE void *
118 xnrealloc (void *p, size_t n, size_t s)
119 {
120   if (xalloc_oversized (n, s))
121     xalloc_die ();
122   return xrealloc (p, n * s);
123 }
124
125 /* If P is null, allocate a block of at least *PN such objects;
126    otherwise, reallocate P so that it contains more than *PN objects
127    each of S bytes.  *PN must be nonzero unless P is null, and S must
128    be nonzero.  Set *PN to the new number of objects, and return the
129    pointer to the new block.  *PN is never set to zero, and the
130    returned pointer is never null.
131
132    Repeated reallocations are guaranteed to make progress, either by
133    allocating an initial block with a nonzero size, or by allocating a
134    larger block.
135
136    In the following implementation, nonzero sizes are increased by a
137    factor of approximately 1.5 so that repeated reallocations have
138    O(N) overall cost rather than O(N**2) cost, but the
139    specification for this function does not guarantee that rate.
140
141    Here is an example of use:
142
143      int *p = NULL;
144      size_t used = 0;
145      size_t allocated = 0;
146
147      void
148      append_int (int value)
149        {
150          if (used == allocated)
151            p = x2nrealloc (p, &allocated, sizeof *p);
152          p[used++] = value;
153        }
154
155    This causes x2nrealloc to allocate a block of some nonzero size the
156    first time it is called.
157
158    To have finer-grained control over the initial size, set *PN to a
159    nonzero value before calling this function with P == NULL.  For
160    example:
161
162      int *p = NULL;
163      size_t used = 0;
164      size_t allocated = 0;
165      size_t allocated1 = 1000;
166
167      void
168      append_int (int value)
169        {
170          if (used == allocated)
171            {
172              p = x2nrealloc (p, &allocated1, sizeof *p);
173              allocated = allocated1;
174            }
175          p[used++] = value;
176        }
177
178    */
179
180 XALLOC_INLINE void *
181 x2nrealloc (void *p, size_t *pn, size_t s)
182 {
183   size_t n = *pn;
184
185   if (! p)
186     {
187       if (! n)
188         {
189           /* The approximate size to use for initial small allocation
190              requests, when the invoking code specifies an old size of
191              zero.  This is the largest "small" request for the GNU C
192              library malloc.  */
193           enum { DEFAULT_MXFAST = 64 * sizeof (size_t) / 4 };
194
195           n = DEFAULT_MXFAST / s;
196           n += !n;
197         }
198     }
199   else
200     {
201       /* Set N = ceil (1.5 * N) so that progress is made if N == 1.
202          Check for overflow, so that N * S stays in size_t range.
203          The check is slightly conservative, but an exact check isn't
204          worth the trouble.  */
205       if ((size_t) -1 / 3 * 2 / s <= n)
206         xalloc_die ();
207       n += (n + 1) / 2;
208     }
209
210   *pn = n;
211   return xrealloc (p, n * s);
212 }
213
214 /* Return a pointer to a new buffer of N bytes.  This is like xmalloc,
215    except it returns char *.  */
216
217 XALLOC_INLINE char *xcharalloc (size_t n)
218                     _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_ALLOC_SIZE ((1));
219 XALLOC_INLINE char *
220 xcharalloc (size_t n)
221 {
222   return XNMALLOC (n, char);
223 }
224
225 #ifdef __cplusplus
226 }
227
228 /* C++ does not allow conversions from void * to other pointer types
229    without a cast.  Use templates to work around the problem when
230    possible.  */
231
232 template <typename T> inline T *
233 xrealloc (T *p, size_t s)
234 {
235   return (T *) xrealloc ((void *) p, s);
236 }
237
238 template <typename T> inline T *
239 xnrealloc (T *p, size_t n, size_t s)
240 {
241   return (T *) xnrealloc ((void *) p, n, s);
242 }
243
244 template <typename T> inline T *
245 x2realloc (T *p, size_t *pn)
246 {
247   return (T *) x2realloc ((void *) p, pn);
248 }
249
250 template <typename T> inline T *
251 x2nrealloc (T *p, size_t *pn, size_t s)
252 {
253   return (T *) x2nrealloc ((void *) p, pn, s);
254 }
255
256 template <typename T> inline T *
257 xmemdup (T const *p, size_t s)
258 {
259   return (T *) xmemdup ((void const *) p, s);
260 }
261
262 #endif
263
264
265 #endif /* !XALLOC_H_ */