| 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 blockExecuted 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 blockExecuted 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 blockExecuted 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 |