/* Memory allocation used during tests.

Copyright 2001-2003, 2006-2016 Free Software Foundation, Inc.
Contributed by the AriC and Caramba projects, INRIA.

This file is part of the GNU MPFR Library.

The GNU MPFR Library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 3 of the License, or (at your
option) any later version.

The GNU MPFR Library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
License for more details.

You should have received a copy of the GNU Lesser General Public License
along with the GNU MPFR Library; see the file COPYING.LESSER.  If not, see
http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */

/* Note: this file comes from GMP's tests/memory.c */

#include <stdio.h>
#include <stdlib.h>  /* for abort */
#include <limits.h>

#include "mpfr-test.h"

/* Each block allocated is a separate malloc, for the benefit of a redzoning
   malloc debugger during development or when bug hunting.

   Sizes passed when reallocating or freeing are checked (the default
   routines don't care about these).

   Memory leaks are checked by requiring that all blocks have been freed
   when tests_memory_end() is called.  Test programs must be sure to have
   "clear"s for all temporary variables used.  */

struct header {
  void           *ptr;
  size_t         size;
  struct header  *next;
};

static struct header  *tests_memory_list;

/* Return a pointer to a pointer to the found block (so it can be updated
   when unlinking). */
static struct header **
tests_memory_find (void *ptr)
{
  struct header  **hp;

  for (hp = &tests_memory_list; *hp != NULL; hp = &((*hp)->next))
    if ((*hp)->ptr == ptr)
      return hp;

  return NULL;
}

/*
static int
tests_memory_valid (void *ptr)
{
  return (tests_memory_find (ptr) != NULL);
}
*/

void *
tests_allocate (size_t size)
{
  struct header  *h;

  if (size == 0)
    {
      printf ("tests_allocate(): attempt to allocate 0 bytes\n");
      abort ();
    }

  h = (struct header *) __gmp_default_allocate (sizeof (*h));
  h->next = tests_memory_list;
  tests_memory_list = h;

  h->size = size;
  h->ptr = __gmp_default_allocate (size);
  return h->ptr;
}

void *
tests_reallocate (void *ptr, size_t old_size, size_t new_size)
{
  struct header  **hp, *h;

  if (new_size == 0)
    {
      printf ("tests_reallocate(): attempt to reallocate 0x%lX to 0 bytes\n",
              (unsigned long) ptr);
      abort ();
    }

  hp = tests_memory_find (ptr);
  if (hp == NULL)
    {
      printf ("tests_reallocate(): attempt to reallocate bad pointer 0x%lX\n",
              (unsigned long) ptr);
      abort ();
    }
  h = *hp;

  if (h->size != old_size)
    {
      /* Note: we should use the standard %zu to print sizes, but
         this is not supported by old C implementations. */
      printf ("tests_reallocate(): bad old size %lu, should be %lu\n",
              (unsigned long) old_size, (unsigned long) h->size);
      abort ();
    }

  h->size = new_size;
  h->ptr = __gmp_default_reallocate (ptr, old_size, new_size);
  return h->ptr;
}

static struct header **
tests_free_find (void *ptr)
{
  struct header  **hp = tests_memory_find (ptr);
  if (hp == NULL)
    {
      printf ("tests_free(): attempt to free bad pointer 0x%lX\n",
              (unsigned long) ptr);
      abort ();
    }
  return hp;
}

static void
tests_free_nosize (void *ptr)
{
  struct header  **hp = tests_free_find (ptr);
  struct header  *h = *hp;

  *hp = h->next;  /* unlink */

  __gmp_default_free (ptr, h->size);
  __gmp_default_free (h, sizeof (*h));
}

void
tests_free (void *ptr, size_t size)
{
  struct header  **hp = tests_free_find (ptr);
  struct header  *h = *hp;

  if (h->size != size)
    {
      /* Note: we should use the standard %zu to print sizes, but
         this is not supported by old C implementations. */
      printf ("tests_free(): bad size %lu, should be %lu\n",
              (unsigned long) size, (unsigned long) h->size);
      abort ();
    }

  tests_free_nosize (ptr);
}

void
tests_memory_start (void)
{
  tests_memory_list = NULL;
  mp_set_memory_functions (tests_allocate, tests_reallocate, tests_free);
}

void
tests_memory_end (void)
{
  if (tests_memory_list != NULL)
    {
      struct header  *h;
      unsigned  count;

      printf ("tests_memory_end(): not all memory freed\n");

      count = 0;
      for (h = tests_memory_list; h != NULL; h = h->next)
        count++;

      printf ("    %u blocks remaining\n", count);
      abort ();
    }
}
