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 3 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, see <http://www.gnu.org/licenses/>. 17 18 */ 19 20 21 #ifndef _CAP_C_ 22 #define _CAP_C_ 23 24 #include "cap.h" 25 26 typedef struct _cap_mapping cap_mapping; 27 struct _cap_mapping { 28 unsigned_cell external; 29 void *internal; 30 cap_mapping *next; 31 }; 32 33 struct _cap { 34 int nr_mappings; 35 cap_mapping *mappings; 36 }; 37 38 INLINE_CAP\ 39 (cap *) 40 cap_create(const char *key) 41 { 42 return ZALLOC(cap); 43 } 44 45 INLINE_CAP\ 46 (void) 47 cap_init(cap *db) 48 { 49 cap_mapping *current_map = db->mappings; 50 if (current_map != NULL) { 51 db->nr_mappings = db->mappings->external; 52 /* verify that the mappings that were not removed are in sequence 53 down to nr 1 */ 54 while (current_map->next != NULL) { 55 if (current_map->external != current_map->next->external + 1) 56 error("cap: cap database possibly corrupt"); 57 current_map = current_map->next; 58 } 59 ASSERT(current_map->next == NULL); 60 if (current_map->external != 1) 61 error("cap: cap database possibly currupt"); 62 } 63 else { 64 db->nr_mappings = 0; 65 } 66 } 67 68 INLINE_CAP\ 69 (void *) 70 cap_internal(cap *db, 71 signed_cell external) 72 { 73 cap_mapping *current_map = db->mappings; 74 while (current_map != NULL) { 75 if (current_map->external == external) 76 return current_map->internal; 77 current_map = current_map->next; 78 } 79 return (void*)0; 80 } 81 82 INLINE_CAP\ 83 (signed_cell) 84 cap_external(cap *db, 85 void *internal) 86 { 87 cap_mapping *current_map = db->mappings; 88 while (current_map != NULL) { 89 if (current_map->internal == internal) 90 return current_map->external; 91 current_map = current_map->next; 92 } 93 return 0; 94 } 95 96 INLINE_CAP\ 97 (void) 98 cap_add(cap *db, 99 void *internal) 100 { 101 if (cap_external(db, internal) != 0) { 102 error("cap: attempting to add an object already in the data base"); 103 } 104 else { 105 /* insert at the front making things in decending order */ 106 cap_mapping *new_map = ZALLOC(cap_mapping); 107 new_map->next = db->mappings; 108 new_map->internal = internal; 109 db->nr_mappings += 1; 110 new_map->external = db->nr_mappings; 111 db->mappings = new_map; 112 } 113 } 114 115 INLINE_CAP\ 116 (void) 117 cap_remove(cap *db, 118 void *internal) 119 { 120 cap_mapping **current_map = &db->mappings; 121 while (*current_map != NULL) { 122 if ((*current_map)->internal == internal) { 123 cap_mapping *delete = *current_map; 124 *current_map = delete->next; 125 free(delete); 126 return; 127 } 128 current_map = &(*current_map)->next; 129 } 130 error("cap: attempt to remove nonexistant internal object"); 131 } 132 133 #endif 134