xref: /netbsd-src/external/gpl3/gdb/dist/sim/igen/misc.c (revision 181254a7b1bdde6873432bffef2d2decc4b5c22f)
1 /* The IGEN simulator generator for GDB, the GNU Debugger.
2 
3    Copyright 2002-2019 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 
46 void
47 error (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 
58 void
59 warning (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 
69 void
70 notify (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 
80 void *
81 zalloc (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 
91 unsigned long long
92 a2i (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 
201 unsigned
202 target_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 
210 unsigned
211 i2target (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 
220 int
221 name2i (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 
263 const char *
264 i2name (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