e962e01d980f5f6e3026cd3a629fd8822d63fc19
[external/binutils.git] / sim / igen / misc.c
1 /* The IGEN simulator generator for GDB, the GNU Debugger.
2
3    Copyright 2002, 2007 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 2 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, write to the Free Software
21    Foundation, Inc., 59 Temple Place - Suite 330,
22    Boston, MA 02111-1307, USA.  */
23
24
25
26 #include <stdio.h>
27 #include <stdarg.h>
28 #include <ctype.h>
29
30 #include "config.h"
31 #include "misc.h"
32
33 #ifdef HAVE_STDLIB_H
34 #include <stdlib.h>
35 #endif
36
37 #ifdef HAVE_STRING_H
38 #include <string.h>
39 #else
40 #ifdef HAVE_STRINGS_H
41 #include <strings.h>
42 #endif
43 #endif
44
45 /* NB: Because warning and error can be interchanged, neither append a
46    trailing '\n' */
47
48 void
49 error (const line_ref *line, char *msg, ...)
50 {
51   va_list ap;
52   if (line != NULL)
53     fprintf (stderr, "%s:%d: ", line->file_name, line->line_nr);
54   va_start (ap, msg);
55   vfprintf (stderr, msg, ap);
56   va_end (ap);
57   exit (1);
58 }
59
60 void
61 warning (const line_ref *line, char *msg, ...)
62 {
63   va_list ap;
64   if (line != NULL)
65     fprintf (stderr, "%s:%d: warning: ", line->file_name, line->line_nr);
66   va_start (ap, msg);
67   vfprintf (stderr, msg, ap);
68   va_end (ap);
69 }
70
71 void
72 notify (const line_ref *line, char *msg, ...)
73 {
74   va_list ap;
75   if (line != NULL)
76     fprintf (stdout, "%s %d: info: ", line->file_name, line->line_nr);
77   va_start (ap, msg);
78   vfprintf (stdout, msg, ap);
79   va_end (ap);
80 }
81
82 void *
83 zalloc (long size)
84 {
85   void *memory = malloc (size);
86   if (memory == NULL)
87     ERROR ("zalloc failed");
88   memset (memory, 0, size);
89   return memory;
90 }
91
92
93 unsigned long long
94 a2i (const char *a)
95 {
96   int neg = 0;
97   int base = 10;
98   unsigned long long num = 0;
99   int looping;
100
101   while (isspace (*a))
102     a++;
103
104   if (strcmp (a, "true") == 0 || strcmp (a, "TRUE") == 0)
105     return 1;
106
107   if (strcmp (a, "false") == 0 || strcmp (a, "false") == 0)
108     return 0;
109
110   if (*a == '-')
111     {
112       neg = 1;
113       a++;
114     }
115
116   if (*a == '0')
117     {
118       if (a[1] == 'x' || a[1] == 'X')
119         {
120           a += 2;
121           base = 16;
122         }
123       else if (a[1] == 'b' || a[1] == 'b')
124         {
125           a += 2;
126           base = 2;
127         }
128       else
129         base = 8;
130     }
131
132   looping = 1;
133   while (looping)
134     {
135       int ch = *a++;
136
137       switch (base)
138         {
139         default:
140           looping = 0;
141           break;
142
143         case 2:
144           if (ch >= '0' && ch <= '1')
145             {
146               num = (num * 2) + (ch - '0');
147             }
148           else
149             {
150               looping = 0;
151             }
152           break;
153
154         case 10:
155           if (ch >= '0' && ch <= '9')
156             {
157               num = (num * 10) + (ch - '0');
158             }
159           else
160             {
161               looping = 0;
162             }
163           break;
164
165         case 8:
166           if (ch >= '0' && ch <= '7')
167             {
168               num = (num * 8) + (ch - '0');
169             }
170           else
171             {
172               looping = 0;
173             }
174           break;
175
176         case 16:
177           if (ch >= '0' && ch <= '9')
178             {
179               num = (num * 16) + (ch - '0');
180             }
181           else if (ch >= 'a' && ch <= 'f')
182             {
183               num = (num * 16) + (ch - 'a' + 10);
184             }
185           else if (ch >= 'A' && ch <= 'F')
186             {
187               num = (num * 16) + (ch - 'A' + 10);
188             }
189           else
190             {
191               looping = 0;
192             }
193           break;
194         }
195     }
196
197   if (neg)
198     num = -num;
199
200   return num;
201 }
202
203 unsigned
204 target_a2i (int ms_bit_nr, const char *a)
205 {
206   if (ms_bit_nr)
207     return (ms_bit_nr - a2i (a));
208   else
209     return a2i (a);
210 }
211
212 unsigned
213 i2target (int ms_bit_nr, unsigned bit)
214 {
215   if (ms_bit_nr)
216     return ms_bit_nr - bit;
217   else
218     return bit;
219 }
220
221
222 int
223 name2i (const char *names, const name_map * map)
224 {
225   const name_map *curr;
226   const char *name = names;
227   while (*name != '\0')
228     {
229       /* find our name */
230       char *end = strchr (name, ',');
231       char *next;
232       unsigned len;
233       if (end == NULL)
234         {
235           end = strchr (name, '\0');
236           next = end;
237         }
238       else
239         {
240           next = end + 1;
241         }
242       len = end - name;
243       /* look it up */
244       curr = map;
245       while (curr->name != NULL)
246         {
247           if (strncmp (curr->name, name, len) == 0
248               && strlen (curr->name) == len)
249             return curr->i;
250           curr++;
251         }
252       name = next;
253     }
254   /* nothing found, possibly return a default */
255   curr = map;
256   while (curr->name != NULL)
257     curr++;
258   if (curr->i >= 0)
259     return curr->i;
260   else
261     error (NULL, "%s contains no valid names", names);
262   return 0;
263 }
264
265 const char *
266 i2name (const int i, const name_map * map)
267 {
268   while (map->name != NULL)
269     {
270       if (map->i == i)
271         return map->name;
272       map++;
273     }
274   error (NULL, "map lookup failed for %d\n", i);
275   return NULL;
276 }