1 /* The IGEN simulator generator for GDB, the GNU Debugger. 2 3 Copyright 2002-2024 Free Software Foundation, Inc. 4 5 Contributed by Andrew Cagney. 6 7 This file is part of GDB. 8 9 This program is free software; you can redistribute it and/or modify 10 it under the terms of the GNU General Public License as published by 11 the Free Software Foundation; either version 3 of the License, or 12 (at your option) any later version. 13 14 This program is distributed in the hope that it will be useful, 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 GNU General Public License for more details. 18 19 You should have received a copy of the GNU General Public License 20 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 21 22 23 24 #include <stdio.h> 25 #include <stdarg.h> 26 #include <ctype.h> 27 28 #include "misc.h" 29 30 #include <stdlib.h> 31 #include <string.h> 32 33 /* NB: Because warning and error can be interchanged, neither append a 34 trailing '\n' */ 35 36 void 37 error (const line_ref *line, const char *msg, ...) 38 { 39 va_list ap; 40 if (line != NULL) 41 fprintf (stderr, "%s:%d: ", line->file_name, line->line_nr); 42 va_start (ap, msg); 43 vfprintf (stderr, msg, ap); 44 va_end (ap); 45 exit (1); 46 } 47 48 void 49 warning (const line_ref *line, const char *msg, ...) 50 { 51 va_list ap; 52 if (line != NULL) 53 fprintf (stderr, "%s:%d: warning: ", line->file_name, line->line_nr); 54 va_start (ap, msg); 55 vfprintf (stderr, msg, ap); 56 va_end (ap); 57 } 58 59 void 60 notify (const line_ref *line, const char *msg, ...) 61 { 62 va_list ap; 63 if (line != NULL) 64 fprintf (stdout, "%s %d: info: ", line->file_name, line->line_nr); 65 va_start (ap, msg); 66 vfprintf (stdout, msg, ap); 67 va_end (ap); 68 } 69 70 void * 71 zalloc (long size) 72 { 73 void *memory = malloc (size); 74 if (memory == NULL) 75 ERROR ("zalloc failed"); 76 memset (memory, 0, size); 77 return memory; 78 } 79 80 81 unsigned long long 82 a2i (const char *a) 83 { 84 int neg = 0; 85 int base = 10; 86 unsigned long long num = 0; 87 int looping; 88 89 while (isspace (*a)) 90 a++; 91 92 if (strcmp (a, "true") == 0 || strcmp (a, "TRUE") == 0) 93 return 1; 94 95 if (strcmp (a, "false") == 0 || strcmp (a, "FALSE") == 0) 96 return 0; 97 98 if (*a == '-') 99 { 100 neg = 1; 101 a++; 102 } 103 104 if (*a == '0') 105 { 106 if (a[1] == 'x' || a[1] == 'X') 107 { 108 a += 2; 109 base = 16; 110 } 111 else if (a[1] == 'b' || a[1] == 'B') 112 { 113 a += 2; 114 base = 2; 115 } 116 else 117 base = 8; 118 } 119 120 looping = 1; 121 while (looping) 122 { 123 int ch = *a++; 124 125 switch (base) 126 { 127 default: 128 looping = 0; 129 break; 130 131 case 2: 132 if (ch >= '0' && ch <= '1') 133 { 134 num = (num * 2) + (ch - '0'); 135 } 136 else 137 { 138 looping = 0; 139 } 140 break; 141 142 case 10: 143 if (ch >= '0' && ch <= '9') 144 { 145 num = (num * 10) + (ch - '0'); 146 } 147 else 148 { 149 looping = 0; 150 } 151 break; 152 153 case 8: 154 if (ch >= '0' && ch <= '7') 155 { 156 num = (num * 8) + (ch - '0'); 157 } 158 else 159 { 160 looping = 0; 161 } 162 break; 163 164 case 16: 165 if (ch >= '0' && ch <= '9') 166 { 167 num = (num * 16) + (ch - '0'); 168 } 169 else if (ch >= 'a' && ch <= 'f') 170 { 171 num = (num * 16) + (ch - 'a' + 10); 172 } 173 else if (ch >= 'A' && ch <= 'F') 174 { 175 num = (num * 16) + (ch - 'A' + 10); 176 } 177 else 178 { 179 looping = 0; 180 } 181 break; 182 } 183 } 184 185 if (neg) 186 num = -num; 187 188 return num; 189 } 190 191 unsigned 192 target_a2i (int ms_bit_nr, const char *a) 193 { 194 if (ms_bit_nr) 195 return (ms_bit_nr - a2i (a)); 196 else 197 return a2i (a); 198 } 199 200 unsigned 201 i2target (int ms_bit_nr, unsigned bit) 202 { 203 if (ms_bit_nr) 204 return ms_bit_nr - bit; 205 else 206 return bit; 207 } 208 209 210 int 211 name2i (const char *names, const name_map * map) 212 { 213 const name_map *curr; 214 const char *name = names; 215 while (*name != '\0') 216 { 217 /* find our name */ 218 const char *end = strchr (name, ','); 219 const char *next; 220 unsigned len; 221 if (end == NULL) 222 { 223 end = strchr (name, '\0'); 224 next = end; 225 } 226 else 227 { 228 next = end + 1; 229 } 230 len = end - name; 231 /* look it up */ 232 curr = map; 233 while (curr->name != NULL) 234 { 235 if (strncmp (curr->name, name, len) == 0 236 && strlen (curr->name) == len) 237 return curr->i; 238 curr++; 239 } 240 name = next; 241 } 242 /* nothing found, possibly return a default */ 243 curr = map; 244 while (curr->name != NULL) 245 curr++; 246 if (curr->i >= 0) 247 return curr->i; 248 else 249 error (NULL, "%s contains no valid names\n", names); 250 return 0; 251 } 252 253 const char * 254 i2name (const int i, const name_map * map) 255 { 256 while (map->name != NULL) 257 { 258 if (map->i == i) 259 return map->name; 260 map++; 261 } 262 error (NULL, "map lookup failed for %d\n", i); 263 return NULL; 264 } 265