Absolute File Name: | /home/opencoverage/opencoverage/guest-scripts/coreutils/src/gnulib/lib/xalloc.h |
Source code | Switch to Preprocessed file |
Line | Source | Count | ||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | /* xalloc.h -- malloc with out-of-memory checking | - | ||||||||||||||||||
2 | - | |||||||||||||||||||
3 | Copyright (C) 1990-2000, 2003-2004, 2006-2018 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 <https://www.gnu.org/licenses/>. */ | - | ||||||||||||||||||
17 | - | |||||||||||||||||||
18 | #ifndef XALLOC_H_ | - | ||||||||||||||||||
19 | #define XALLOC_H_ | - | ||||||||||||||||||
20 | - | |||||||||||||||||||
21 | #include <stddef.h> | - | ||||||||||||||||||
22 | #include <stdint.h> | - | ||||||||||||||||||
23 | - | |||||||||||||||||||
24 | #include "xalloc-oversized.h" | - | ||||||||||||||||||
25 | - | |||||||||||||||||||
26 | #ifndef _GL_INLINE_HEADER_BEGIN | - | ||||||||||||||||||
27 | #error "Please include config.h first." | - | ||||||||||||||||||
28 | #endif | - | ||||||||||||||||||
29 | _GL_INLINE_HEADER_BEGIN | - | ||||||||||||||||||
30 | #ifndef XALLOC_INLINE | - | ||||||||||||||||||
31 | # define XALLOC_INLINE _GL_INLINE | - | ||||||||||||||||||
32 | #endif | - | ||||||||||||||||||
33 | - | |||||||||||||||||||
34 | #ifdef __cplusplus | - | ||||||||||||||||||
35 | extern "C" { | - | ||||||||||||||||||
36 | #endif | - | ||||||||||||||||||
37 | - | |||||||||||||||||||
38 | - | |||||||||||||||||||
39 | #if __GNUC__ >= 3 | - | ||||||||||||||||||
40 | # define _GL_ATTRIBUTE_MALLOC __attribute__ ((__malloc__)) | - | ||||||||||||||||||
41 | #else | - | ||||||||||||||||||
42 | # define _GL_ATTRIBUTE_MALLOC | - | ||||||||||||||||||
43 | #endif | - | ||||||||||||||||||
44 | - | |||||||||||||||||||
45 | #if ! defined __clang__ && \ | - | ||||||||||||||||||
46 | (__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_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))
| 0-15918 | ||||||||||||||||||
108 | xalloc_die (); never executed: xalloc_die (); | 0 | ||||||||||||||||||
109 | return xmalloc (n * s); executed 15918 times by 20 tests: return xmalloc (n * s); Executed by:
| 15918 | ||||||||||||||||||
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))
| 0-780 | ||||||||||||||||||
121 | xalloc_die (); never executed: xalloc_die (); | 0 | ||||||||||||||||||
122 | return xrealloc (p, n * s); executed 780 times by 6 tests: return xrealloc (p, n * s); Executed by:
| 780 | ||||||||||||||||||
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. S must be nonzero. Set *PN to the new number of | - | ||||||||||||||||||
128 | objects, and return the pointer to the new block. *PN is never set | - | ||||||||||||||||||
129 | to zero, and the returned pointer is never null. | - | ||||||||||||||||||
130 | - | |||||||||||||||||||
131 | Repeated reallocations are guaranteed to make progress, either by | - | ||||||||||||||||||
132 | allocating an initial block with a nonzero size, or by allocating a | - | ||||||||||||||||||
133 | larger block. | - | ||||||||||||||||||
134 | - | |||||||||||||||||||
135 | In the following implementation, nonzero sizes are increased by a | - | ||||||||||||||||||
136 | factor of approximately 1.5 so that repeated reallocations have | - | ||||||||||||||||||
137 | O(N) overall cost rather than O(N**2) cost, but the | - | ||||||||||||||||||
138 | specification for this function does not guarantee that rate. | - | ||||||||||||||||||
139 | - | |||||||||||||||||||
140 | Here is an example of use: | - | ||||||||||||||||||
141 | - | |||||||||||||||||||
142 | int *p = NULL; | - | ||||||||||||||||||
143 | size_t used = 0; | - | ||||||||||||||||||
144 | size_t allocated = 0; | - | ||||||||||||||||||
145 | - | |||||||||||||||||||
146 | void | - | ||||||||||||||||||
147 | append_int (int value) | - | ||||||||||||||||||
148 | { | - | ||||||||||||||||||
149 | if (used == allocated) | - | ||||||||||||||||||
150 | p = x2nrealloc (p, &allocated, sizeof *p); | - | ||||||||||||||||||
151 | p[used++] = value; | - | ||||||||||||||||||
152 | } | - | ||||||||||||||||||
153 | - | |||||||||||||||||||
154 | This causes x2nrealloc to allocate a block of some nonzero size the | - | ||||||||||||||||||
155 | first time it is called. | - | ||||||||||||||||||
156 | - | |||||||||||||||||||
157 | To have finer-grained control over the initial size, set *PN to a | - | ||||||||||||||||||
158 | nonzero value before calling this function with P == NULL. For | - | ||||||||||||||||||
159 | example: | - | ||||||||||||||||||
160 | - | |||||||||||||||||||
161 | int *p = NULL; | - | ||||||||||||||||||
162 | size_t used = 0; | - | ||||||||||||||||||
163 | size_t allocated = 0; | - | ||||||||||||||||||
164 | size_t allocated1 = 1000; | - | ||||||||||||||||||
165 | - | |||||||||||||||||||
166 | void | - | ||||||||||||||||||
167 | append_int (int value) | - | ||||||||||||||||||
168 | { | - | ||||||||||||||||||
169 | if (used == allocated) | - | ||||||||||||||||||
170 | { | - | ||||||||||||||||||
171 | p = x2nrealloc (p, &allocated1, sizeof *p); | - | ||||||||||||||||||
172 | allocated = allocated1; | - | ||||||||||||||||||
173 | } | - | ||||||||||||||||||
174 | p[used++] = value; | - | ||||||||||||||||||
175 | } | - | ||||||||||||||||||
176 | - | |||||||||||||||||||
177 | */ | - | ||||||||||||||||||
178 | - | |||||||||||||||||||
179 | XALLOC_INLINE void * | - | ||||||||||||||||||
180 | x2nrealloc (void *p, size_t *pn, size_t s) | - | ||||||||||||||||||
181 | { | - | ||||||||||||||||||
182 | size_t n = *pn; | - | ||||||||||||||||||
183 | - | |||||||||||||||||||
184 | if (! p)
| 245-8169 | ||||||||||||||||||
185 | { | - | ||||||||||||||||||
186 | if (! n)
| 25-8144 | ||||||||||||||||||
187 | { | - | ||||||||||||||||||
188 | /* The approximate size to use for initial small allocation | - | ||||||||||||||||||
189 | requests, when the invoking code specifies an old size of | - | ||||||||||||||||||
190 | zero. This is the largest "small" request for the GNU C | - | ||||||||||||||||||
191 | library malloc. */ | - | ||||||||||||||||||
192 | enum { DEFAULT_MXFAST = 64 * sizeof (size_t) / 4 }; | - | ||||||||||||||||||
193 | - | |||||||||||||||||||
194 | n = DEFAULT_MXFAST / s; | - | ||||||||||||||||||
195 | n += !n; | - | ||||||||||||||||||
196 | } executed 8144 times by 23 tests: end of block Executed by:
| 8144 | ||||||||||||||||||
197 | if (xalloc_oversized (n, s))
| 0-8169 | ||||||||||||||||||
198 | xalloc_die (); never executed: xalloc_die (); | 0 | ||||||||||||||||||
199 | } executed 8169 times by 24 tests: end of block Executed by:
| 8169 | ||||||||||||||||||
200 | else | - | ||||||||||||||||||
201 | { | - | ||||||||||||||||||
202 | /* Set N = floor (1.5 * N) + 1 so that progress is made even if N == 0. | - | ||||||||||||||||||
203 | Check for overflow, so that N * S stays in both ptrdiff_t and | - | ||||||||||||||||||
204 | size_t range. The check may be slightly conservative, but an | - | ||||||||||||||||||
205 | exact check isn't worth the trouble. */ | - | ||||||||||||||||||
206 | if ((PTRDIFF_MAX < SIZE_MAX ? PTRDIFF_MAX : SIZE_MAX) / 3 * 2 / s
| 0-245 | ||||||||||||||||||
207 | <= n)
| 0-245 | ||||||||||||||||||
208 | xalloc_die (); never executed: xalloc_die (); | 0 | ||||||||||||||||||
209 | n += n / 2 + 1; | - | ||||||||||||||||||
210 | } executed 245 times by 9 tests: end of block Executed by:
| 245 | ||||||||||||||||||
211 | - | |||||||||||||||||||
212 | *pn = n; | - | ||||||||||||||||||
213 | return xrealloc (p, n * s); executed 8414 times by 24 tests: return xrealloc (p, n * s); Executed by:
| 8414 | ||||||||||||||||||
214 | } | - | ||||||||||||||||||
215 | - | |||||||||||||||||||
216 | /* Return a pointer to a new buffer of N bytes. This is like xmalloc, | - | ||||||||||||||||||
217 | except it returns char *. */ | - | ||||||||||||||||||
218 | - | |||||||||||||||||||
219 | XALLOC_INLINE char *xcharalloc (size_t n) | - | ||||||||||||||||||
220 | _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_ALLOC_SIZE ((1)); | - | ||||||||||||||||||
221 | XALLOC_INLINE char * | - | ||||||||||||||||||
222 | xcharalloc (size_t n) | - | ||||||||||||||||||
223 | { | - | ||||||||||||||||||
224 | return XNMALLOC (n, char); executed 203 times by 22 tests: return ((char *) (sizeof (char) == 1 ? xmalloc (n) : xnmalloc (n, sizeof (char)))); Executed by:
| 203 | ||||||||||||||||||
225 | } | - | ||||||||||||||||||
226 | - | |||||||||||||||||||
227 | #ifdef __cplusplus | - | ||||||||||||||||||
228 | } | - | ||||||||||||||||||
229 | - | |||||||||||||||||||
230 | /* C++ does not allow conversions from void * to other pointer types | - | ||||||||||||||||||
231 | without a cast. Use templates to work around the problem when | - | ||||||||||||||||||
232 | possible. */ | - | ||||||||||||||||||
233 | - | |||||||||||||||||||
234 | template <typename T> inline T * | - | ||||||||||||||||||
235 | xrealloc (T *p, size_t s) | - | ||||||||||||||||||
236 | { | - | ||||||||||||||||||
237 | return (T *) xrealloc ((void *) p, s); | - | ||||||||||||||||||
238 | } | - | ||||||||||||||||||
239 | - | |||||||||||||||||||
240 | template <typename T> inline T * | - | ||||||||||||||||||
241 | xnrealloc (T *p, size_t n, size_t s) | - | ||||||||||||||||||
242 | { | - | ||||||||||||||||||
243 | return (T *) xnrealloc ((void *) p, n, s); | - | ||||||||||||||||||
244 | } | - | ||||||||||||||||||
245 | - | |||||||||||||||||||
246 | template <typename T> inline T * | - | ||||||||||||||||||
247 | x2realloc (T *p, size_t *pn) | - | ||||||||||||||||||
248 | { | - | ||||||||||||||||||
249 | return (T *) x2realloc ((void *) p, pn); | - | ||||||||||||||||||
250 | } | - | ||||||||||||||||||
251 | - | |||||||||||||||||||
252 | template <typename T> inline T * | - | ||||||||||||||||||
253 | x2nrealloc (T *p, size_t *pn, size_t s) | - | ||||||||||||||||||
254 | { | - | ||||||||||||||||||
255 | return (T *) x2nrealloc ((void *) p, pn, s); | - | ||||||||||||||||||
256 | } | - | ||||||||||||||||||
257 | - | |||||||||||||||||||
258 | template <typename T> inline T * | - | ||||||||||||||||||
259 | xmemdup (T const *p, size_t s) | - | ||||||||||||||||||
260 | { | - | ||||||||||||||||||
261 | return (T *) xmemdup ((void const *) p, s); | - | ||||||||||||||||||
262 | } | - | ||||||||||||||||||
263 | - | |||||||||||||||||||
264 | #endif | - | ||||||||||||||||||
265 | - | |||||||||||||||||||
266 | _GL_INLINE_HEADER_END | - | ||||||||||||||||||
267 | - | |||||||||||||||||||
268 | #endif /* !XALLOC_H_ */ | - | ||||||||||||||||||
Source code | Switch to Preprocessed file |