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