/*  This file is part of the program psim.

    Copyright (C) 1994-1995,1997, Andrew Cagney <cagney@highland.com.au>

    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/>.
 
    */


#ifndef _CAP_C_
#define _CAP_C_

#include "cap.h"

typedef struct _cap_mapping cap_mapping;
struct _cap_mapping {
  unsigned_cell external;
  void *internal;
  cap_mapping *next;
};

struct _cap {
  int nr_mappings;
  cap_mapping *mappings;
};

INLINE_CAP\
(cap *)
cap_create(const char *key)
{
  return ZALLOC(cap);
}

INLINE_CAP\
(void)
cap_init(cap *db)
{
  cap_mapping *current_map = db->mappings;
  if (current_map != NULL) {
    db->nr_mappings = db->mappings->external;
    /* verify that the mappings that were not removed are in sequence
       down to nr 1 */
    while (current_map->next != NULL) {
      if (current_map->external != current_map->next->external + 1)
	error("cap: cap database possibly corrupt");
      current_map = current_map->next;
    }
    ASSERT(current_map->next == NULL);
    if (current_map->external != 1)
      error("cap: cap database possibly currupt");
  }
  else {
    db->nr_mappings = 0;
  }
}

INLINE_CAP\
(void *)
cap_internal(cap *db,
	     signed_cell external)
{
  cap_mapping *current_map = db->mappings;
  while (current_map != NULL) {
    if (current_map->external == external)
      return current_map->internal;
    current_map = current_map->next;
  }
  return (void*)0;
}

INLINE_CAP\
(signed_cell)
cap_external(cap *db,
	     void *internal)
{
  cap_mapping *current_map = db->mappings;
  while (current_map != NULL) {
    if (current_map->internal == internal)
      return current_map->external;
    current_map = current_map->next;
  }
  return 0;
}

INLINE_CAP\
(void)
cap_add(cap *db,
	void *internal)
{
  if (cap_external(db, internal) != 0) {
    error("cap: attempting to add an object already in the data base");
  }
  else {
    /* insert at the front making things in decending order */
    cap_mapping *new_map = ZALLOC(cap_mapping);
    new_map->next = db->mappings;
    new_map->internal = internal;
    db->nr_mappings += 1;
    new_map->external = db->nr_mappings;
    db->mappings = new_map;
  }
}

INLINE_CAP\
(void)
cap_remove(cap *db,
	   void *internal)
{
  cap_mapping **current_map = &db->mappings;
  while (*current_map != NULL) {
    if ((*current_map)->internal == internal) {
      cap_mapping *delete = *current_map;
      *current_map = delete->next;
      free(delete);
      return;
    }
    current_map = &(*current_map)->next;
  }
  error("cap: attempt to remove nonexistant internal object");
}

#endif
