Coverage Report

Created: 2023-03-26 07:33

/src/wget/lib/malloc/dynarray.h
Line
Count
Source (jump to first uncovered line)
1
/* Type-safe arrays which grow dynamically.  Shared definitions.
2
   Copyright (C) 2017-2023 Free Software Foundation, Inc.
3
   This file is part of the GNU C Library.
4
5
   The GNU C Library is free software; you can redistribute it and/or
6
   modify it under the terms of the GNU Lesser General Public
7
   License as published by the Free Software Foundation; either
8
   version 2.1 of the License, or (at your option) any later version.
9
10
   The GNU C Library 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 GNU
13
   Lesser General Public License for more details.
14
15
   You should have received a copy of the GNU Lesser General Public
16
   License along with the GNU C Library; if not, see
17
   <https://www.gnu.org/licenses/>.  */
18
19
/* To use the dynarray facility, you need to include
20
   <malloc/dynarray-skeleton.c> and define the parameter macros
21
   documented in that file.
22
23
   A minimal example which provides a growing list of integers can be
24
   defined like this:
25
26
     struct int_array
27
     {
28
       // Pointer to result array followed by its length,
29
       // as required by DYNARRAY_FINAL_TYPE.
30
       int *array;
31
       size_t length;
32
     };
33
34
     #define DYNARRAY_STRUCT dynarray_int
35
     #define DYNARRAY_ELEMENT int
36
     #define DYNARRAY_PREFIX dynarray_int_
37
     #define DYNARRAY_FINAL_TYPE struct int_array
38
     #include <malloc/dynarray-skeleton.c>
39
40
   To create a three-element array with elements 1, 2, 3, use this
41
   code:
42
43
     struct dynarray_int dyn;
44
     dynarray_int_init (&dyn);
45
     for (int i = 1; i <= 3; ++i)
46
       {
47
         int *place = dynarray_int_emplace (&dyn);
48
         assert (place != NULL);
49
         *place = i;
50
       }
51
     struct int_array result;
52
     bool ok = dynarray_int_finalize (&dyn, &result);
53
     assert (ok);
54
     assert (result.length == 3);
55
     assert (result.array[0] == 1);
56
     assert (result.array[1] == 2);
57
     assert (result.array[2] == 3);
58
     free (result.array);
59
60
   If the elements contain resources which must be freed, define
61
   DYNARRAY_ELEMENT_FREE appropriately, like this:
62
63
     struct str_array
64
     {
65
       char **array;
66
       size_t length;
67
     };
68
69
     #define DYNARRAY_STRUCT dynarray_str
70
     #define DYNARRAY_ELEMENT char *
71
     #define DYNARRAY_ELEMENT_FREE(ptr) free (*ptr)
72
     #define DYNARRAY_PREFIX dynarray_str_
73
     #define DYNARRAY_FINAL_TYPE struct str_array
74
     #include <malloc/dynarray-skeleton.c>
75
76
   Compared to scratch buffers, dynamic arrays have the following
77
   features:
78
79
   - They have an element type, and are not just an untyped buffer of
80
     bytes.
81
82
   - When growing, previously stored elements are preserved.  (It is
83
     expected that scratch_buffer_grow_preserve and
84
     scratch_buffer_set_array_size eventually go away because all
85
     current users are moved to dynamic arrays.)
86
87
   - Scratch buffers have a more aggressive growth policy because
88
     growing them typically means a retry of an operation (across an
89
     NSS service module boundary), which is expensive.
90
91
   - For the same reason, scratch buffers have a much larger initial
92
     stack allocation.  */
93
94
#ifndef _DYNARRAY_H
95
#define _DYNARRAY_H
96
97
#include <stddef.h>
98
#include <string.h>
99
100
struct dynarray_header
101
{
102
  size_t used;
103
  size_t allocated;
104
  void *array;
105
};
106
107
/* Marker used in the allocated member to indicate that an error was
108
   encountered.  */
109
static inline size_t
110
__dynarray_error_marker (void)
111
0
{
112
0
  return -1;
113
0
}
Unexecuted instantiation: regex.c:__dynarray_error_marker
Unexecuted instantiation: dynarray_resize.c:__dynarray_error_marker
114
115
/* Internal function.  See the has_failed function in
116
   dynarray-skeleton.c.  */
117
static inline bool
118
__dynarray_error (struct dynarray_header *list)
119
0
{
120
0
  return list->allocated == __dynarray_error_marker ();
121
0
}
Unexecuted instantiation: regex.c:__dynarray_error
Unexecuted instantiation: dynarray_resize.c:__dynarray_error
122
123
/* Internal function.  Enlarge the dynamically allocated area of the
124
   array to make room for one more element.  SCRATCH is a pointer to
125
   the scratch area (which is not heap-allocated and must not be
126
   freed).  ELEMENT_SIZE is the size, in bytes, of one element.
127
   Return false on failure, true on success.  */
128
bool __libc_dynarray_emplace_enlarge (struct dynarray_header *,
129
                                      void *scratch, size_t element_size);
130
131
/* Internal function.  Enlarge the dynamically allocated area of the
132
   array to make room for at least SIZE elements (which must be larger
133
   than the existing used part of the dynamic array).  SCRATCH is a
134
   pointer to the scratch area (which is not heap-allocated and must
135
   not be freed).  ELEMENT_SIZE is the size, in bytes, of one element.
136
   Return false on failure, true on success.  */
137
bool __libc_dynarray_resize (struct dynarray_header *, size_t size,
138
                             void *scratch, size_t element_size);
139
140
/* Internal function.  Like __libc_dynarray_resize, but clear the new
141
   part of the dynamic array.  */
142
bool __libc_dynarray_resize_clear (struct dynarray_header *, size_t size,
143
                                   void *scratch, size_t element_size);
144
145
/* Internal type.  */
146
struct dynarray_finalize_result
147
{
148
  void *array;
149
  size_t length;
150
};
151
152
/* Internal function.  Copy the dynamically-allocated area to an
153
   explicitly-sized heap allocation.  SCRATCH is a pointer to the
154
   embedded scratch space.  ELEMENT_SIZE is the size, in bytes, of the
155
   element type.  On success, true is returned, and pointer and length
156
   are written to *RESULT.  On failure, false is returned.  The caller
157
   has to take care of some of the memory management; this function is
158
   expected to be called from dynarray-skeleton.c.  */
159
bool __libc_dynarray_finalize (struct dynarray_header *list, void *scratch,
160
                               size_t element_size,
161
                               struct dynarray_finalize_result *result);
162
163
164
/* Internal function.  Terminate the process after an index error.
165
   SIZE is the number of elements of the dynamic array.  INDEX is the
166
   lookup index which triggered the failure.  */
167
_Noreturn void __libc_dynarray_at_failure (size_t size, size_t index);
168
169
#ifndef _ISOMAC
170
libc_hidden_proto (__libc_dynarray_emplace_enlarge)
171
libc_hidden_proto (__libc_dynarray_resize)
172
libc_hidden_proto (__libc_dynarray_resize_clear)
173
libc_hidden_proto (__libc_dynarray_finalize)
174
libc_hidden_proto (__libc_dynarray_at_failure)
175
#endif
176
177
#endif /* _DYNARRAY_H */