/src/wget2/lib/malloc/scratch_buffer.gl.h
Line | Count | Source |
1 | | /* DO NOT EDIT! GENERATED AUTOMATICALLY! */ |
2 | | /* Variable-sized buffer with on-stack default allocation. |
3 | | Copyright (C) 2015-2025 Free Software Foundation, Inc. |
4 | | This file is part of the GNU C Library. |
5 | | |
6 | | The GNU C Library is free software; you can redistribute it and/or |
7 | | modify it under the terms of the GNU Lesser General Public |
8 | | License as published by the Free Software Foundation; either |
9 | | version 2.1 of the License, or (at your option) any later version. |
10 | | |
11 | | The GNU C Library 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 GNU |
14 | | Lesser General Public License for more details. |
15 | | |
16 | | You should have received a copy of the GNU Lesser General Public |
17 | | License along with the GNU C Library; if not, see |
18 | | <https://www.gnu.org/licenses/>. */ |
19 | | |
20 | | #ifndef _SCRATCH_BUFFER_H |
21 | | #define _SCRATCH_BUFFER_H |
22 | | |
23 | | /* Scratch buffers with a default stack allocation and fallback to |
24 | | heap allocation. It is expected that this function is used in this |
25 | | way: |
26 | | |
27 | | struct scratch_buffer tmpbuf; |
28 | | scratch_buffer_init (&tmpbuf); |
29 | | |
30 | | while (!function_that_uses_buffer (tmpbuf.data, tmpbuf.length)) |
31 | | if (!scratch_buffer_grow (&tmpbuf)) |
32 | | return -1; |
33 | | |
34 | | scratch_buffer_free (&tmpbuf); |
35 | | return 0; |
36 | | |
37 | | The allocation functions (scratch_buffer_grow, |
38 | | scratch_buffer_grow_preserve, scratch_buffer_set_array_size) make |
39 | | sure that the heap allocation, if any, is freed, so that the code |
40 | | above does not have a memory leak. The buffer still remains in a |
41 | | state that can be deallocated using scratch_buffer_free, so a loop |
42 | | like this is valid as well: |
43 | | |
44 | | struct scratch_buffer tmpbuf; |
45 | | scratch_buffer_init (&tmpbuf); |
46 | | |
47 | | while (!function_that_uses_buffer (tmpbuf.data, tmpbuf.length)) |
48 | | if (!scratch_buffer_grow (&tmpbuf)) |
49 | | break; |
50 | | |
51 | | scratch_buffer_free (&tmpbuf); |
52 | | |
53 | | scratch_buffer_grow and scratch_buffer_grow_preserve are guaranteed |
54 | | to grow the buffer by at least 512 bytes. This means that when |
55 | | using the scratch buffer as a backing store for a non-character |
56 | | array whose element size, in bytes, is 512 or smaller, the scratch |
57 | | buffer only has to grow once to make room for at least one more |
58 | | element. |
59 | | */ |
60 | | |
61 | | #include <stdbool.h> |
62 | | #include <stddef.h> |
63 | | #include <stdlib.h> |
64 | | |
65 | | /* Scratch buffer. Must be initialized with scratch_buffer_init |
66 | | before its use. */ |
67 | | struct scratch_buffer { |
68 | | void *data; /* Pointer to the beginning of the scratch area. */ |
69 | | size_t length; /* Allocated space at the data pointer, in bytes. */ |
70 | | union { max_align_t __align; char __c[1024]; } __space; |
71 | | }; |
72 | | |
73 | | /* Initializes *BUFFER so that BUFFER->data points to BUFFER->__space |
74 | | and BUFFER->length reflects the available space. */ |
75 | | static inline void |
76 | | scratch_buffer_init (struct scratch_buffer *buffer) |
77 | 28.5k | { |
78 | 28.5k | buffer->data = buffer->__space.__c; |
79 | 28.5k | buffer->length = sizeof (buffer->__space); |
80 | 28.5k | } glob.c:scratch_buffer_init Line | Count | Source | 77 | 28.5k | { | 78 | 28.5k | buffer->data = buffer->__space.__c; | 79 | 28.5k | buffer->length = sizeof (buffer->__space); | 80 | 28.5k | } |
Unexecuted instantiation: scratch_buffer_grow.c:scratch_buffer_init Unexecuted instantiation: scratch_buffer_set_array_size.c:scratch_buffer_init |
81 | | |
82 | | /* Deallocates *BUFFER (if it was heap-allocated). */ |
83 | | static inline void |
84 | | scratch_buffer_free (struct scratch_buffer *buffer) |
85 | 28.5k | { |
86 | 28.5k | if (buffer->data != buffer->__space.__c) |
87 | 28.5k | free (buffer->data); |
88 | 28.5k | } glob.c:scratch_buffer_free Line | Count | Source | 85 | 28.5k | { | 86 | 28.5k | if (buffer->data != buffer->__space.__c) | 87 | 28.5k | free (buffer->data); | 88 | 28.5k | } |
Unexecuted instantiation: scratch_buffer_grow.c:scratch_buffer_free Unexecuted instantiation: scratch_buffer_set_array_size.c:scratch_buffer_free |
89 | | |
90 | | /* Grow *BUFFER by some arbitrary amount. The buffer contents is NOT |
91 | | preserved. Return true on success, false on allocation failure (in |
92 | | which case the old buffer is freed). On success, the new buffer is |
93 | | larger than the previous size. On failure, *BUFFER is deallocated, |
94 | | but remains in a free-able state, and errno is set. */ |
95 | | bool __libc_scratch_buffer_grow (struct scratch_buffer *buffer); |
96 | | |
97 | | /* Alias for __libc_scratch_buffer_grow. */ |
98 | | static inline _GL_ATTRIBUTE_ALWAYS_INLINE bool |
99 | | scratch_buffer_grow (struct scratch_buffer *buffer) |
100 | 0 | { |
101 | 0 | return _GL_LIKELY (__libc_scratch_buffer_grow (buffer)); |
102 | 0 | } Unexecuted instantiation: glob.c:scratch_buffer_grow Unexecuted instantiation: scratch_buffer_grow.c:scratch_buffer_grow Unexecuted instantiation: scratch_buffer_set_array_size.c:scratch_buffer_grow |
103 | | |
104 | | /* Like __libc_scratch_buffer_grow, but preserve the old buffer |
105 | | contents on success, as a prefix of the new buffer. */ |
106 | | bool __libc_scratch_buffer_grow_preserve (struct scratch_buffer *buffer); |
107 | | |
108 | | /* Alias for __libc_scratch_buffer_grow_preserve. */ |
109 | | static inline _GL_ATTRIBUTE_ALWAYS_INLINE bool |
110 | | scratch_buffer_grow_preserve (struct scratch_buffer *buffer) |
111 | 0 | { |
112 | 0 | return _GL_LIKELY (__libc_scratch_buffer_grow_preserve (buffer)); |
113 | 0 | } Unexecuted instantiation: glob.c:scratch_buffer_grow_preserve Unexecuted instantiation: scratch_buffer_grow.c:scratch_buffer_grow_preserve Unexecuted instantiation: scratch_buffer_set_array_size.c:scratch_buffer_grow_preserve |
114 | | |
115 | | /* Grow *BUFFER so that it can store at least NELEM elements of SIZE |
116 | | bytes. The buffer contents are NOT preserved. Both NELEM and SIZE |
117 | | can be zero. Return true on success, false on allocation failure |
118 | | (in which case the old buffer is freed, but *BUFFER remains in a |
119 | | free-able state, and errno is set). It is unspecified whether this |
120 | | function can reduce the array size. */ |
121 | | bool __libc_scratch_buffer_set_array_size (struct scratch_buffer *buffer, |
122 | | size_t nelem, size_t size); |
123 | | |
124 | | /* Alias for __libc_scratch_set_array_size. */ |
125 | | static inline _GL_ATTRIBUTE_ALWAYS_INLINE bool |
126 | | scratch_buffer_set_array_size (struct scratch_buffer *buffer, |
127 | | size_t nelem, size_t size) |
128 | 0 | { |
129 | 0 | return _GL_LIKELY (__libc_scratch_buffer_set_array_size |
130 | 0 | (buffer, nelem, size)); |
131 | 0 | } Unexecuted instantiation: glob.c:scratch_buffer_set_array_size Unexecuted instantiation: scratch_buffer_grow.c:scratch_buffer_set_array_size Unexecuted instantiation: scratch_buffer_set_array_size.c:scratch_buffer_set_array_size |
132 | | |
133 | | #endif /* _SCRATCH_BUFFER_H */ |