1 /* This file is part of the program psim. 2 3 Copyright (C) 1994-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 #include <stdio.h> 22 #include <stdarg.h> 23 #include <ctype.h> 24 25 #include "build-config.h" 26 #include "misc.h" 27 28 #ifdef HAVE_STDLIB_H 29 #include <stdlib.h> 30 #endif 31 32 #ifdef HAVE_STRING_H 33 #include <string.h> 34 #else 35 #ifdef HAVE_STRINGS_H 36 #include <strings.h> 37 #endif 38 #endif 39 40 void 41 error (char *msg, ...) 42 { 43 va_list ap; 44 va_start(ap, msg); 45 vprintf(msg, ap); 46 va_end(ap); 47 exit (1); 48 } 49 50 void * 51 zalloc(long size) 52 { 53 void *memory = malloc(size); 54 if (memory == NULL) 55 error("zalloc failed\n"); 56 memset(memory, 0, size); 57 return memory; 58 } 59 60 void 61 dumpf (int indent, char *msg, ...) 62 { 63 va_list ap; 64 for (; indent > 0; indent--) 65 printf(" "); 66 va_start(ap, msg); 67 vprintf(msg, ap); 68 va_end(ap); 69 } 70 71 72 unsigned 73 a2i(const char *a) 74 { 75 int neg = 0; 76 int base = 10; 77 unsigned num = 0; 78 int looping; 79 80 while (isspace (*a)) 81 a++; 82 83 if (*a == '-') { 84 neg = 1; 85 a++; 86 } 87 88 if (*a == '0') { 89 if (a[1] == 'x' || a[1] == 'X') { 90 a += 2; 91 base = 16; 92 } 93 else 94 base = 8; 95 } 96 97 looping = 1; 98 while (looping) { 99 int ch = *a++; 100 101 switch (base) { 102 default: 103 looping = 0; 104 break; 105 106 case 10: 107 if (ch >= '0' && ch <= '9') { 108 num = (num * 10) + (ch - '0'); 109 } else { 110 looping = 0; 111 } 112 break; 113 114 case 8: 115 if (ch >= '0' && ch <= '7') { 116 num = (num * 8) + (ch - '0'); 117 } else { 118 looping = 0; 119 } 120 break; 121 122 case 16: 123 if (ch >= '0' && ch <= '9') { 124 num = (num * 16) + (ch - '0'); 125 } else if (ch >= 'a' && ch <= 'f') { 126 num = (num * 16) + (ch - 'a' + 10); 127 } else if (ch >= 'A' && ch <= 'F') { 128 num = (num * 16) + (ch - 'A' + 10); 129 } else { 130 looping = 0; 131 } 132 break; 133 } 134 } 135 136 if (neg) 137 num = - num; 138 139 return num; 140 } 141 142 unsigned 143 target_a2i(int ms_bit_nr, 144 const char *a) 145 { 146 if (ms_bit_nr) 147 return (ms_bit_nr - a2i(a)); 148 else 149 return a2i(a); 150 } 151 152 unsigned 153 i2target(int ms_bit_nr, 154 unsigned bit) 155 { 156 if (ms_bit_nr) 157 return ms_bit_nr - bit; 158 else 159 return bit; 160 } 161 162 163 int 164 name2i(const char *names, 165 const name_map *map) 166 { 167 const name_map *curr; 168 const char *name = names; 169 while (*name != '\0') { 170 /* find our name */ 171 char *end = strchr(name, ','); 172 char *next; 173 int len; 174 if (end == NULL) { 175 end = strchr(name, '\0'); 176 next = end; 177 } 178 else { 179 next = end + 1; 180 } 181 len = end - name; 182 /* look it up */ 183 curr = map; 184 while (curr->name != NULL) { 185 if (strncmp(curr->name, name, len) == 0 186 && strlen(curr->name) == len) 187 return curr->i; 188 curr++; 189 } 190 name = next; 191 } 192 /* nothing found, possibly return a default */ 193 curr = map; 194 while (curr->name != NULL) 195 curr++; 196 if (curr->i >= 0) 197 return curr->i; 198 else 199 error("%s contains no valid names\n", names); 200 return 0; 201 } 202 203 const char * 204 i2name(const int i, 205 const name_map *map) 206 { 207 while (map->name != NULL) { 208 if (map->i == i) 209 return map->name; 210 map++; 211 } 212 error("map lookup failed for %d\n", i); 213 return NULL; 214 } 215