/* Support functions for general registry objects.

   Copyright (C) 2011-2013 Free Software Foundation, Inc.

   This file is part of GDB.

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

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#include "defs.h"
#include "registry.h"
#include "gdb_assert.h"
#include "gdb_string.h"

const struct registry_data *
register_data_with_cleanup (struct registry_data_registry *registry,
			    registry_data_callback save,
			    registry_data_callback free)
{
  struct registry_data_registration **curr;

  /* Append new registration.  */
  for (curr = &registry->registrations;
       *curr != NULL;
       curr = &(*curr)->next)
    ;

  *curr = XMALLOC (struct registry_data_registration);
  (*curr)->next = NULL;
  (*curr)->data = XMALLOC (struct registry_data);
  (*curr)->data->index = registry->num_registrations++;
  (*curr)->data->save = save;
  (*curr)->data->free = free;

  return (*curr)->data;
}

void
registry_alloc_data (struct registry_data_registry *registry,
		       struct registry_fields *fields)
{
  gdb_assert (fields->data == NULL);
  fields->num_data = registry->num_registrations;
  fields->data = XCALLOC (fields->num_data, void *);
}

void
registry_clear_data (struct registry_data_registry *data_registry,
		     registry_callback_adaptor adaptor,
		     struct registry_container *container,
		     struct registry_fields *fields)
{
  struct registry_data_registration *registration;
  int i;

  gdb_assert (fields->data != NULL);

  /* Process all the save handlers.  */

  for (registration = data_registry->registrations, i = 0;
       i < fields->num_data;
       registration = registration->next, i++)
    if (fields->data[i] != NULL && registration->data->save != NULL)
      adaptor (registration->data->save, container, fields->data[i]);

  /* Now process all the free handlers.  */

  for (registration = data_registry->registrations, i = 0;
       i < fields->num_data;
       registration = registration->next, i++)
    if (fields->data[i] != NULL && registration->data->free != NULL)
      adaptor (registration->data->free, container, fields->data[i]);

  memset (fields->data, 0, fields->num_data * sizeof (void *));
}

void
registry_container_free_data (struct registry_data_registry *data_registry,
			      registry_callback_adaptor adaptor,
			      struct registry_container *container,
			      struct registry_fields *fields)
{
  void ***rdata = &fields->data;
  gdb_assert (*rdata != NULL);
  registry_clear_data (data_registry, adaptor, container, fields);
  xfree (*rdata);
  *rdata = NULL;
}

void
registry_set_data (struct registry_fields *fields,
		   const struct registry_data *data,
		   void *value)
{
  gdb_assert (data->index < fields->num_data);
  fields->data[data->index] = value;
}

void *
registry_data (struct registry_fields *fields,
	       const struct registry_data *data)
{
  gdb_assert (data->index < fields->num_data);
  return fields->data[data->index];
}
