Blame malloc/tst-dynarray.c

Packit Service 82fcde
/* Test for dynamic arrays.
Packit Service 82fcde
   Copyright (C) 2017-2018 Free Software Foundation, Inc.
Packit Service 82fcde
   This file is part of the GNU C Library.
Packit Service 82fcde
Packit Service 82fcde
   The GNU C Library is free software; you can redistribute it and/or
Packit Service 82fcde
   modify it under the terms of the GNU Lesser General Public
Packit Service 82fcde
   License as published by the Free Software Foundation; either
Packit Service 82fcde
   version 2.1 of the License, or (at your option) any later version.
Packit Service 82fcde
Packit Service 82fcde
   The GNU C Library is distributed in the hope that it will be useful,
Packit Service 82fcde
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 82fcde
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service 82fcde
   Lesser General Public License for more details.
Packit Service 82fcde
Packit Service 82fcde
   You should have received a copy of the GNU Lesser General Public
Packit Service 82fcde
   License along with the GNU C Library; if not, see
Packit Service 82fcde
   <http://www.gnu.org/licenses/>.  */
Packit Service 82fcde
Packit Service 82fcde
#include "tst-dynarray-shared.h"
Packit Service 82fcde
Packit Service 82fcde
#include <errno.h>
Packit Service 82fcde
#include <stdint.h>
Packit Service 82fcde
Packit Service 82fcde
#define DYNARRAY_STRUCT dynarray_long
Packit Service 82fcde
#define DYNARRAY_ELEMENT long
Packit Service 82fcde
#define DYNARRAY_PREFIX dynarray_long_
Packit Service 82fcde
#define DYNARRAY_ELEMENT_INIT(e) (*(e) = 17)
Packit Service 82fcde
#include <malloc/dynarray-skeleton.c>
Packit Service 82fcde
Packit Service 82fcde
struct long_array
Packit Service 82fcde
{
Packit Service 82fcde
  long *array;
Packit Service 82fcde
  size_t length;
Packit Service 82fcde
};
Packit Service 82fcde
Packit Service 82fcde
#define DYNARRAY_STRUCT dynarray_long_noscratch
Packit Service 82fcde
#define DYNARRAY_ELEMENT long
Packit Service 82fcde
#define DYNARRAY_PREFIX dynarray_long_noscratch_
Packit Service 82fcde
#define DYNARRAY_ELEMENT_INIT(e) (*(e) = 23)
Packit Service 82fcde
#define DYNARRAY_FINAL_TYPE struct long_array
Packit Service 82fcde
#define DYNARRAY_INITIAL_SIZE 0
Packit Service 82fcde
#include <malloc/dynarray-skeleton.c>
Packit Service 82fcde
Packit Service 82fcde
#define DYNARRAY_STRUCT zstr
Packit Service 82fcde
#define DYNARRAY_ELEMENT char
Packit Service 82fcde
#define DYNARRAY_PREFIX zstr_
Packit Service 82fcde
#define DYNARRAY_INITIAL_SIZE 128
Packit Service 82fcde
#include <malloc/dynarray-skeleton.c>
Packit Service 82fcde
Packit Service 82fcde
#include <malloc.h>
Packit Service 82fcde
#include <mcheck.h>
Packit Service 82fcde
#include <stdint.h>
Packit Service 82fcde
#include <support/check.h>
Packit Service 82fcde
#include <support/support.h>
Packit Service 82fcde
Packit Service 82fcde
enum { max_count = 20 };
Packit Service 82fcde
Packit Service 82fcde
/* Test dynamic arrays with int elements (no automatic deallocation
Packit Service 82fcde
   for elements).  */
Packit Service 82fcde
static void
Packit Service 82fcde
test_int (void)
Packit Service 82fcde
{
Packit Service 82fcde
  /* Empty array.  */
Packit Service 82fcde
  {
Packit Service 82fcde
    struct dynarray_int dyn;
Packit Service 82fcde
    dynarray_int_init (&dyn);
Packit Service 82fcde
    CHECK_EMPTY (int, &dyn);
Packit Service 82fcde
  }
Packit Service 82fcde
Packit Service 82fcde
  /* Empty array with finalization.  */
Packit Service 82fcde
  {
Packit Service 82fcde
    struct dynarray_int dyn;
Packit Service 82fcde
    dynarray_int_init (&dyn);
Packit Service 82fcde
    CHECK_INIT_STATE (int, &dyn);
Packit Service 82fcde
    struct int_array result = { (int *) (uintptr_t) -1, -1 };
Packit Service 82fcde
    TEST_VERIFY_EXIT (dynarray_int_finalize (&dyn, &result));
Packit Service 82fcde
    CHECK_INIT_STATE (int, &dyn);
Packit Service 82fcde
    TEST_VERIFY_EXIT (result.array == NULL);
Packit Service 82fcde
    TEST_VERIFY_EXIT (result.length == 0);
Packit Service 82fcde
  }
Packit Service 82fcde
Packit Service 82fcde
  /* Non-empty array tests.
Packit Service 82fcde
Packit Service 82fcde
     do_add: Switch between emplace (false) and add (true).
Packit Service 82fcde
     do_finalize: Perform finalize call at the end.
Packit Service 82fcde
     do_clear: Perform clear call at the end.
Packit Service 82fcde
     do_remove_last: Perform remove_last call after adding elements.
Packit Service 82fcde
     count: Number of elements added to the array.  */
Packit Service 82fcde
  for (int do_add = 0; do_add < 2; ++do_add)
Packit Service 82fcde
    for (int do_finalize = 0; do_finalize < 2; ++do_finalize)
Packit Service 82fcde
      for (int do_clear = 0; do_clear < 2; ++do_clear)
Packit Service 82fcde
        for (int do_remove_last = 0; do_remove_last < 2; ++do_remove_last)
Packit Service 82fcde
          for (unsigned int count = 0; count < max_count; ++count)
Packit Service 82fcde
            {
Packit Service 82fcde
              if (do_remove_last && count == 0)
Packit Service 82fcde
                continue;
Packit Service 82fcde
              unsigned int base = count * count;
Packit Service 82fcde
              struct dynarray_int dyn;
Packit Service 82fcde
              dynarray_int_init (&dyn);
Packit Service 82fcde
              for (unsigned int i = 0; i < count; ++i)
Packit Service 82fcde
                {
Packit Service 82fcde
                  if (do_add)
Packit Service 82fcde
                    dynarray_int_add (&dyn, base + i);
Packit Service 82fcde
                  else
Packit Service 82fcde
                    {
Packit Service 82fcde
                      int *place = dynarray_int_emplace (&dyn);
Packit Service 82fcde
                      TEST_VERIFY_EXIT (place != NULL);
Packit Service 82fcde
                      *place = base + i;
Packit Service 82fcde
                    }
Packit Service 82fcde
                  TEST_VERIFY_EXIT (!dynarray_int_has_failed (&dyn));
Packit Service 82fcde
                  TEST_VERIFY_EXIT (dynarray_int_size (&dyn) == i + 1);
Packit Service 82fcde
                  TEST_VERIFY_EXIT (dynarray_int_size (&dyn)
Packit Service 82fcde
                                    <= dyn.dynarray_header.allocated);
Packit Service 82fcde
                }
Packit Service 82fcde
              TEST_VERIFY_EXIT (dynarray_int_size (&dyn) == count);
Packit Service 82fcde
              TEST_VERIFY_EXIT (count <= dyn.dynarray_header.allocated);
Packit Service 82fcde
              if (count > 0)
Packit Service 82fcde
                {
Packit Service 82fcde
                  TEST_VERIFY (dynarray_int_begin (&dyn)
Packit Service 82fcde
                               == dynarray_int_at (&dyn, 0));
Packit Service 82fcde
                  TEST_VERIFY (dynarray_int_end (&dyn)
Packit Service 82fcde
                               == dynarray_int_at (&dyn, count - 1) + 1);
Packit Service 82fcde
                }
Packit Service 82fcde
              unsigned final_count;
Packit Service 82fcde
              bool heap_array = dyn.dynarray_header.array != dyn.scratch;
Packit Service 82fcde
              if (do_remove_last)
Packit Service 82fcde
                {
Packit Service 82fcde
                  dynarray_int_remove_last (&dyn);
Packit Service 82fcde
                  if (count == 0)
Packit Service 82fcde
                    final_count = 0;
Packit Service 82fcde
                  else
Packit Service 82fcde
                    final_count = count - 1;
Packit Service 82fcde
                }
Packit Service 82fcde
              else
Packit Service 82fcde
                final_count = count;
Packit Service 82fcde
              if (final_count > 0)
Packit Service 82fcde
                {
Packit Service 82fcde
                  TEST_VERIFY (dynarray_int_begin (&dyn)
Packit Service 82fcde
                               == dynarray_int_at (&dyn, 0));
Packit Service 82fcde
                  TEST_VERIFY (dynarray_int_end (&dyn)
Packit Service 82fcde
                               == dynarray_int_at (&dyn, final_count - 1) + 1);
Packit Service 82fcde
                }
Packit Service 82fcde
              if (do_clear)
Packit Service 82fcde
                {
Packit Service 82fcde
                  dynarray_int_clear (&dyn);
Packit Service 82fcde
                  final_count = 0;
Packit Service 82fcde
                }
Packit Service 82fcde
              TEST_VERIFY_EXIT (!dynarray_int_has_failed (&dyn));
Packit Service 82fcde
              TEST_VERIFY_EXIT ((dyn.dynarray_header.array != dyn.scratch)
Packit Service 82fcde
                                == heap_array);
Packit Service 82fcde
              TEST_VERIFY_EXIT (dynarray_int_size (&dyn) == final_count);
Packit Service 82fcde
              TEST_VERIFY_EXIT (dyn.dynarray_header.allocated >= final_count);
Packit Service 82fcde
              if (!do_clear)
Packit Service 82fcde
                for (unsigned int i = 0; i < final_count; ++i)
Packit Service 82fcde
                  TEST_VERIFY_EXIT (*dynarray_int_at (&dyn, i) == base + i);
Packit Service 82fcde
              if (do_finalize)
Packit Service 82fcde
                {
Packit Service 82fcde
                  struct int_array result = { (int *) (uintptr_t) -1, -1 };
Packit Service 82fcde
                  TEST_VERIFY_EXIT (dynarray_int_finalize (&dyn, &result));
Packit Service 82fcde
                  CHECK_INIT_STATE (int, &dyn);
Packit Service 82fcde
                  TEST_VERIFY_EXIT (result.length == final_count);
Packit Service 82fcde
                  if (final_count == 0)
Packit Service 82fcde
                    TEST_VERIFY_EXIT (result.array == NULL);
Packit Service 82fcde
                  else
Packit Service 82fcde
                    {
Packit Service 82fcde
                      TEST_VERIFY_EXIT (result.array != NULL);
Packit Service 82fcde
                      TEST_VERIFY_EXIT (result.array != (int *) (uintptr_t) -1);
Packit Service 82fcde
                      TEST_VERIFY_EXIT
Packit Service 82fcde
                        (malloc_usable_size (result.array)
Packit Service 82fcde
                         >= final_count * sizeof (result.array[0]));
Packit Service 82fcde
                      for (unsigned int i = 0; i < final_count; ++i)
Packit Service 82fcde
                        TEST_VERIFY_EXIT (result.array[i] == base + i);
Packit Service 82fcde
                      free (result.array);
Packit Service 82fcde
                    }
Packit Service 82fcde
                }
Packit Service 82fcde
              else /* !do_finalize */
Packit Service 82fcde
                {
Packit Service 82fcde
                  dynarray_int_free (&dyn);
Packit Service 82fcde
                  CHECK_INIT_STATE (int, &dyn);
Packit Service 82fcde
                }
Packit Service 82fcde
            }
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
/* Test dynamic arrays with char * elements (with automatic
Packit Service 82fcde
   deallocation of the pointed-to strings).  */
Packit Service 82fcde
static void
Packit Service 82fcde
test_str (void)
Packit Service 82fcde
{
Packit Service 82fcde
  /* Empty array.  */
Packit Service 82fcde
  {
Packit Service 82fcde
    struct dynarray_str dyn;
Packit Service 82fcde
    dynarray_str_init (&dyn);
Packit Service 82fcde
    CHECK_EMPTY (str, &dyn);
Packit Service 82fcde
  }
Packit Service 82fcde
Packit Service 82fcde
  /* Empty array with finalization.  */
Packit Service 82fcde
  {
Packit Service 82fcde
    struct dynarray_str dyn;
Packit Service 82fcde
    dynarray_str_init (&dyn);
Packit Service 82fcde
    TEST_VERIFY_EXIT (!dynarray_str_has_failed (&dyn));
Packit Service 82fcde
    struct str_array result = { (char **) (uintptr_t) -1, -1 };
Packit Service 82fcde
    TEST_VERIFY_EXIT (dynarray_str_finalize (&dyn, &result));
Packit Service 82fcde
    CHECK_INIT_STATE (str, &dyn);
Packit Service 82fcde
    TEST_VERIFY_EXIT (result.array == NULL);
Packit Service 82fcde
    TEST_VERIFY_EXIT (result.length == 0);
Packit Service 82fcde
  }
Packit Service 82fcde
Packit Service 82fcde
  /* Non-empty array tests.
Packit Service 82fcde
Packit Service 82fcde
     do_add: Switch between emplace (false) and add (true).
Packit Service 82fcde
     do_finalize: Perform finalize call at the end.
Packit Service 82fcde
     do_clear: Perform clear call at the end.
Packit Service 82fcde
     do_remove_last: Perform remove_last call after adding elements.
Packit Service 82fcde
     count: Number of elements added to the array.  */
Packit Service 82fcde
  for (int do_add = 0; do_add < 2; ++do_add)
Packit Service 82fcde
    for (int do_finalize = 0; do_finalize < 2; ++do_finalize)
Packit Service 82fcde
      for (int do_clear = 0; do_clear < 2; ++do_clear)
Packit Service 82fcde
        for (int do_remove_last = 0; do_remove_last < 2; ++do_remove_last)
Packit Service 82fcde
          for (unsigned int count = 0; count < max_count; ++count)
Packit Service 82fcde
            {
Packit Service 82fcde
              if (do_remove_last && count == 0)
Packit Service 82fcde
                continue;
Packit Service 82fcde
              unsigned int base = count * count;
Packit Service 82fcde
              struct dynarray_str dyn;
Packit Service 82fcde
              dynarray_str_init (&dyn);
Packit Service 82fcde
              for (unsigned int i = 0; i < count; ++i)
Packit Service 82fcde
                {
Packit Service 82fcde
                  char *item = xasprintf ("%d", base + i);
Packit Service 82fcde
                  if (do_add)
Packit Service 82fcde
                    dynarray_str_add (&dyn, item);
Packit Service 82fcde
                  else
Packit Service 82fcde
                    {
Packit Service 82fcde
                      char **place = dynarray_str_emplace (&dyn);
Packit Service 82fcde
                      TEST_VERIFY_EXIT (place != NULL);
Packit Service 82fcde
                      TEST_VERIFY_EXIT (*place == NULL);
Packit Service 82fcde
                      *place = item;
Packit Service 82fcde
                    }
Packit Service 82fcde
                  TEST_VERIFY_EXIT (!dynarray_str_has_failed (&dyn));
Packit Service 82fcde
                  TEST_VERIFY_EXIT (dynarray_str_size (&dyn) == i + 1);
Packit Service 82fcde
                  TEST_VERIFY_EXIT (dynarray_str_size (&dyn)
Packit Service 82fcde
                                    <= dyn.dynarray_header.allocated);
Packit Service 82fcde
                }
Packit Service 82fcde
              TEST_VERIFY_EXIT (dynarray_str_size (&dyn) == count);
Packit Service 82fcde
              TEST_VERIFY_EXIT (count <= dyn.dynarray_header.allocated);
Packit Service 82fcde
              if (count > 0)
Packit Service 82fcde
                {
Packit Service 82fcde
                  TEST_VERIFY (dynarray_str_begin (&dyn)
Packit Service 82fcde
                               == dynarray_str_at (&dyn, 0));
Packit Service 82fcde
                  TEST_VERIFY (dynarray_str_end (&dyn)
Packit Service 82fcde
                               == dynarray_str_at (&dyn, count - 1) + 1);
Packit Service 82fcde
                }
Packit Service 82fcde
              unsigned final_count;
Packit Service 82fcde
              bool heap_array = dyn.dynarray_header.array != dyn.scratch;
Packit Service 82fcde
              if (do_remove_last)
Packit Service 82fcde
                {
Packit Service 82fcde
                  dynarray_str_remove_last (&dyn);
Packit Service 82fcde
                  if (count == 0)
Packit Service 82fcde
                    final_count = 0;
Packit Service 82fcde
                  else
Packit Service 82fcde
                    final_count = count - 1;
Packit Service 82fcde
                }
Packit Service 82fcde
              else
Packit Service 82fcde
                final_count = count;
Packit Service 82fcde
              if (final_count > 0)
Packit Service 82fcde
                {
Packit Service 82fcde
                  TEST_VERIFY (dynarray_str_begin (&dyn)
Packit Service 82fcde
                               == dynarray_str_at (&dyn, 0));
Packit Service 82fcde
                  TEST_VERIFY (dynarray_str_end (&dyn)
Packit Service 82fcde
                               == dynarray_str_at (&dyn, final_count - 1) + 1);
Packit Service 82fcde
                }
Packit Service 82fcde
              if (do_clear)
Packit Service 82fcde
                {
Packit Service 82fcde
                  dynarray_str_clear (&dyn);
Packit Service 82fcde
                  final_count = 0;
Packit Service 82fcde
                }
Packit Service 82fcde
              TEST_VERIFY_EXIT (!dynarray_str_has_failed (&dyn));
Packit Service 82fcde
              TEST_VERIFY_EXIT ((dyn.dynarray_header.array != dyn.scratch)
Packit Service 82fcde
                                == heap_array);
Packit Service 82fcde
              TEST_VERIFY_EXIT (dynarray_str_size (&dyn) == final_count);
Packit Service 82fcde
              TEST_VERIFY_EXIT (dyn.dynarray_header.allocated >= final_count);
Packit Service 82fcde
              if (!do_clear)
Packit Service 82fcde
                for (unsigned int i = 0; i < count - do_remove_last; ++i)
Packit Service 82fcde
                  {
Packit Service 82fcde
                    char *expected = xasprintf ("%d", base + i);
Packit Service 82fcde
                    const char *actual = *dynarray_str_at (&dyn, i);
Packit Service 82fcde
                    TEST_VERIFY_EXIT (strcmp (actual, expected) == 0);
Packit Service 82fcde
                    free (expected);
Packit Service 82fcde
                  }
Packit Service 82fcde
              if (do_finalize)
Packit Service 82fcde
                {
Packit Service 82fcde
                  struct str_array result = { (char **) (uintptr_t) -1, -1 };
Packit Service 82fcde
                  TEST_VERIFY_EXIT (dynarray_str_finalize (&dyn, &result));
Packit Service 82fcde
                  CHECK_INIT_STATE (str, &dyn);
Packit Service 82fcde
                  TEST_VERIFY_EXIT (result.length == final_count);
Packit Service 82fcde
                  if (final_count == 0)
Packit Service 82fcde
                    TEST_VERIFY_EXIT (result.array == NULL);
Packit Service 82fcde
                  else
Packit Service 82fcde
                    {
Packit Service 82fcde
                      TEST_VERIFY_EXIT (result.array != NULL);
Packit Service 82fcde
                      TEST_VERIFY_EXIT (result.array
Packit Service 82fcde
                                        != (char **) (uintptr_t) -1);
Packit Service 82fcde
                      TEST_VERIFY_EXIT (result.length
Packit Service 82fcde
                                        == count - do_remove_last);
Packit Service 82fcde
                      TEST_VERIFY_EXIT
Packit Service 82fcde
                        (malloc_usable_size (result.array)
Packit Service 82fcde
                         >= final_count * sizeof (result.array[0]));
Packit Service 82fcde
                      for (unsigned int i = 0; i < count - do_remove_last; ++i)
Packit Service 82fcde
                        {
Packit Service 82fcde
                          char *expected = xasprintf ("%d", base + i);
Packit Service 82fcde
                          char *actual = result.array[i];
Packit Service 82fcde
                          TEST_VERIFY_EXIT (strcmp (actual, expected) == 0);
Packit Service 82fcde
                          free (expected);
Packit Service 82fcde
                          free (actual);
Packit Service 82fcde
                        }
Packit Service 82fcde
                      free (result.array);
Packit Service 82fcde
                    }
Packit Service 82fcde
                }
Packit Service 82fcde
              else /* !do_finalize */
Packit Service 82fcde
                {
Packit Service 82fcde
                  dynarray_str_free (&dyn);
Packit Service 82fcde
                  CHECK_INIT_STATE (str, &dyn);
Packit Service 82fcde
                }
Packit Service 82fcde
            }
Packit Service 82fcde
Packit Service 82fcde
  /* Test resizing.  */
Packit Service 82fcde
  {
Packit Service 82fcde
    enum { count = 2131 };
Packit Service 82fcde
    struct dynarray_str dyn;
Packit Service 82fcde
    dynarray_str_init (&dyn);
Packit Service 82fcde
Packit Service 82fcde
    /* From length 0 to length 1.  */
Packit Service 82fcde
    TEST_VERIFY (dynarray_str_resize (&dyn, 1));
Packit Service 82fcde
    TEST_VERIFY (dynarray_str_size (&dyn) == 1);
Packit Service 82fcde
    TEST_VERIFY (*dynarray_str_at (&dyn, 0) == NULL);
Packit Service 82fcde
    *dynarray_str_at (&dyn, 0) = xstrdup ("allocated");
Packit Service 82fcde
    dynarray_str_free (&dyn);
Packit Service 82fcde
Packit Service 82fcde
    /* From length 0 to length 1 and 2.  */
Packit Service 82fcde
    TEST_VERIFY (dynarray_str_resize (&dyn, 1));
Packit Service 82fcde
    TEST_VERIFY (dynarray_str_size (&dyn) == 1);
Packit Service 82fcde
    TEST_VERIFY (*dynarray_str_at (&dyn, 0) == NULL);
Packit Service 82fcde
    *dynarray_str_at (&dyn, 0) = xstrdup ("allocated0");
Packit Service 82fcde
    TEST_VERIFY (dynarray_str_resize (&dyn, 2));
Packit Service 82fcde
    TEST_VERIFY (dynarray_str_size (&dyn) == 2);
Packit Service 82fcde
    TEST_VERIFY (strcmp (*dynarray_str_at (&dyn, 0), "allocated0") == 0);
Packit Service 82fcde
    TEST_VERIFY (*dynarray_str_at (&dyn, 1) == NULL);
Packit Service 82fcde
    *dynarray_str_at (&dyn, 1) = xstrdup ("allocated1");
Packit Service 82fcde
    TEST_VERIFY (dynarray_str_resize (&dyn, count));
Packit Service 82fcde
    TEST_VERIFY (dynarray_str_size (&dyn) == count);
Packit Service 82fcde
    TEST_VERIFY (strcmp (*dynarray_str_at (&dyn, 0), "allocated0") == 0);
Packit Service 82fcde
    TEST_VERIFY (strcmp (*dynarray_str_at (&dyn, 1), "allocated1") == 0);
Packit Service 82fcde
    for (int i = 2; i < count; ++i)
Packit Service 82fcde
      TEST_VERIFY (*dynarray_str_at (&dyn, i) == NULL);
Packit Service 82fcde
    *dynarray_str_at (&dyn, count - 1) = xstrdup ("allocated2");
Packit Service 82fcde
    TEST_VERIFY (dynarray_str_resize (&dyn, 3));
Packit Service 82fcde
    TEST_VERIFY (strcmp (*dynarray_str_at (&dyn, 0), "allocated0") == 0);
Packit Service 82fcde
    TEST_VERIFY (strcmp (*dynarray_str_at (&dyn, 1), "allocated1") == 0);
Packit Service 82fcde
    TEST_VERIFY (*dynarray_str_at (&dyn, 2) == NULL);
Packit Service 82fcde
    dynarray_str_free (&dyn);
Packit Service 82fcde
  }
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
/* Verify that DYNARRAY_ELEMENT_INIT has an effect.  */
Packit Service 82fcde
static void
Packit Service 82fcde
test_long_init (void)
Packit Service 82fcde
{
Packit Service 82fcde
  enum { count = 2131 };
Packit Service 82fcde
  {
Packit Service 82fcde
    struct dynarray_long dyn;
Packit Service 82fcde
    dynarray_long_init (&dyn);
Packit Service 82fcde
    for (int i = 0; i < count; ++i)
Packit Service 82fcde
      {
Packit Service 82fcde
        long *place = dynarray_long_emplace (&dyn);
Packit Service 82fcde
        TEST_VERIFY_EXIT (place != NULL);
Packit Service 82fcde
        TEST_VERIFY (*place == 17);
Packit Service 82fcde
      }
Packit Service 82fcde
    TEST_VERIFY (dynarray_long_size (&dyn) == count);
Packit Service 82fcde
    for (int i = 0; i < count; ++i)
Packit Service 82fcde
      TEST_VERIFY (*dynarray_long_at (&dyn, i) == 17);
Packit Service 82fcde
    dynarray_long_free (&dyn);
Packit Service 82fcde
Packit Service 82fcde
    TEST_VERIFY (dynarray_long_resize (&dyn, 1));
Packit Service 82fcde
    TEST_VERIFY (dynarray_long_size (&dyn) == 1);
Packit Service 82fcde
    TEST_VERIFY (*dynarray_long_at (&dyn, 0) == 17);
Packit Service 82fcde
    *dynarray_long_at (&dyn, 0) = 18;
Packit Service 82fcde
    dynarray_long_free (&dyn);
Packit Service 82fcde
    TEST_VERIFY (dynarray_long_resize (&dyn, 1));
Packit Service 82fcde
    TEST_VERIFY (dynarray_long_size (&dyn) == 1);
Packit Service 82fcde
    TEST_VERIFY (*dynarray_long_at (&dyn, 0) == 17);
Packit Service 82fcde
    TEST_VERIFY (dynarray_long_resize (&dyn, 2));
Packit Service 82fcde
    TEST_VERIFY (dynarray_long_size (&dyn) == 2);
Packit Service 82fcde
    TEST_VERIFY (*dynarray_long_at (&dyn, 0) == 17);
Packit Service 82fcde
    TEST_VERIFY (*dynarray_long_at (&dyn, 1) == 17);
Packit Service 82fcde
    *dynarray_long_at (&dyn, 0) = 18;
Packit Service 82fcde
    TEST_VERIFY (dynarray_long_resize (&dyn, count));
Packit Service 82fcde
    TEST_VERIFY (dynarray_long_size (&dyn) == count);
Packit Service 82fcde
    TEST_VERIFY (*dynarray_long_at (&dyn, 0) == 18);
Packit Service 82fcde
    for (int i = 1; i < count; ++i)
Packit Service 82fcde
      TEST_VERIFY (*dynarray_long_at (&dyn, i) == 17);
Packit Service 82fcde
    dynarray_long_free (&dyn);
Packit Service 82fcde
  }
Packit Service 82fcde
Packit Service 82fcde
  /* Similar, but without an on-stack scratch region
Packit Service 82fcde
     (DYNARRAY_INITIAL_SIZE is 0).  */
Packit Service 82fcde
  {
Packit Service 82fcde
    struct dynarray_long_noscratch dyn;
Packit Service 82fcde
    dynarray_long_noscratch_init (&dyn);
Packit Service 82fcde
    struct long_array result;
Packit Service 82fcde
    TEST_VERIFY_EXIT (dynarray_long_noscratch_finalize (&dyn, &result));
Packit Service 82fcde
    TEST_VERIFY (result.array == NULL);
Packit Service 82fcde
    TEST_VERIFY (result.length == 0);
Packit Service 82fcde
Packit Service 82fcde
    /* Test with one element.  */
Packit Service 82fcde
    {
Packit Service 82fcde
      long *place = dynarray_long_noscratch_emplace (&dyn);
Packit Service 82fcde
      TEST_VERIFY_EXIT (place != NULL);
Packit Service 82fcde
      TEST_VERIFY (*place == 23);
Packit Service 82fcde
    }
Packit Service 82fcde
    TEST_VERIFY (dynarray_long_noscratch_size (&dyn) == 1);
Packit Service 82fcde
    TEST_VERIFY (*dynarray_long_noscratch_at (&dyn, 0) == 23);
Packit Service 82fcde
    TEST_VERIFY_EXIT (dynarray_long_noscratch_finalize (&dyn, &result));
Packit Service 82fcde
    TEST_VERIFY_EXIT (result.array != NULL);
Packit Service 82fcde
    TEST_VERIFY (result.length == 1);
Packit Service 82fcde
    TEST_VERIFY (result.array[0] == 23);
Packit Service 82fcde
    free (result.array);
Packit Service 82fcde
Packit Service 82fcde
    for (int i = 0; i < count; ++i)
Packit Service 82fcde
      {
Packit Service 82fcde
        long *place = dynarray_long_noscratch_emplace (&dyn);
Packit Service 82fcde
        TEST_VERIFY_EXIT (place != NULL);
Packit Service 82fcde
        TEST_VERIFY (*place == 23);
Packit Service 82fcde
        if (i == 0)
Packit Service 82fcde
          *place = 29;
Packit Service 82fcde
      }
Packit Service 82fcde
    TEST_VERIFY (dynarray_long_noscratch_size (&dyn) == count);
Packit Service 82fcde
    TEST_VERIFY (*dynarray_long_noscratch_at (&dyn, 0) == 29);
Packit Service 82fcde
    for (int i = 1; i < count; ++i)
Packit Service 82fcde
      TEST_VERIFY (*dynarray_long_noscratch_at (&dyn, i) == 23);
Packit Service 82fcde
    TEST_VERIFY_EXIT (dynarray_long_noscratch_finalize (&dyn, &result));
Packit Service 82fcde
    TEST_VERIFY_EXIT (result.array != NULL);
Packit Service 82fcde
    TEST_VERIFY (result.length == count);
Packit Service 82fcde
    TEST_VERIFY (result.array[0] == 29);
Packit Service 82fcde
    for (int i = 1; i < count; ++i)
Packit Service 82fcde
      TEST_VERIFY (result.array[i] == 23);
Packit Service 82fcde
    free (result.array);
Packit Service 82fcde
Packit Service 82fcde
    TEST_VERIFY (dynarray_long_noscratch_resize (&dyn, 1));
Packit Service 82fcde
    TEST_VERIFY (dynarray_long_noscratch_size (&dyn) == 1);
Packit Service 82fcde
    TEST_VERIFY (*dynarray_long_noscratch_at (&dyn, 0) == 23);
Packit Service 82fcde
    *dynarray_long_noscratch_at (&dyn, 0) = 24;
Packit Service 82fcde
    dynarray_long_noscratch_free (&dyn);
Packit Service 82fcde
    TEST_VERIFY (dynarray_long_noscratch_resize (&dyn, 1));
Packit Service 82fcde
    TEST_VERIFY (dynarray_long_noscratch_size (&dyn) == 1);
Packit Service 82fcde
    TEST_VERIFY (*dynarray_long_noscratch_at (&dyn, 0) == 23);
Packit Service 82fcde
    TEST_VERIFY (dynarray_long_noscratch_resize (&dyn, 2));
Packit Service 82fcde
    TEST_VERIFY (dynarray_long_noscratch_size (&dyn) == 2);
Packit Service 82fcde
    TEST_VERIFY (*dynarray_long_noscratch_at (&dyn, 0) == 23);
Packit Service 82fcde
    TEST_VERIFY (*dynarray_long_noscratch_at (&dyn, 1) == 23);
Packit Service 82fcde
    *dynarray_long_noscratch_at (&dyn, 0) = 24;
Packit Service 82fcde
    TEST_VERIFY (dynarray_long_noscratch_resize (&dyn, count));
Packit Service 82fcde
    TEST_VERIFY (dynarray_long_noscratch_size (&dyn) == count);
Packit Service 82fcde
    TEST_VERIFY (*dynarray_long_noscratch_at (&dyn, 0) == 24);
Packit Service 82fcde
    for (int i = 1; i < count; ++i)
Packit Service 82fcde
      TEST_VERIFY (*dynarray_long_noscratch_at (&dyn, i) == 23);
Packit Service 82fcde
    dynarray_long_noscratch_free (&dyn);
Packit Service 82fcde
  }
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
/* Test overflow in resize.  */
Packit Service 82fcde
static void
Packit Service 82fcde
test_long_overflow (void)
Packit Service 82fcde
{
Packit Service 82fcde
  {
Packit Service 82fcde
    struct dynarray_long dyn;
Packit Service 82fcde
    dynarray_long_init (&dyn);
Packit Service 82fcde
    errno = EINVAL;
Packit Service 82fcde
    TEST_VERIFY (!dynarray_long_resize
Packit Service 82fcde
                 (&dyn, (SIZE_MAX / sizeof (long)) + 1));
Packit Service 82fcde
    TEST_VERIFY (errno == ENOMEM);
Packit Service 82fcde
    TEST_VERIFY (dynarray_long_has_failed (&dyn));
Packit Service 82fcde
  }
Packit Service 82fcde
Packit Service 82fcde
  {
Packit Service 82fcde
    struct dynarray_long_noscratch dyn;
Packit Service 82fcde
    dynarray_long_noscratch_init (&dyn);
Packit Service 82fcde
    errno = EINVAL;
Packit Service 82fcde
    TEST_VERIFY (!dynarray_long_noscratch_resize
Packit Service 82fcde
                 (&dyn, (SIZE_MAX / sizeof (long)) + 1));
Packit Service 82fcde
    TEST_VERIFY (errno == ENOMEM);
Packit Service 82fcde
    TEST_VERIFY (dynarray_long_noscratch_has_failed (&dyn));
Packit Service 82fcde
  }
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
/* Test NUL-terminated string construction with the add function and
Packit Service 82fcde
   the simple finalize function.  */
Packit Service 82fcde
static void
Packit Service 82fcde
test_zstr (void)
Packit Service 82fcde
{
Packit Service 82fcde
  /* Totally empty string (no NUL termination).  */
Packit Service 82fcde
  {
Packit Service 82fcde
    struct zstr s;
Packit Service 82fcde
    zstr_init (&s);
Packit Service 82fcde
    char *result = zstr_finalize (&s, NULL);
Packit Service 82fcde
    TEST_VERIFY (result == NULL);
Packit Service 82fcde
    TEST_VERIFY (zstr_size (&s) == 0);
Packit Service 82fcde
    size_t length = 1;
Packit Service 82fcde
    result = zstr_finalize (&s, &length);
Packit Service 82fcde
    TEST_VERIFY (result == NULL);
Packit Service 82fcde
    TEST_VERIFY (length == 0);
Packit Service 82fcde
    TEST_VERIFY (zstr_size (&s) == 0);
Packit Service 82fcde
  }
Packit Service 82fcde
Packit Service 82fcde
  /* Empty string.  */
Packit Service 82fcde
  {
Packit Service 82fcde
    struct zstr s;
Packit Service 82fcde
    zstr_init (&s);
Packit Service 82fcde
    zstr_add (&s, '\0');
Packit Service 82fcde
    char *result = zstr_finalize (&s, NULL);
Packit Service 82fcde
    TEST_VERIFY_EXIT (result != NULL);
Packit Service 82fcde
    TEST_VERIFY (*result == '\0');
Packit Service 82fcde
    TEST_VERIFY (zstr_size (&s) == 0);
Packit Service 82fcde
    free (result);
Packit Service 82fcde
Packit Service 82fcde
    zstr_add (&s, '\0');
Packit Service 82fcde
    size_t length = 1;
Packit Service 82fcde
    result = zstr_finalize (&s, &length);
Packit Service 82fcde
    TEST_VERIFY_EXIT (result != NULL);
Packit Service 82fcde
    TEST_VERIFY (*result == '\0');
Packit Service 82fcde
    TEST_VERIFY (length == 1);
Packit Service 82fcde
    TEST_VERIFY (zstr_size (&s) == 0);
Packit Service 82fcde
    free (result);
Packit Service 82fcde
  }
Packit Service 82fcde
Packit Service 82fcde
  /* A few characters.  */
Packit Service 82fcde
  {
Packit Service 82fcde
    struct zstr s;
Packit Service 82fcde
    zstr_init (&s);
Packit Service 82fcde
    zstr_add (&s, 'A');
Packit Service 82fcde
    zstr_add (&s, 'b');
Packit Service 82fcde
    zstr_add (&s, 'c');
Packit Service 82fcde
    zstr_add (&s, '\0');
Packit Service 82fcde
    char *result = zstr_finalize (&s, NULL);
Packit Service 82fcde
    TEST_VERIFY_EXIT (result != NULL);
Packit Service 82fcde
    TEST_VERIFY (strcmp (result, "Abc") == 0);
Packit Service 82fcde
    TEST_VERIFY (zstr_size (&s) == 0);
Packit Service 82fcde
    free (result);
Packit Service 82fcde
Packit Service 82fcde
    zstr_add (&s, 'X');
Packit Service 82fcde
    zstr_add (&s, 'y');
Packit Service 82fcde
    zstr_add (&s, 'z');
Packit Service 82fcde
    zstr_add (&s, '\0');
Packit Service 82fcde
    size_t length = 1;
Packit Service 82fcde
    result = zstr_finalize (&s, &length);
Packit Service 82fcde
    TEST_VERIFY_EXIT (result != NULL);
Packit Service 82fcde
    TEST_VERIFY (strcmp (result, "Xyz") == 0);
Packit Service 82fcde
    TEST_VERIFY (length == 4);
Packit Service 82fcde
    TEST_VERIFY (zstr_size (&s) == 0);
Packit Service 82fcde
    free (result);
Packit Service 82fcde
  }
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
static int
Packit Service 82fcde
do_test (void)
Packit Service 82fcde
{
Packit Service 82fcde
  mtrace ();
Packit Service 82fcde
  test_int ();
Packit Service 82fcde
  test_str ();
Packit Service 82fcde
  test_long_init ();
Packit Service 82fcde
  test_long_overflow ();
Packit Service 82fcde
  test_zstr ();
Packit Service 82fcde
  return 0;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
#include <support/test-driver.c>