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