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