1*66e63ce3Schristos /* This file is part of the program psim. 2*66e63ce3Schristos 3*66e63ce3Schristos Copyright (C) 1994-1995,1997, Andrew Cagney <cagney@highland.com.au> 4*66e63ce3Schristos 5*66e63ce3Schristos This program is free software; you can redistribute it and/or modify 6*66e63ce3Schristos it under the terms of the GNU General Public License as published by 7*66e63ce3Schristos the Free Software Foundation; either version 2 of the License, or 8*66e63ce3Schristos (at your option) any later version. 9*66e63ce3Schristos 10*66e63ce3Schristos This program is distributed in the hope that it will be useful, 11*66e63ce3Schristos but WITHOUT ANY WARRANTY; without even the implied warranty of 12*66e63ce3Schristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13*66e63ce3Schristos GNU General Public License for more details. 14*66e63ce3Schristos 15*66e63ce3Schristos You should have received a copy of the GNU General Public License 16*66e63ce3Schristos along with this program; if not, write to the Free Software 17*66e63ce3Schristos Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 18*66e63ce3Schristos 19*66e63ce3Schristos */ 20*66e63ce3Schristos 21*66e63ce3Schristos 22*66e63ce3Schristos #ifndef _CAP_C_ 23*66e63ce3Schristos #define _CAP_C_ 24*66e63ce3Schristos 25*66e63ce3Schristos #include "cap.h" 26*66e63ce3Schristos 27*66e63ce3Schristos typedef struct _cap_mapping cap_mapping; 28*66e63ce3Schristos struct _cap_mapping { 29*66e63ce3Schristos unsigned_cell external; 30*66e63ce3Schristos void *internal; 31*66e63ce3Schristos cap_mapping *next; 32*66e63ce3Schristos }; 33*66e63ce3Schristos 34*66e63ce3Schristos struct _cap { 35*66e63ce3Schristos int nr_mappings; 36*66e63ce3Schristos cap_mapping *mappings; 37*66e63ce3Schristos }; 38*66e63ce3Schristos 39*66e63ce3Schristos INLINE_CAP\ 40*66e63ce3Schristos (cap *) 41*66e63ce3Schristos cap_create(const char *key) 42*66e63ce3Schristos { 43*66e63ce3Schristos return ZALLOC(cap); 44*66e63ce3Schristos } 45*66e63ce3Schristos 46*66e63ce3Schristos INLINE_CAP\ 47*66e63ce3Schristos (void) 48*66e63ce3Schristos cap_init(cap *db) 49*66e63ce3Schristos { 50*66e63ce3Schristos cap_mapping *current_map = db->mappings; 51*66e63ce3Schristos if (current_map != NULL) { 52*66e63ce3Schristos db->nr_mappings = db->mappings->external; 53*66e63ce3Schristos /* verify that the mappings that were not removed are in sequence 54*66e63ce3Schristos down to nr 1 */ 55*66e63ce3Schristos while (current_map->next != NULL) { 56*66e63ce3Schristos if (current_map->external != current_map->next->external + 1) 57*66e63ce3Schristos error("cap: cap database possibly corrupt"); 58*66e63ce3Schristos current_map = current_map->next; 59*66e63ce3Schristos } 60*66e63ce3Schristos ASSERT(current_map->next == NULL); 61*66e63ce3Schristos if (current_map->external != 1) 62*66e63ce3Schristos error("cap: cap database possibly currupt"); 63*66e63ce3Schristos } 64*66e63ce3Schristos else { 65*66e63ce3Schristos db->nr_mappings = 0; 66*66e63ce3Schristos } 67*66e63ce3Schristos } 68*66e63ce3Schristos 69*66e63ce3Schristos INLINE_CAP\ 70*66e63ce3Schristos (void *) 71*66e63ce3Schristos cap_internal(cap *db, 72*66e63ce3Schristos signed_cell external) 73*66e63ce3Schristos { 74*66e63ce3Schristos cap_mapping *current_map = db->mappings; 75*66e63ce3Schristos while (current_map != NULL) { 76*66e63ce3Schristos if (current_map->external == external) 77*66e63ce3Schristos return current_map->internal; 78*66e63ce3Schristos current_map = current_map->next; 79*66e63ce3Schristos } 80*66e63ce3Schristos return (void*)0; 81*66e63ce3Schristos } 82*66e63ce3Schristos 83*66e63ce3Schristos INLINE_CAP\ 84*66e63ce3Schristos (signed_cell) 85*66e63ce3Schristos cap_external(cap *db, 86*66e63ce3Schristos void *internal) 87*66e63ce3Schristos { 88*66e63ce3Schristos cap_mapping *current_map = db->mappings; 89*66e63ce3Schristos while (current_map != NULL) { 90*66e63ce3Schristos if (current_map->internal == internal) 91*66e63ce3Schristos return current_map->external; 92*66e63ce3Schristos current_map = current_map->next; 93*66e63ce3Schristos } 94*66e63ce3Schristos return 0; 95*66e63ce3Schristos } 96*66e63ce3Schristos 97*66e63ce3Schristos INLINE_CAP\ 98*66e63ce3Schristos (void) 99*66e63ce3Schristos cap_add(cap *db, 100*66e63ce3Schristos void *internal) 101*66e63ce3Schristos { 102*66e63ce3Schristos if (cap_external(db, internal) != 0) { 103*66e63ce3Schristos error("cap: attempting to add an object already in the data base"); 104*66e63ce3Schristos } 105*66e63ce3Schristos else { 106*66e63ce3Schristos /* insert at the front making things in decending order */ 107*66e63ce3Schristos cap_mapping *new_map = ZALLOC(cap_mapping); 108*66e63ce3Schristos new_map->next = db->mappings; 109*66e63ce3Schristos new_map->internal = internal; 110*66e63ce3Schristos db->nr_mappings += 1; 111*66e63ce3Schristos new_map->external = db->nr_mappings; 112*66e63ce3Schristos db->mappings = new_map; 113*66e63ce3Schristos } 114*66e63ce3Schristos } 115*66e63ce3Schristos 116*66e63ce3Schristos INLINE_CAP\ 117*66e63ce3Schristos (void) 118*66e63ce3Schristos cap_remove(cap *db, 119*66e63ce3Schristos void *internal) 120*66e63ce3Schristos { 121*66e63ce3Schristos cap_mapping **current_map = &db->mappings; 122*66e63ce3Schristos while (*current_map != NULL) { 123*66e63ce3Schristos if ((*current_map)->internal == internal) { 124*66e63ce3Schristos cap_mapping *delete = *current_map; 125*66e63ce3Schristos *current_map = delete->next; 126*66e63ce3Schristos free(delete); 127*66e63ce3Schristos return; 128*66e63ce3Schristos } 129*66e63ce3Schristos current_map = &(*current_map)->next; 130*66e63ce3Schristos } 131*66e63ce3Schristos error("cap: attempt to remove nonexistant internal object"); 132*66e63ce3Schristos } 133*66e63ce3Schristos 134*66e63ce3Schristos #endif 135