Code

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