Remove "[Add new features here]" for 2.27
[glibc.git] / malloc / tst-dynarray.c
blob2206d75e318aaa3f616232d39805451bf2c6ad99
1 /* Test for dynamic arrays.
2 Copyright (C) 2017 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
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.
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.
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 <http://www.gnu.org/licenses/>. */
19 #include "tst-dynarray-shared.h"
21 #define DYNARRAY_STRUCT dynarray_long
22 #define DYNARRAY_ELEMENT long
23 #define DYNARRAY_PREFIX dynarray_long_
24 #define DYNARRAY_ELEMENT_INIT(e) (*(e) = 17)
25 #include <malloc/dynarray-skeleton.c>
27 struct long_array
29 long *array;
30 size_t length;
33 #define DYNARRAY_STRUCT dynarray_long_noscratch
34 #define DYNARRAY_ELEMENT long
35 #define DYNARRAY_PREFIX dynarray_long_noscratch_
36 #define DYNARRAY_ELEMENT_INIT(e) (*(e) = 23)
37 #define DYNARRAY_FINAL_TYPE struct long_array
38 #define DYNARRAY_INITIAL_SIZE 0
39 #include <malloc/dynarray-skeleton.c>
41 #define DYNARRAY_STRUCT zstr
42 #define DYNARRAY_ELEMENT char
43 #define DYNARRAY_PREFIX zstr_
44 #define DYNARRAY_INITIAL_SIZE 128
45 #include <malloc/dynarray-skeleton.c>
47 #include <malloc.h>
48 #include <mcheck.h>
49 #include <stdint.h>
50 #include <support/check.h>
51 #include <support/support.h>
53 enum { max_count = 20 };
55 /* Test dynamic arrays with int elements (no automatic deallocation
56 for elements). */
57 static void
58 test_int (void)
60 /* Empty array. */
62 struct dynarray_int dyn;
63 dynarray_int_init (&dyn);
64 CHECK_EMPTY (int, &dyn);
67 /* Empty array with finalization. */
69 struct dynarray_int dyn;
70 dynarray_int_init (&dyn);
71 CHECK_INIT_STATE (int, &dyn);
72 struct int_array result = { (int *) (uintptr_t) -1, -1 };
73 TEST_VERIFY_EXIT (dynarray_int_finalize (&dyn, &result));
74 CHECK_INIT_STATE (int, &dyn);
75 TEST_VERIFY_EXIT (result.array == NULL);
76 TEST_VERIFY_EXIT (result.length == 0);
79 /* Non-empty array tests.
81 do_add: Switch between emplace (false) and add (true).
82 do_finalize: Perform finalize call at the end.
83 do_clear: Perform clear call at the end.
84 do_remove_last: Perform remove_last call after adding elements.
85 count: Number of elements added to the array. */
86 for (int do_add = 0; do_add < 2; ++do_add)
87 for (int do_finalize = 0; do_finalize < 2; ++do_finalize)
88 for (int do_clear = 0; do_clear < 2; ++do_clear)
89 for (int do_remove_last = 0; do_remove_last < 2; ++do_remove_last)
90 for (unsigned int count = 0; count < max_count; ++count)
92 if (do_remove_last && count == 0)
93 continue;
94 unsigned int base = count * count;
95 struct dynarray_int dyn;
96 dynarray_int_init (&dyn);
97 for (unsigned int i = 0; i < count; ++i)
99 if (do_add)
100 dynarray_int_add (&dyn, base + i);
101 else
103 int *place = dynarray_int_emplace (&dyn);
104 TEST_VERIFY_EXIT (place != NULL);
105 *place = base + i;
107 TEST_VERIFY_EXIT (!dynarray_int_has_failed (&dyn));
108 TEST_VERIFY_EXIT (dynarray_int_size (&dyn) == i + 1);
109 TEST_VERIFY_EXIT (dynarray_int_size (&dyn)
110 <= dyn.dynarray_header.allocated);
112 TEST_VERIFY_EXIT (dynarray_int_size (&dyn) == count);
113 TEST_VERIFY_EXIT (count <= dyn.dynarray_header.allocated);
114 if (count > 0)
116 TEST_VERIFY (dynarray_int_begin (&dyn)
117 == dynarray_int_at (&dyn, 0));
118 TEST_VERIFY (dynarray_int_end (&dyn)
119 == dynarray_int_at (&dyn, count - 1) + 1);
121 unsigned final_count;
122 bool heap_array = dyn.dynarray_header.array != dyn.scratch;
123 if (do_remove_last)
125 dynarray_int_remove_last (&dyn);
126 if (count == 0)
127 final_count = 0;
128 else
129 final_count = count - 1;
131 else
132 final_count = count;
133 if (final_count > 0)
135 TEST_VERIFY (dynarray_int_begin (&dyn)
136 == dynarray_int_at (&dyn, 0));
137 TEST_VERIFY (dynarray_int_end (&dyn)
138 == dynarray_int_at (&dyn, final_count - 1) + 1);
140 if (do_clear)
142 dynarray_int_clear (&dyn);
143 final_count = 0;
145 TEST_VERIFY_EXIT (!dynarray_int_has_failed (&dyn));
146 TEST_VERIFY_EXIT ((dyn.dynarray_header.array != dyn.scratch)
147 == heap_array);
148 TEST_VERIFY_EXIT (dynarray_int_size (&dyn) == final_count);
149 TEST_VERIFY_EXIT (dyn.dynarray_header.allocated >= final_count);
150 if (!do_clear)
151 for (unsigned int i = 0; i < final_count; ++i)
152 TEST_VERIFY_EXIT (*dynarray_int_at (&dyn, i) == base + i);
153 if (do_finalize)
155 struct int_array result = { (int *) (uintptr_t) -1, -1 };
156 TEST_VERIFY_EXIT (dynarray_int_finalize (&dyn, &result));
157 CHECK_INIT_STATE (int, &dyn);
158 TEST_VERIFY_EXIT (result.length == final_count);
159 if (final_count == 0)
160 TEST_VERIFY_EXIT (result.array == NULL);
161 else
163 TEST_VERIFY_EXIT (result.array != NULL);
164 TEST_VERIFY_EXIT (result.array != (int *) (uintptr_t) -1);
165 TEST_VERIFY_EXIT
166 (malloc_usable_size (result.array)
167 >= final_count * sizeof (result.array[0]));
168 for (unsigned int i = 0; i < final_count; ++i)
169 TEST_VERIFY_EXIT (result.array[i] == base + i);
170 free (result.array);
173 else /* !do_finalize */
175 dynarray_int_free (&dyn);
176 CHECK_INIT_STATE (int, &dyn);
181 /* Test dynamic arrays with char * elements (with automatic
182 deallocation of the pointed-to strings). */
183 static void
184 test_str (void)
186 /* Empty array. */
188 struct dynarray_str dyn;
189 dynarray_str_init (&dyn);
190 CHECK_EMPTY (str, &dyn);
193 /* Empty array with finalization. */
195 struct dynarray_str dyn;
196 dynarray_str_init (&dyn);
197 TEST_VERIFY_EXIT (!dynarray_str_has_failed (&dyn));
198 struct str_array result = { (char **) (uintptr_t) -1, -1 };
199 TEST_VERIFY_EXIT (dynarray_str_finalize (&dyn, &result));
200 CHECK_INIT_STATE (str, &dyn);
201 TEST_VERIFY_EXIT (result.array == NULL);
202 TEST_VERIFY_EXIT (result.length == 0);
205 /* Non-empty array tests.
207 do_add: Switch between emplace (false) and add (true).
208 do_finalize: Perform finalize call at the end.
209 do_clear: Perform clear call at the end.
210 do_remove_last: Perform remove_last call after adding elements.
211 count: Number of elements added to the array. */
212 for (int do_add = 0; do_add < 2; ++do_add)
213 for (int do_finalize = 0; do_finalize < 2; ++do_finalize)
214 for (int do_clear = 0; do_clear < 2; ++do_clear)
215 for (int do_remove_last = 0; do_remove_last < 2; ++do_remove_last)
216 for (unsigned int count = 0; count < max_count; ++count)
218 if (do_remove_last && count == 0)
219 continue;
220 unsigned int base = count * count;
221 struct dynarray_str dyn;
222 dynarray_str_init (&dyn);
223 for (unsigned int i = 0; i < count; ++i)
225 char *item = xasprintf ("%d", base + i);
226 if (do_add)
227 dynarray_str_add (&dyn, item);
228 else
230 char **place = dynarray_str_emplace (&dyn);
231 TEST_VERIFY_EXIT (place != NULL);
232 TEST_VERIFY_EXIT (*place == NULL);
233 *place = item;
235 TEST_VERIFY_EXIT (!dynarray_str_has_failed (&dyn));
236 TEST_VERIFY_EXIT (dynarray_str_size (&dyn) == i + 1);
237 TEST_VERIFY_EXIT (dynarray_str_size (&dyn)
238 <= dyn.dynarray_header.allocated);
240 TEST_VERIFY_EXIT (dynarray_str_size (&dyn) == count);
241 TEST_VERIFY_EXIT (count <= dyn.dynarray_header.allocated);
242 if (count > 0)
244 TEST_VERIFY (dynarray_str_begin (&dyn)
245 == dynarray_str_at (&dyn, 0));
246 TEST_VERIFY (dynarray_str_end (&dyn)
247 == dynarray_str_at (&dyn, count - 1) + 1);
249 unsigned final_count;
250 bool heap_array = dyn.dynarray_header.array != dyn.scratch;
251 if (do_remove_last)
253 dynarray_str_remove_last (&dyn);
254 if (count == 0)
255 final_count = 0;
256 else
257 final_count = count - 1;
259 else
260 final_count = count;
261 if (final_count > 0)
263 TEST_VERIFY (dynarray_str_begin (&dyn)
264 == dynarray_str_at (&dyn, 0));
265 TEST_VERIFY (dynarray_str_end (&dyn)
266 == dynarray_str_at (&dyn, final_count - 1) + 1);
268 if (do_clear)
270 dynarray_str_clear (&dyn);
271 final_count = 0;
273 TEST_VERIFY_EXIT (!dynarray_str_has_failed (&dyn));
274 TEST_VERIFY_EXIT ((dyn.dynarray_header.array != dyn.scratch)
275 == heap_array);
276 TEST_VERIFY_EXIT (dynarray_str_size (&dyn) == final_count);
277 TEST_VERIFY_EXIT (dyn.dynarray_header.allocated >= final_count);
278 if (!do_clear)
279 for (unsigned int i = 0; i < count - do_remove_last; ++i)
281 char *expected = xasprintf ("%d", base + i);
282 const char *actual = *dynarray_str_at (&dyn, i);
283 TEST_VERIFY_EXIT (strcmp (actual, expected) == 0);
284 free (expected);
286 if (do_finalize)
288 struct str_array result = { (char **) (uintptr_t) -1, -1 };
289 TEST_VERIFY_EXIT (dynarray_str_finalize (&dyn, &result));
290 CHECK_INIT_STATE (str, &dyn);
291 TEST_VERIFY_EXIT (result.length == final_count);
292 if (final_count == 0)
293 TEST_VERIFY_EXIT (result.array == NULL);
294 else
296 TEST_VERIFY_EXIT (result.array != NULL);
297 TEST_VERIFY_EXIT (result.array
298 != (char **) (uintptr_t) -1);
299 TEST_VERIFY_EXIT (result.length
300 == count - do_remove_last);
301 TEST_VERIFY_EXIT
302 (malloc_usable_size (result.array)
303 >= final_count * sizeof (result.array[0]));
304 for (unsigned int i = 0; i < count - do_remove_last; ++i)
306 char *expected = xasprintf ("%d", base + i);
307 char *actual = result.array[i];
308 TEST_VERIFY_EXIT (strcmp (actual, expected) == 0);
309 free (expected);
310 free (actual);
312 free (result.array);
315 else /* !do_finalize */
317 dynarray_str_free (&dyn);
318 CHECK_INIT_STATE (str, &dyn);
322 /* Test resizing. */
324 enum { count = 2131 };
325 struct dynarray_str dyn;
326 dynarray_str_init (&dyn);
328 /* From length 0 to length 1. */
329 TEST_VERIFY (dynarray_str_resize (&dyn, 1));
330 TEST_VERIFY (dynarray_str_size (&dyn) == 1);
331 TEST_VERIFY (*dynarray_str_at (&dyn, 0) == NULL);
332 *dynarray_str_at (&dyn, 0) = xstrdup ("allocated");
333 dynarray_str_free (&dyn);
335 /* From length 0 to length 1 and 2. */
336 TEST_VERIFY (dynarray_str_resize (&dyn, 1));
337 TEST_VERIFY (dynarray_str_size (&dyn) == 1);
338 TEST_VERIFY (*dynarray_str_at (&dyn, 0) == NULL);
339 *dynarray_str_at (&dyn, 0) = xstrdup ("allocated0");
340 TEST_VERIFY (dynarray_str_resize (&dyn, 2));
341 TEST_VERIFY (dynarray_str_size (&dyn) == 2);
342 TEST_VERIFY (strcmp (*dynarray_str_at (&dyn, 0), "allocated0") == 0);
343 TEST_VERIFY (*dynarray_str_at (&dyn, 1) == NULL);
344 *dynarray_str_at (&dyn, 1) = xstrdup ("allocated1");
345 TEST_VERIFY (dynarray_str_resize (&dyn, count));
346 TEST_VERIFY (dynarray_str_size (&dyn) == count);
347 TEST_VERIFY (strcmp (*dynarray_str_at (&dyn, 0), "allocated0") == 0);
348 TEST_VERIFY (strcmp (*dynarray_str_at (&dyn, 1), "allocated1") == 0);
349 for (int i = 2; i < count; ++i)
350 TEST_VERIFY (*dynarray_str_at (&dyn, i) == NULL);
351 *dynarray_str_at (&dyn, count - 1) = xstrdup ("allocated2");
352 TEST_VERIFY (dynarray_str_resize (&dyn, 3));
353 TEST_VERIFY (strcmp (*dynarray_str_at (&dyn, 0), "allocated0") == 0);
354 TEST_VERIFY (strcmp (*dynarray_str_at (&dyn, 1), "allocated1") == 0);
355 TEST_VERIFY (*dynarray_str_at (&dyn, 2) == NULL);
356 dynarray_str_free (&dyn);
360 /* Verify that DYNARRAY_ELEMENT_INIT has an effect. */
361 static void
362 test_long_init (void)
364 enum { count = 2131 };
366 struct dynarray_long dyn;
367 dynarray_long_init (&dyn);
368 for (int i = 0; i < count; ++i)
370 long *place = dynarray_long_emplace (&dyn);
371 TEST_VERIFY_EXIT (place != NULL);
372 TEST_VERIFY (*place == 17);
374 TEST_VERIFY (dynarray_long_size (&dyn) == count);
375 for (int i = 0; i < count; ++i)
376 TEST_VERIFY (*dynarray_long_at (&dyn, i) == 17);
377 dynarray_long_free (&dyn);
379 TEST_VERIFY (dynarray_long_resize (&dyn, 1));
380 TEST_VERIFY (dynarray_long_size (&dyn) == 1);
381 TEST_VERIFY (*dynarray_long_at (&dyn, 0) == 17);
382 *dynarray_long_at (&dyn, 0) = 18;
383 dynarray_long_free (&dyn);
384 TEST_VERIFY (dynarray_long_resize (&dyn, 1));
385 TEST_VERIFY (dynarray_long_size (&dyn) == 1);
386 TEST_VERIFY (*dynarray_long_at (&dyn, 0) == 17);
387 TEST_VERIFY (dynarray_long_resize (&dyn, 2));
388 TEST_VERIFY (dynarray_long_size (&dyn) == 2);
389 TEST_VERIFY (*dynarray_long_at (&dyn, 0) == 17);
390 TEST_VERIFY (*dynarray_long_at (&dyn, 1) == 17);
391 *dynarray_long_at (&dyn, 0) = 18;
392 TEST_VERIFY (dynarray_long_resize (&dyn, count));
393 TEST_VERIFY (dynarray_long_size (&dyn) == count);
394 TEST_VERIFY (*dynarray_long_at (&dyn, 0) == 18);
395 for (int i = 1; i < count; ++i)
396 TEST_VERIFY (*dynarray_long_at (&dyn, i) == 17);
397 dynarray_long_free (&dyn);
400 /* Similar, but without an on-stack scratch region
401 (DYNARRAY_INITIAL_SIZE is 0). */
403 struct dynarray_long_noscratch dyn;
404 dynarray_long_noscratch_init (&dyn);
405 struct long_array result;
406 TEST_VERIFY_EXIT (dynarray_long_noscratch_finalize (&dyn, &result));
407 TEST_VERIFY (result.array == NULL);
408 TEST_VERIFY (result.length == 0);
410 /* Test with one element. */
412 long *place = dynarray_long_noscratch_emplace (&dyn);
413 TEST_VERIFY_EXIT (place != NULL);
414 TEST_VERIFY (*place == 23);
416 TEST_VERIFY (dynarray_long_noscratch_size (&dyn) == 1);
417 TEST_VERIFY (*dynarray_long_noscratch_at (&dyn, 0) == 23);
418 TEST_VERIFY_EXIT (dynarray_long_noscratch_finalize (&dyn, &result));
419 TEST_VERIFY_EXIT (result.array != NULL);
420 TEST_VERIFY (result.length == 1);
421 TEST_VERIFY (result.array[0] == 23);
422 free (result.array);
424 for (int i = 0; i < count; ++i)
426 long *place = dynarray_long_noscratch_emplace (&dyn);
427 TEST_VERIFY_EXIT (place != NULL);
428 TEST_VERIFY (*place == 23);
429 if (i == 0)
430 *place = 29;
432 TEST_VERIFY (dynarray_long_noscratch_size (&dyn) == count);
433 TEST_VERIFY (*dynarray_long_noscratch_at (&dyn, 0) == 29);
434 for (int i = 1; i < count; ++i)
435 TEST_VERIFY (*dynarray_long_noscratch_at (&dyn, i) == 23);
436 TEST_VERIFY_EXIT (dynarray_long_noscratch_finalize (&dyn, &result));
437 TEST_VERIFY_EXIT (result.array != NULL);
438 TEST_VERIFY (result.length == count);
439 TEST_VERIFY (result.array[0] == 29);
440 for (int i = 1; i < count; ++i)
441 TEST_VERIFY (result.array[i] == 23);
442 free (result.array);
444 TEST_VERIFY (dynarray_long_noscratch_resize (&dyn, 1));
445 TEST_VERIFY (dynarray_long_noscratch_size (&dyn) == 1);
446 TEST_VERIFY (*dynarray_long_noscratch_at (&dyn, 0) == 23);
447 *dynarray_long_noscratch_at (&dyn, 0) = 24;
448 dynarray_long_noscratch_free (&dyn);
449 TEST_VERIFY (dynarray_long_noscratch_resize (&dyn, 1));
450 TEST_VERIFY (dynarray_long_noscratch_size (&dyn) == 1);
451 TEST_VERIFY (*dynarray_long_noscratch_at (&dyn, 0) == 23);
452 TEST_VERIFY (dynarray_long_noscratch_resize (&dyn, 2));
453 TEST_VERIFY (dynarray_long_noscratch_size (&dyn) == 2);
454 TEST_VERIFY (*dynarray_long_noscratch_at (&dyn, 0) == 23);
455 TEST_VERIFY (*dynarray_long_noscratch_at (&dyn, 1) == 23);
456 *dynarray_long_noscratch_at (&dyn, 0) = 24;
457 TEST_VERIFY (dynarray_long_noscratch_resize (&dyn, count));
458 TEST_VERIFY (dynarray_long_noscratch_size (&dyn) == count);
459 TEST_VERIFY (*dynarray_long_noscratch_at (&dyn, 0) == 24);
460 for (int i = 1; i < count; ++i)
461 TEST_VERIFY (*dynarray_long_noscratch_at (&dyn, i) == 23);
462 dynarray_long_noscratch_free (&dyn);
466 /* Test NUL-terminated string construction with the add function and
467 the simple finalize function. */
468 static void
469 test_zstr (void)
471 /* Totally empty string (no NUL termination). */
473 struct zstr s;
474 zstr_init (&s);
475 char *result = zstr_finalize (&s, NULL);
476 TEST_VERIFY (result == NULL);
477 TEST_VERIFY (zstr_size (&s) == 0);
478 size_t length = 1;
479 result = zstr_finalize (&s, &length);
480 TEST_VERIFY (result == NULL);
481 TEST_VERIFY (length == 0);
482 TEST_VERIFY (zstr_size (&s) == 0);
485 /* Empty string. */
487 struct zstr s;
488 zstr_init (&s);
489 zstr_add (&s, '\0');
490 char *result = zstr_finalize (&s, NULL);
491 TEST_VERIFY_EXIT (result != NULL);
492 TEST_VERIFY (*result == '\0');
493 TEST_VERIFY (zstr_size (&s) == 0);
494 free (result);
496 zstr_add (&s, '\0');
497 size_t length = 1;
498 result = zstr_finalize (&s, &length);
499 TEST_VERIFY_EXIT (result != NULL);
500 TEST_VERIFY (*result == '\0');
501 TEST_VERIFY (length == 1);
502 TEST_VERIFY (zstr_size (&s) == 0);
503 free (result);
506 /* A few characters. */
508 struct zstr s;
509 zstr_init (&s);
510 zstr_add (&s, 'A');
511 zstr_add (&s, 'b');
512 zstr_add (&s, 'c');
513 zstr_add (&s, '\0');
514 char *result = zstr_finalize (&s, NULL);
515 TEST_VERIFY_EXIT (result != NULL);
516 TEST_VERIFY (strcmp (result, "Abc") == 0);
517 TEST_VERIFY (zstr_size (&s) == 0);
518 free (result);
520 zstr_add (&s, 'X');
521 zstr_add (&s, 'y');
522 zstr_add (&s, 'z');
523 zstr_add (&s, '\0');
524 size_t length = 1;
525 result = zstr_finalize (&s, &length);
526 TEST_VERIFY_EXIT (result != NULL);
527 TEST_VERIFY (strcmp (result, "Xyz") == 0);
528 TEST_VERIFY (length == 4);
529 TEST_VERIFY (zstr_size (&s) == 0);
530 free (result);
534 static int
535 do_test (void)
537 mtrace ();
538 test_int ();
539 test_str ();
540 test_long_init ();
541 test_zstr ();
542 return 0;
545 #include <support/test-driver.c>