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