1/* The IGEN simulator generator for GDB, the GNU Debugger. 2 3 Copyright 2002-2020 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 "config.h" 29#include "misc.h" 30 31#ifdef HAVE_STDLIB_H 32#include <stdlib.h> 33#endif 34 35#ifdef HAVE_STRING_H 36#include <string.h> 37#else 38#ifdef HAVE_STRINGS_H 39#include <strings.h> 40#endif 41#endif 42 43/* NB: Because warning and error can be interchanged, neither append a 44 trailing '\n' */ 45 46void 47error (const line_ref *line, char *msg, ...) 48{ 49 va_list ap; 50 if (line != NULL) 51 fprintf (stderr, "%s:%d: ", line->file_name, line->line_nr); 52 va_start (ap, msg); 53 vfprintf (stderr, msg, ap); 54 va_end (ap); 55 exit (1); 56} 57 58void 59warning (const line_ref *line, char *msg, ...) 60{ 61 va_list ap; 62 if (line != NULL) 63 fprintf (stderr, "%s:%d: warning: ", line->file_name, line->line_nr); 64 va_start (ap, msg); 65 vfprintf (stderr, msg, ap); 66 va_end (ap); 67} 68 69void 70notify (const line_ref *line, char *msg, ...) 71{ 72 va_list ap; 73 if (line != NULL) 74 fprintf (stdout, "%s %d: info: ", line->file_name, line->line_nr); 75 va_start (ap, msg); 76 vfprintf (stdout, msg, ap); 77 va_end (ap); 78} 79 80void * 81zalloc (long size) 82{ 83 void *memory = malloc (size); 84 if (memory == NULL) 85 ERROR ("zalloc failed"); 86 memset (memory, 0, size); 87 return memory; 88} 89 90 91unsigned long long 92a2i (const char *a) 93{ 94 int neg = 0; 95 int base = 10; 96 unsigned long long num = 0; 97 int looping; 98 99 while (isspace (*a)) 100 a++; 101 102 if (strcmp (a, "true") == 0 || strcmp (a, "TRUE") == 0) 103 return 1; 104 105 if (strcmp (a, "false") == 0 || strcmp (a, "FALSE") == 0) 106 return 0; 107 108 if (*a == '-') 109 { 110 neg = 1; 111 a++; 112 } 113 114 if (*a == '0') 115 { 116 if (a[1] == 'x' || a[1] == 'X') 117 { 118 a += 2; 119 base = 16; 120 } 121 else if (a[1] == 'b' || a[1] == 'B') 122 { 123 a += 2; 124 base = 2; 125 } 126 else 127 base = 8; 128 } 129 130 looping = 1; 131 while (looping) 132 { 133 int ch = *a++; 134 135 switch (base) 136 { 137 default: 138 looping = 0; 139 break; 140 141 case 2: 142 if (ch >= '0' && ch <= '1') 143 { 144 num = (num * 2) + (ch - '0'); 145 } 146 else 147 { 148 looping = 0; 149 } 150 break; 151 152 case 10: 153 if (ch >= '0' && ch <= '9') 154 { 155 num = (num * 10) + (ch - '0'); 156 } 157 else 158 { 159 looping = 0; 160 } 161 break; 162 163 case 8: 164 if (ch >= '0' && ch <= '7') 165 { 166 num = (num * 8) + (ch - '0'); 167 } 168 else 169 { 170 looping = 0; 171 } 172 break; 173 174 case 16: 175 if (ch >= '0' && ch <= '9') 176 { 177 num = (num * 16) + (ch - '0'); 178 } 179 else if (ch >= 'a' && ch <= 'f') 180 { 181 num = (num * 16) + (ch - 'a' + 10); 182 } 183 else if (ch >= 'A' && ch <= 'F') 184 { 185 num = (num * 16) + (ch - 'A' + 10); 186 } 187 else 188 { 189 looping = 0; 190 } 191 break; 192 } 193 } 194 195 if (neg) 196 num = -num; 197 198 return num; 199} 200 201unsigned 202target_a2i (int ms_bit_nr, const char *a) 203{ 204 if (ms_bit_nr) 205 return (ms_bit_nr - a2i (a)); 206 else 207 return a2i (a); 208} 209 210unsigned 211i2target (int ms_bit_nr, unsigned bit) 212{ 213 if (ms_bit_nr) 214 return ms_bit_nr - bit; 215 else 216 return bit; 217} 218 219 220int 221name2i (const char *names, const name_map * map) 222{ 223 const name_map *curr; 224 const char *name = names; 225 while (*name != '\0') 226 { 227 /* find our name */ 228 char *end = strchr (name, ','); 229 char *next; 230 unsigned len; 231 if (end == NULL) 232 { 233 end = strchr (name, '\0'); 234 next = end; 235 } 236 else 237 { 238 next = end + 1; 239 } 240 len = end - name; 241 /* look it up */ 242 curr = map; 243 while (curr->name != NULL) 244 { 245 if (strncmp (curr->name, name, len) == 0 246 && strlen (curr->name) == len) 247 return curr->i; 248 curr++; 249 } 250 name = next; 251 } 252 /* nothing found, possibly return a default */ 253 curr = map; 254 while (curr->name != NULL) 255 curr++; 256 if (curr->i >= 0) 257 return curr->i; 258 else 259 error (NULL, "%s contains no valid names", names); 260 return 0; 261} 262 263const char * 264i2name (const int i, const name_map * map) 265{ 266 while (map->name != NULL) 267 { 268 if (map->i == i) 269 return map->name; 270 map++; 271 } 272 error (NULL, "map lookup failed for %d\n", i); 273 return NULL; 274} 275