This commit was generated by cvs2svn to track changes on a CVS vendor
[external/binutils.git] / sim / igen / misc.c
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
41 /* NB: Because warning and error can be interchanged, neither append a
42    trailing '\n' */
43
44 void
45 error (const line_ref *line,
46        char *msg,
47        ...)
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,
60          char *msg,
61          ...)
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,
73         char *msg,
74         ...)
75 {
76   va_list ap;
77   if (line != NULL)
78     fprintf (stdout, "%s %d: info: ", line->file_name, line->line_nr);
79   va_start(ap, msg);
80   vfprintf (stdout, msg, ap);
81   va_end(ap);
82 }
83
84 void *
85 zalloc(long size)
86 {
87   void *memory = malloc(size);
88   if (memory == NULL)
89     ERROR ("zalloc failed");
90   memset(memory, 0, size);
91   return memory;
92 }
93
94
95 unsigned long long
96 a2i (const char *a)
97 {
98   int neg = 0;
99   int base = 10;
100   unsigned long long num = 0;
101   int looping;
102   
103   while (isspace (*a))
104     a++;
105   
106   if (strcmp (a, "true") == 0
107       || strcmp (a, "TRUE") == 0)
108     return 1;
109
110   if (strcmp (a, "false") == 0
111       || strcmp (a, "false") == 0)
112     return 0;
113
114   if (*a == '-')
115     {
116       neg = 1;
117       a++;
118     }
119   
120   if (*a == '0')
121     {
122       if (a[1] == 'x' || a[1] == 'X')
123         {
124           a += 2;
125           base = 16;
126         }
127       else if (a[1] == 'b' || a[1] == 'b')
128         {
129           a += 2;
130           base = 2;
131         }
132       else
133         base = 8;
134     }
135   
136   looping = 1;
137   while (looping)
138     {
139       int ch = *a++;
140       
141       switch (base)
142         {
143         default:
144           looping = 0;
145           break;
146           
147         case 2:
148           if (ch >= '0' && ch <= '1')
149             {
150               num = (num * 2) + (ch - '0');
151             }
152           else
153             {
154               looping = 0;
155             }
156           break;
157           
158         case 10:
159           if (ch >= '0' && ch <= '9')
160             {
161               num = (num * 10) + (ch - '0');
162             }
163           else
164             {
165               looping = 0;
166             }
167           break;
168           
169         case 8:
170           if (ch >= '0' && ch <= '7')
171             {
172               num = (num * 8) + (ch - '0');
173             }
174           else
175             {
176               looping = 0;
177             }
178           break;
179           
180         case 16:
181           if (ch >= '0' && ch <= '9')
182             {
183               num = (num * 16) + (ch - '0');
184             }
185           else if (ch >= 'a' && ch <= 'f')
186             {
187               num = (num * 16) + (ch - 'a' + 10);
188             }
189           else if (ch >= 'A' && ch <= 'F')
190             {
191               num = (num * 16) + (ch - 'A' + 10);
192             }
193           else
194             {
195               looping = 0;
196             }
197           break;
198         }
199     }
200   
201   if (neg)
202     num = - num;
203
204   return num;
205 }
206
207 unsigned
208 target_a2i(int ms_bit_nr,
209            const char *a)
210 {
211   if (ms_bit_nr)
212     return (ms_bit_nr - a2i(a));
213   else
214     return a2i(a);
215 }
216
217 unsigned
218 i2target(int ms_bit_nr,
219          unsigned bit)
220 {
221   if (ms_bit_nr)
222     return ms_bit_nr - bit;
223   else
224     return bit;
225 }
226
227
228 int
229 name2i (const char *names,
230         const name_map *map)
231 {
232   const name_map *curr;
233   const char *name = names;
234   while (*name != '\0')
235     {
236       /* find our name */
237       char *end = strchr(name, ',');
238       char *next;
239       unsigned len;
240       if (end == NULL)
241         {
242           end = strchr(name, '\0');
243           next = end;
244         }
245       else
246         {
247           next = end + 1;
248         }
249       len = end - name;
250       /* look it up */
251       curr = map;
252       while (curr->name != NULL)
253         {
254           if (strncmp (curr->name, name, len) == 0
255               && strlen (curr->name) == len)
256             return curr->i;
257           curr++;
258         }
259       name = next;
260     }
261   /* nothing found, possibly return a default */
262   curr = map;
263   while (curr->name != NULL)
264     curr++;
265   if (curr->i >= 0)
266     return curr->i;
267   else
268     error (NULL, "%s contains no valid names", names);
269   return 0;
270 }
271
272 const char *
273 i2name (const int i,
274         const name_map *map)
275 {
276   while (map->name != NULL)
277     {
278       if (map->i == i)
279         return map->name;
280       map++;
281     }
282   error (NULL, "map lookup failed for %d\n", i);
283   return NULL;
284 }