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