1 /* Test for dynamic arrays.
2 Copyright (C) 2017-2022 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 #include "tst-dynarray-shared.h"
20
21 #include <errno.h>
22 #include <stdint.h>
23 #include <libc-diag.h>
24
25 #define DYNARRAY_STRUCT dynarray_long
26 #define DYNARRAY_ELEMENT long
27 #define DYNARRAY_PREFIX dynarray_long_
28 #define DYNARRAY_ELEMENT_INIT(e) (*(e) = 17)
29 #include <malloc/dynarray-skeleton.c>
30
31 struct long_array
32 {
33 long *array;
34 size_t length;
35 };
36
37 #define DYNARRAY_STRUCT dynarray_long_noscratch
38 #define DYNARRAY_ELEMENT long
39 #define DYNARRAY_PREFIX dynarray_long_noscratch_
40 #define DYNARRAY_ELEMENT_INIT(e) (*(e) = 23)
41 #define DYNARRAY_FINAL_TYPE struct long_array
42 #define DYNARRAY_INITIAL_SIZE 0
43 #include <malloc/dynarray-skeleton.c>
44
45 #define DYNARRAY_STRUCT zstr
46 #define DYNARRAY_ELEMENT char
47 #define DYNARRAY_PREFIX zstr_
48 #define DYNARRAY_INITIAL_SIZE 128
49 #include <malloc/dynarray-skeleton.c>
50
51 #include <malloc.h>
52 #include <mcheck.h>
53 #include <stdint.h>
54 #include <support/check.h>
55 #include <support/support.h>
56
57 enum { max_count = 20 };
58
59 /* Test dynamic arrays with int elements (no automatic deallocation
60 for elements). */
61 static void
test_int(void)62 test_int (void)
63 {
64 /* Empty array. */
65 {
66 struct dynarray_int dyn;
67 dynarray_int_init (&dyn);
68 CHECK_EMPTY (int, &dyn);
69 }
70
71 /* Empty array with finalization. */
72 {
73 struct dynarray_int dyn;
74 dynarray_int_init (&dyn);
75 CHECK_INIT_STATE (int, &dyn);
76 struct int_array result = { (int *) (uintptr_t) -1, -1 };
77 TEST_VERIFY_EXIT (dynarray_int_finalize (&dyn, &result));
78 CHECK_INIT_STATE (int, &dyn);
79 TEST_VERIFY_EXIT (result.array == NULL);
80 TEST_VERIFY_EXIT (result.length == 0);
81 }
82
83 /* Non-empty array tests.
84
85 do_add: Switch between emplace (false) and add (true).
86 do_finalize: Perform finalize call at the end.
87 do_clear: Perform clear call at the end.
88 do_remove_last: Perform remove_last call after adding elements.
89 count: Number of elements added to the array. */
90 for (int do_add = 0; do_add < 2; ++do_add)
91 for (int do_finalize = 0; do_finalize < 2; ++do_finalize)
92 for (int do_clear = 0; do_clear < 2; ++do_clear)
93 for (int do_remove_last = 0; do_remove_last < 2; ++do_remove_last)
94 for (unsigned int count = 0; count < max_count; ++count)
95 {
96 if (do_remove_last && count == 0)
97 continue;
98 unsigned int base = count * count;
99 struct dynarray_int dyn;
100 dynarray_int_init (&dyn);
101 for (unsigned int i = 0; i < count; ++i)
102 {
103 if (do_add)
104 dynarray_int_add (&dyn, base + i);
105 else
106 {
107 int *place = dynarray_int_emplace (&dyn);
108 TEST_VERIFY_EXIT (place != NULL);
109 *place = base + i;
110 }
111 TEST_VERIFY_EXIT (!dynarray_int_has_failed (&dyn));
112 TEST_VERIFY_EXIT (dynarray_int_size (&dyn) == i + 1);
113 TEST_VERIFY_EXIT (dynarray_int_size (&dyn)
114 <= dyn.u.dynarray_header.allocated);
115 }
116 TEST_VERIFY_EXIT (dynarray_int_size (&dyn) == count);
117 TEST_VERIFY_EXIT (count <= dyn.u.dynarray_header.allocated);
118 if (count > 0)
119 {
120 TEST_VERIFY (dynarray_int_begin (&dyn)
121 == dynarray_int_at (&dyn, 0));
122 TEST_VERIFY (dynarray_int_end (&dyn)
123 == dynarray_int_at (&dyn, count - 1) + 1);
124 }
125 unsigned final_count;
126 bool heap_array = dyn.u.dynarray_header.array != dyn.scratch;
127 if (do_remove_last)
128 {
129 dynarray_int_remove_last (&dyn);
130 if (count == 0)
131 final_count = 0;
132 else
133 final_count = count - 1;
134 }
135 else
136 final_count = count;
137 if (final_count > 0)
138 {
139 TEST_VERIFY (dynarray_int_begin (&dyn)
140 == dynarray_int_at (&dyn, 0));
141 TEST_VERIFY (dynarray_int_end (&dyn)
142 == dynarray_int_at (&dyn, final_count - 1) + 1);
143 }
144 if (do_clear)
145 {
146 dynarray_int_clear (&dyn);
147 final_count = 0;
148 }
149 TEST_VERIFY_EXIT (!dynarray_int_has_failed (&dyn));
150 TEST_VERIFY_EXIT ((dyn.u.dynarray_header.array != dyn.scratch)
151 == heap_array);
152 TEST_VERIFY_EXIT (dynarray_int_size (&dyn) == final_count);
153 TEST_VERIFY_EXIT (dyn.u.dynarray_header.allocated
154 >= final_count);
155 if (!do_clear)
156 for (unsigned int i = 0; i < final_count; ++i)
157 TEST_VERIFY_EXIT (*dynarray_int_at (&dyn, i) == base + i);
158 if (do_finalize)
159 {
160 struct int_array result = { (int *) (uintptr_t) -1, -1 };
161 TEST_VERIFY_EXIT (dynarray_int_finalize (&dyn, &result));
162 CHECK_INIT_STATE (int, &dyn);
163 TEST_VERIFY_EXIT (result.length == final_count);
164 if (final_count == 0)
165 TEST_VERIFY_EXIT (result.array == NULL);
166 else
167 {
168 TEST_VERIFY_EXIT (result.array != NULL);
169 TEST_VERIFY_EXIT (result.array != (int *) (uintptr_t) -1);
170 TEST_VERIFY_EXIT
171 (malloc_usable_size (result.array)
172 >= final_count * sizeof (result.array[0]));
173 for (unsigned int i = 0; i < final_count; ++i)
174 TEST_VERIFY_EXIT (result.array[i] == base + i);
175 free (result.array);
176 }
177 }
178 else /* !do_finalize */
179 {
180 dynarray_int_free (&dyn);
181 CHECK_INIT_STATE (int, &dyn);
182 }
183 }
184 }
185
186 /* Test dynamic arrays with char * elements (with automatic
187 deallocation of the pointed-to strings). */
188 static void
test_str(void)189 test_str (void)
190 {
191 /* Empty array. */
192 {
193 struct dynarray_str dyn;
194 dynarray_str_init (&dyn);
195 CHECK_EMPTY (str, &dyn);
196 }
197
198 /* Empty array with finalization. */
199 {
200 struct dynarray_str dyn;
201 dynarray_str_init (&dyn);
202 TEST_VERIFY_EXIT (!dynarray_str_has_failed (&dyn));
203 struct str_array result = { (char **) (uintptr_t) -1, -1 };
204 TEST_VERIFY_EXIT (dynarray_str_finalize (&dyn, &result));
205 CHECK_INIT_STATE (str, &dyn);
206 TEST_VERIFY_EXIT (result.array == NULL);
207 TEST_VERIFY_EXIT (result.length == 0);
208 }
209
210 /* Non-empty array tests.
211
212 do_add: Switch between emplace (false) and add (true).
213 do_finalize: Perform finalize call at the end.
214 do_clear: Perform clear call at the end.
215 do_remove_last: Perform remove_last call after adding elements.
216 count: Number of elements added to the array. */
217 for (int do_add = 0; do_add < 2; ++do_add)
218 for (int do_finalize = 0; do_finalize < 2; ++do_finalize)
219 for (int do_clear = 0; do_clear < 2; ++do_clear)
220 for (int do_remove_last = 0; do_remove_last < 2; ++do_remove_last)
221 for (unsigned int count = 0; count < max_count; ++count)
222 {
223 if (do_remove_last && count == 0)
224 continue;
225 unsigned int base = count * count;
226 struct dynarray_str dyn;
227 dynarray_str_init (&dyn);
228 for (unsigned int i = 0; i < count; ++i)
229 {
230 char *item = xasprintf ("%d", base + i);
231 if (do_add)
232 dynarray_str_add (&dyn, item);
233 else
234 {
235 char **place = dynarray_str_emplace (&dyn);
236 TEST_VERIFY_EXIT (place != NULL);
237 TEST_VERIFY_EXIT (*place == NULL);
238 *place = item;
239 }
240 TEST_VERIFY_EXIT (!dynarray_str_has_failed (&dyn));
241 TEST_VERIFY_EXIT (dynarray_str_size (&dyn) == i + 1);
242 TEST_VERIFY_EXIT (dynarray_str_size (&dyn)
243 <= dyn.u.dynarray_header.allocated);
244 }
245 TEST_VERIFY_EXIT (dynarray_str_size (&dyn) == count);
246 TEST_VERIFY_EXIT (count <= dyn.u.dynarray_header.allocated);
247 if (count > 0)
248 {
249 TEST_VERIFY (dynarray_str_begin (&dyn)
250 == dynarray_str_at (&dyn, 0));
251 TEST_VERIFY (dynarray_str_end (&dyn)
252 == dynarray_str_at (&dyn, count - 1) + 1);
253 }
254 unsigned final_count;
255 bool heap_array = dyn.u.dynarray_header.array != dyn.scratch;
256 if (do_remove_last)
257 {
258 dynarray_str_remove_last (&dyn);
259 if (count == 0)
260 final_count = 0;
261 else
262 final_count = count - 1;
263 }
264 else
265 final_count = count;
266 if (final_count > 0)
267 {
268 TEST_VERIFY (dynarray_str_begin (&dyn)
269 == dynarray_str_at (&dyn, 0));
270 TEST_VERIFY (dynarray_str_end (&dyn)
271 == dynarray_str_at (&dyn, final_count - 1) + 1);
272 }
273 if (do_clear)
274 {
275 dynarray_str_clear (&dyn);
276 final_count = 0;
277 }
278 TEST_VERIFY_EXIT (!dynarray_str_has_failed (&dyn));
279 TEST_VERIFY_EXIT ((dyn.u.dynarray_header.array != dyn.scratch)
280 == heap_array);
281 TEST_VERIFY_EXIT (dynarray_str_size (&dyn) == final_count);
282 TEST_VERIFY_EXIT (dyn.u.dynarray_header.allocated
283 >= final_count);
284 if (!do_clear)
285 for (unsigned int i = 0; i < count - do_remove_last; ++i)
286 {
287 char *expected = xasprintf ("%d", base + i);
288 const char *actual = *dynarray_str_at (&dyn, i);
289 TEST_VERIFY_EXIT (strcmp (actual, expected) == 0);
290 free (expected);
291 }
292 if (do_finalize)
293 {
294 struct str_array result = { (char **) (uintptr_t) -1, -1 };
295 TEST_VERIFY_EXIT (dynarray_str_finalize (&dyn, &result));
296 CHECK_INIT_STATE (str, &dyn);
297 TEST_VERIFY_EXIT (result.length == final_count);
298 if (final_count == 0)
299 TEST_VERIFY_EXIT (result.array == NULL);
300 else
301 {
302 TEST_VERIFY_EXIT (result.array != NULL);
303 TEST_VERIFY_EXIT (result.array
304 != (char **) (uintptr_t) -1);
305 TEST_VERIFY_EXIT (result.length
306 == count - do_remove_last);
307 TEST_VERIFY_EXIT
308 (malloc_usable_size (result.array)
309 >= final_count * sizeof (result.array[0]));
310 for (unsigned int i = 0; i < count - do_remove_last; ++i)
311 {
312 char *expected = xasprintf ("%d", base + i);
313 char *actual = result.array[i];
314 TEST_VERIFY_EXIT (strcmp (actual, expected) == 0);
315 free (expected);
316 free (actual);
317 }
318 free (result.array);
319 }
320 }
321 else /* !do_finalize */
322 {
323 dynarray_str_free (&dyn);
324 CHECK_INIT_STATE (str, &dyn);
325 }
326 }
327
328 /* Test resizing. */
329 {
330 enum { count = 2131 };
331 struct dynarray_str dyn;
332 dynarray_str_init (&dyn);
333
334 /* From length 0 to length 1. */
335 TEST_VERIFY (dynarray_str_resize (&dyn, 1));
336 TEST_VERIFY (dynarray_str_size (&dyn) == 1);
337 TEST_VERIFY (*dynarray_str_at (&dyn, 0) == NULL);
338 *dynarray_str_at (&dyn, 0) = xstrdup ("allocated");
339 dynarray_str_free (&dyn);
340
341 /* From length 0 to length 1 and 2. */
342 TEST_VERIFY (dynarray_str_resize (&dyn, 1));
343 TEST_VERIFY (dynarray_str_size (&dyn) == 1);
344 TEST_VERIFY (*dynarray_str_at (&dyn, 0) == NULL);
345 *dynarray_str_at (&dyn, 0) = xstrdup ("allocated0");
346 TEST_VERIFY (dynarray_str_resize (&dyn, 2));
347 TEST_VERIFY (dynarray_str_size (&dyn) == 2);
348 TEST_VERIFY (strcmp (*dynarray_str_at (&dyn, 0), "allocated0") == 0);
349 TEST_VERIFY (*dynarray_str_at (&dyn, 1) == NULL);
350 *dynarray_str_at (&dyn, 1) = xstrdup ("allocated1");
351 TEST_VERIFY (dynarray_str_resize (&dyn, count));
352 TEST_VERIFY (dynarray_str_size (&dyn) == count);
353 TEST_VERIFY (strcmp (*dynarray_str_at (&dyn, 0), "allocated0") == 0);
354 TEST_VERIFY (strcmp (*dynarray_str_at (&dyn, 1), "allocated1") == 0);
355 for (int i = 2; i < count; ++i)
356 TEST_VERIFY (*dynarray_str_at (&dyn, i) == NULL);
357 *dynarray_str_at (&dyn, count - 1) = xstrdup ("allocated2");
358 TEST_VERIFY (dynarray_str_resize (&dyn, 3));
359 TEST_VERIFY (strcmp (*dynarray_str_at (&dyn, 0), "allocated0") == 0);
360 TEST_VERIFY (strcmp (*dynarray_str_at (&dyn, 1), "allocated1") == 0);
361 TEST_VERIFY (*dynarray_str_at (&dyn, 2) == NULL);
362 dynarray_str_free (&dyn);
363 }
364 }
365
366 /* Verify that DYNARRAY_ELEMENT_INIT has an effect. */
367 static void
test_long_init(void)368 test_long_init (void)
369 {
370 enum { count = 2131 };
371 {
372 struct dynarray_long dyn;
373 dynarray_long_init (&dyn);
374 for (int i = 0; i < count; ++i)
375 {
376 long *place = dynarray_long_emplace (&dyn);
377 TEST_VERIFY_EXIT (place != NULL);
378 TEST_VERIFY (*place == 17);
379 }
380 TEST_VERIFY (dynarray_long_size (&dyn) == count);
381 for (int i = 0; i < count; ++i)
382 TEST_VERIFY (*dynarray_long_at (&dyn, i) == 17);
383 dynarray_long_free (&dyn);
384
385 TEST_VERIFY (dynarray_long_resize (&dyn, 1));
386 TEST_VERIFY (dynarray_long_size (&dyn) == 1);
387 TEST_VERIFY (*dynarray_long_at (&dyn, 0) == 17);
388 *dynarray_long_at (&dyn, 0) = 18;
389 dynarray_long_free (&dyn);
390 TEST_VERIFY (dynarray_long_resize (&dyn, 1));
391 TEST_VERIFY (dynarray_long_size (&dyn) == 1);
392 TEST_VERIFY (*dynarray_long_at (&dyn, 0) == 17);
393 TEST_VERIFY (dynarray_long_resize (&dyn, 2));
394 TEST_VERIFY (dynarray_long_size (&dyn) == 2);
395 TEST_VERIFY (*dynarray_long_at (&dyn, 0) == 17);
396 TEST_VERIFY (*dynarray_long_at (&dyn, 1) == 17);
397 *dynarray_long_at (&dyn, 0) = 18;
398 TEST_VERIFY (dynarray_long_resize (&dyn, count));
399 TEST_VERIFY (dynarray_long_size (&dyn) == count);
400 TEST_VERIFY (*dynarray_long_at (&dyn, 0) == 18);
401 for (int i = 1; i < count; ++i)
402 TEST_VERIFY (*dynarray_long_at (&dyn, i) == 17);
403 dynarray_long_free (&dyn);
404 }
405
406 /* Similar, but without an on-stack scratch region
407 (DYNARRAY_INITIAL_SIZE is 0). */
408 {
409 struct dynarray_long_noscratch dyn;
410 dynarray_long_noscratch_init (&dyn);
411 struct long_array result;
412 TEST_VERIFY_EXIT (dynarray_long_noscratch_finalize (&dyn, &result));
413 TEST_VERIFY (result.array == NULL);
414 TEST_VERIFY (result.length == 0);
415
416 /* Test with one element. */
417 {
418 long *place = dynarray_long_noscratch_emplace (&dyn);
419 TEST_VERIFY_EXIT (place != NULL);
420 TEST_VERIFY (*place == 23);
421 }
422 TEST_VERIFY (dynarray_long_noscratch_size (&dyn) == 1);
423 TEST_VERIFY (*dynarray_long_noscratch_at (&dyn, 0) == 23);
424 TEST_VERIFY_EXIT (dynarray_long_noscratch_finalize (&dyn, &result));
425 TEST_VERIFY_EXIT (result.array != NULL);
426 TEST_VERIFY (result.length == 1);
427 TEST_VERIFY (result.array[0] == 23);
428 free (result.array);
429
430 for (int i = 0; i < count; ++i)
431 {
432 long *place = dynarray_long_noscratch_emplace (&dyn);
433 TEST_VERIFY_EXIT (place != NULL);
434 TEST_VERIFY (*place == 23);
435 if (i == 0)
436 *place = 29;
437 }
438 TEST_VERIFY (dynarray_long_noscratch_size (&dyn) == count);
439 TEST_VERIFY (*dynarray_long_noscratch_at (&dyn, 0) == 29);
440 for (int i = 1; i < count; ++i)
441 TEST_VERIFY (*dynarray_long_noscratch_at (&dyn, i) == 23);
442 TEST_VERIFY_EXIT (dynarray_long_noscratch_finalize (&dyn, &result));
443 TEST_VERIFY_EXIT (result.array != NULL);
444 TEST_VERIFY (result.length == count);
445 TEST_VERIFY (result.array[0] == 29);
446 for (int i = 1; i < count; ++i)
447 TEST_VERIFY (result.array[i] == 23);
448 free (result.array);
449
450 TEST_VERIFY (dynarray_long_noscratch_resize (&dyn, 1));
451 TEST_VERIFY (dynarray_long_noscratch_size (&dyn) == 1);
452 TEST_VERIFY (*dynarray_long_noscratch_at (&dyn, 0) == 23);
453 *dynarray_long_noscratch_at (&dyn, 0) = 24;
454 dynarray_long_noscratch_free (&dyn);
455 TEST_VERIFY (dynarray_long_noscratch_resize (&dyn, 1));
456 TEST_VERIFY (dynarray_long_noscratch_size (&dyn) == 1);
457 TEST_VERIFY (*dynarray_long_noscratch_at (&dyn, 0) == 23);
458 TEST_VERIFY (dynarray_long_noscratch_resize (&dyn, 2));
459 TEST_VERIFY (dynarray_long_noscratch_size (&dyn) == 2);
460 TEST_VERIFY (*dynarray_long_noscratch_at (&dyn, 0) == 23);
461 TEST_VERIFY (*dynarray_long_noscratch_at (&dyn, 1) == 23);
462 *dynarray_long_noscratch_at (&dyn, 0) = 24;
463 TEST_VERIFY (dynarray_long_noscratch_resize (&dyn, count));
464 TEST_VERIFY (dynarray_long_noscratch_size (&dyn) == count);
465 TEST_VERIFY (*dynarray_long_noscratch_at (&dyn, 0) == 24);
466 for (int i = 1; i < count; ++i)
467 TEST_VERIFY (*dynarray_long_noscratch_at (&dyn, i) == 23);
468 dynarray_long_noscratch_free (&dyn);
469 }
470 }
471
472 /* Test overflow in resize. */
473 static void
test_long_overflow(void)474 test_long_overflow (void)
475 {
476 {
477 struct dynarray_long dyn;
478 dynarray_long_init (&dyn);
479 errno = EINVAL;
480 DIAG_PUSH_NEEDS_COMMENT;
481 /* GCC 12 (on 32-bit platforms) warns that after inlining, a loop
482 iteration would invoke undefined behavior. That loop iteration
483 can never be executed because an allocation of this size must
484 fail. */
485 DIAG_IGNORE_NEEDS_COMMENT (12, "-Waggressive-loop-optimizations");
486 TEST_VERIFY (!dynarray_long_resize
487 (&dyn, (SIZE_MAX / sizeof (long)) + 1));
488 DIAG_POP_NEEDS_COMMENT;
489 TEST_VERIFY (errno == ENOMEM);
490 TEST_VERIFY (dynarray_long_has_failed (&dyn));
491 }
492
493 {
494 struct dynarray_long_noscratch dyn;
495 dynarray_long_noscratch_init (&dyn);
496 errno = EINVAL;
497 DIAG_PUSH_NEEDS_COMMENT;
498 /* GCC 12 (on 32-bit platforms) warns that after inlining, a loop
499 iteration would invoke undefined behavior. That loop iteration
500 can never be executed because an allocation of this size must
501 fail. */
502 DIAG_IGNORE_NEEDS_COMMENT (12, "-Waggressive-loop-optimizations");
503 TEST_VERIFY (!dynarray_long_noscratch_resize
504 (&dyn, (SIZE_MAX / sizeof (long)) + 1));
505 DIAG_POP_NEEDS_COMMENT;
506 TEST_VERIFY (errno == ENOMEM);
507 TEST_VERIFY (dynarray_long_noscratch_has_failed (&dyn));
508 }
509 }
510
511 /* Test NUL-terminated string construction with the add function and
512 the simple finalize function. */
513 static void
test_zstr(void)514 test_zstr (void)
515 {
516 /* Totally empty string (no NUL termination). */
517 {
518 struct zstr s;
519 zstr_init (&s);
520 char *result = zstr_finalize (&s, NULL);
521 TEST_VERIFY (result == NULL);
522 TEST_VERIFY (zstr_size (&s) == 0);
523 size_t length = 1;
524 result = zstr_finalize (&s, &length);
525 TEST_VERIFY (result == NULL);
526 TEST_VERIFY (length == 0);
527 TEST_VERIFY (zstr_size (&s) == 0);
528 }
529
530 /* Empty string. */
531 {
532 struct zstr s;
533 zstr_init (&s);
534 zstr_add (&s, '\0');
535 char *result = zstr_finalize (&s, NULL);
536 TEST_VERIFY_EXIT (result != NULL);
537 TEST_VERIFY (*result == '\0');
538 TEST_VERIFY (zstr_size (&s) == 0);
539 free (result);
540
541 zstr_add (&s, '\0');
542 size_t length = 1;
543 result = zstr_finalize (&s, &length);
544 TEST_VERIFY_EXIT (result != NULL);
545 TEST_VERIFY (*result == '\0');
546 TEST_VERIFY (length == 1);
547 TEST_VERIFY (zstr_size (&s) == 0);
548 free (result);
549 }
550
551 /* A few characters. */
552 {
553 struct zstr s;
554 zstr_init (&s);
555 zstr_add (&s, 'A');
556 zstr_add (&s, 'b');
557 zstr_add (&s, 'c');
558 zstr_add (&s, '\0');
559 char *result = zstr_finalize (&s, NULL);
560 TEST_VERIFY_EXIT (result != NULL);
561 TEST_VERIFY (strcmp (result, "Abc") == 0);
562 TEST_VERIFY (zstr_size (&s) == 0);
563 free (result);
564
565 zstr_add (&s, 'X');
566 zstr_add (&s, 'y');
567 zstr_add (&s, 'z');
568 zstr_add (&s, '\0');
569 size_t length = 1;
570 result = zstr_finalize (&s, &length);
571 TEST_VERIFY_EXIT (result != NULL);
572 TEST_VERIFY (strcmp (result, "Xyz") == 0);
573 TEST_VERIFY (length == 4);
574 TEST_VERIFY (zstr_size (&s) == 0);
575 free (result);
576 }
577 }
578
579 static int
do_test(void)580 do_test (void)
581 {
582 mtrace ();
583 test_int ();
584 test_str ();
585 test_long_init ();
586 test_long_overflow ();
587 test_zstr ();
588 return 0;
589 }
590
591 #include <support/test-driver.c>
592