maint: update copyright
[gnulib.git] / lib / eealloc.h
1 /* Memory allocation with expensive empty allocations.
2    Copyright (C) 2003, 2008, 2010-2014 Free Software Foundation, Inc.
3    Written by Bruno Haible <bruno@clisp.org>, 2003,
4    based on prior work by Jim Meyering.
5
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.
10
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.
15
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/>.  */
18
19 #ifndef _EEALLOC_H
20 #define _EEALLOC_H
21
22 /* malloc() and realloc() are allowed to return NULL when asked to allocate
23    a memory block of 0 bytes; this is not an out-of-memory condition.
24    (See ISO C 99 section 7.20.3.)  In some places, this is not welcome,
25    because it requires extra checking (so as not to confuse a zero-sized
26    allocation with an out-of-memory condition).  This file provides
27    malloc()/realloc() workalikes which return non-NULL pointers for
28    succeeding zero-sized allocations.  GNU libc already defines malloc()
29    and realloc() this way; on such platforms the workalikes are aliased
30    to the original malloc()/realloc() functions.  */
31
32 #include <stdlib.h>
33
34 #ifndef _GL_INLINE_HEADER_BEGIN
35  #error "Please include config.h first."
36 #endif
37 _GL_INLINE_HEADER_BEGIN
38 #ifndef EEALLOC_INLINE
39 # define EEALLOC_INLINE _GL_INLINE
40 #endif
41
42 #if MALLOC_0_IS_NONNULL
43 # define eemalloc malloc
44 #else
45 # if __GNUC__ >= 3
46 EEALLOC_INLINE void *eemalloc (size_t n)
47      __attribute__ ((__malloc__))
48 #  if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)
49      __attribute__ ((__alloc_size__ (1)))
50 #  endif
51   ;
52 # endif
53 EEALLOC_INLINE void *
54 eemalloc (size_t n)
55 {
56   /* If n is zero, allocate a 1-byte block.  */
57   if (n == 0)
58     n = 1;
59   return malloc (n);
60 }
61 #endif
62
63 #if REALLOC_0_IS_NONNULL
64 # define eerealloc realloc
65 #else
66 # if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)
67 EEALLOC_INLINE void *eerealloc (void *p, size_t n)
68      __attribute__ ((__alloc_size__ (2)));
69 # endif
70 EEALLOC_INLINE void *
71 eerealloc (void *p, size_t n)
72 {
73   /* If n is zero, allocate or keep a 1-byte block.  */
74   if (n == 0)
75     n = 1;
76   return realloc (p, n);
77 }
78 #endif
79
80 /* Maybe we should also define variants
81     eenmalloc (size_t n, size_t s) - behaves like eemalloc (n * s)
82     eezalloc (size_t n) - like eemalloc followed by memset 0
83     eecalloc (size_t n, size_t s) - like eemalloc (n * s) followed by memset 0
84     eenrealloc (void *p, size_t n, size_t s) - like eerealloc (p, n * s)
85    If this would be useful in your application. please speak up.  */
86
87 _GL_INLINE_HEADER_END
88
89 #endif /* _EEALLOC_H */