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