RIP gzip, we found a nicer playmate.
[dragonfly.git] / gnu / usr.bin / as / messages.c
1 /* messages.c - error reporter -
2    Copyright (C) 1987, 1991, 1992 Free Software Foundation, Inc.
3
4    This file is part of GAS, the GNU Assembler.
5
6    GAS is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 2, or (at your option)
9    any later version.
10
11    GAS is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with GAS; see the file COPYING.  If not, write to
18    the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20 /*
21  * $FreeBSD: src/gnu/usr.bin/as/messages.c,v 1.8 1999/08/27 23:34:19 peter Exp $
22  * $DragonFly: src/gnu/usr.bin/as/Attic/messages.c,v 1.3 2004/01/23 20:53:09 joerg Exp $
23  */
24 #include <stdio.h>
25 #include <errno.h>
26
27 #include "as.h"
28
29 #include <stdarg.h>
30
31 extern char *strerror ();
32
33 static void as_show_where PARAMS ((void));
34 static void as_warn_internal PARAMS ((char *, unsigned int, char *));
35 static void as_bad_internal PARAMS ((char *, unsigned int, char *));
36
37 /*
38  * Despite the rest of the comments in this file, (FIXME-SOON),
39  * here is the current scheme for error messages etc:
40  *
41  * as_fatal() is used when gas is quite confused and
42  * continuing the assembly is pointless.  In this case we
43  * exit immediately with error status.
44  *
45  * as_bad() is used to mark errors that result in what we
46  * presume to be a useless object file.  Say, we ignored
47  * something that might have been vital.  If we see any of
48  * these, assembly will continue to the end of the source,
49  * no object file will be produced, and we will terminate
50  * with error status.  The new option, -Z, tells us to
51  * produce an object file anyway but we still exit with
52  * error status.  The assumption here is that you don't want
53  * this object file but we could be wrong.
54  *
55  * as_warn() is used when we have an error from which we
56  * have a plausible error recovery.  eg, masking the top
57  * bits of a constant that is longer than will fit in the
58  * destination.  In this case we will continue to assemble
59  * the source, although we may have made a bad assumption,
60  * and we will produce an object file and return normal exit
61  * status (ie, no error).  The new option -X tells us to
62  * treat all as_warn() errors as as_bad() errors.  That is,
63  * no object file will be produced and we will exit with
64  * error status.  The idea here is that we don't kill an
65  * entire make because of an error that we knew how to
66  * correct.  On the other hand, sometimes you might want to
67  * stop the make at these points.
68  *
69  * as_tsktsk() is used when we see a minor error for which
70  * our error recovery action is almost certainly correct.
71  * In this case, we print a message and then assembly
72  * continues as though no error occurred.
73  */
74
75 static void
76 identify(char *file)
77 {
78   static int identified;
79   if (identified)
80     return;
81   identified++;
82
83   if (!file)
84     {
85       unsigned int x;
86       as_where (&file, &x);
87     }
88
89   fprintf (stderr, "%s: Assembler messages:\n", file);
90 }
91
92 static int warning_count;       /* Count of number of warnings issued */
93
94 int
95 had_warnings ()
96 {
97   return (warning_count);
98 }                               /* had_err() */
99
100 /* Nonzero if we've hit a 'bad error', and should not write an obj file,
101    and exit with a nonzero error code */
102
103 static int error_count;
104
105 int
106 had_errors ()
107 {
108   return (error_count);
109 }                               /* had_errors() */
110
111
112 /* Print the current location to stderr.  */
113
114 static void
115 as_show_where ()
116 {
117   char *file;
118   unsigned int line;
119
120   as_where (&file, &line);
121   identify (file);
122   fprintf (stderr, "%s:%u: ", file, line);
123 }
124
125 /*
126  *                      a s _ p e r r o r
127  *
128  * Like perror(3), but with more info.
129  */
130
131 void
132 as_perror (gripe, filename)
133      const char *gripe;         /* Unpunctuated error theme. */
134      const char *filename;
135 {
136   const char *errtxt;
137
138   as_show_where ();
139   fprintf (stderr, gripe, filename);
140 #ifdef BFD_ASSEMBLER
141   errtxt = bfd_errmsg (bfd_get_error ());
142 #else
143   errtxt = strerror (errno);
144 #endif
145   fprintf (stderr, ": %s\n", errtxt);
146   errno = 0;
147 #ifdef BFD_ASSEMBLER
148   bfd_set_error (bfd_error_no_error);
149 #endif
150 }
151
152 /*
153  *                      a s _ t s k t s k ()
154  *
155  * Send to stderr a string as a warning, and locate warning
156  * in input file(s).
157  * Please only use this for when we have some recovery action.
158  * Please explain in string (which may have '\n's) what recovery was done.
159  */
160
161 void
162 as_tsktsk(const char *format, ...)
163 {
164   va_list args;
165
166   as_show_where ();
167   va_start (args, format);
168   vfprintf (stderr, format, args);
169   va_end (args);
170   (void) putc ('\n', stderr);
171 }                               /* as_tsktsk() */
172
173 /* The common portion of as_warn and as_warn_where.  */
174
175 static void
176 as_warn_internal (file, line, buffer)
177      char *file;
178      unsigned int line;
179      char *buffer;
180 {
181   ++warning_count;
182
183   if (file == NULL)
184     as_where (&file, &line);
185
186   identify (file);
187   fprintf (stderr, "%s:%u: Warning: ", file, line);
188   fputs (buffer, stderr);
189   (void) putc ('\n', stderr);
190 #ifndef NO_LISTING
191   listing_warning (buffer);
192 #endif
193 }
194
195 /*
196  *                      a s _ w a r n ()
197  *
198  * Send to stderr a string as a warning, and locate warning
199  * in input file(s).
200  * Please only use this for when we have some recovery action.
201  * Please explain in string (which may have '\n's) what recovery was done.
202  */
203
204 #if 1
205 #define flag_no_warnings        (flagseen['W'])
206 #endif
207
208 void
209 as_warn (const char *format,...)
210 {
211   va_list args;
212   char buffer[200];
213
214   if (!flag_no_warnings)
215     {
216       va_start (args, format);
217       vsprintf (buffer, format, args);
218       va_end (args);
219       as_warn_internal ((char *) NULL, 0, buffer);
220     }
221 }                               /* as_warn() */
222
223 /* as_warn_where, like as_bad but the file name and line number are
224    passed in.  Unfortunately, we have to repeat the function in order
225    to handle the varargs correctly and portably.  */
226
227 void
228 as_warn_where(char *file, unsigned int line, const char *format, ...)
229 {
230   va_list args;
231   char buffer[200];
232
233   if (!flag_no_warnings)
234     {
235       va_start (args, format);
236       vsprintf (buffer, format, args);
237       va_end (args);
238       as_warn_internal (file, line, buffer);
239     }
240 }                               /* as_warn() */
241
242 /* The common portion of as_bad and as_bad_where.  */
243
244 static void
245 as_bad_internal (file, line, buffer)
246      char *file;
247      unsigned int line;
248      char *buffer;
249 {
250   ++error_count;
251
252   if (file == NULL)
253     as_where (&file, &line);
254
255   identify (file);
256   fprintf (stderr, "%s:%u: Error: ", file, line);
257   fputs (buffer, stderr);
258   (void) putc ('\n', stderr);
259 #ifndef NO_LISTING
260   listing_error (buffer);
261 #endif
262 }
263
264 /*
265  *                      a s _ b a d ()
266  *
267  * Send to stderr a string as a warning, and locate warning in input file(s).
268  * Please us when there is no recovery, but we want to continue processing
269  * but not produce an object file.
270  * Please explain in string (which may have '\n's) what recovery was done.
271  */
272
273 void
274 as_bad (const char *format,...)
275 {
276   va_list args;
277   char buffer[200];
278
279   va_start (args, format);
280   vsprintf (buffer, format, args);
281   va_end (args);
282
283   as_bad_internal ((char *) NULL, 0, buffer);
284 }
285
286 /* as_bad_where, like as_bad but the file name and line number are
287    passed in.  Unfortunately, we have to repeat the function in order
288    to handle the varargs correctly and portably.  */
289
290 void
291 as_bad_where (char *file, unsigned int line, const char *format,...)
292 {
293   va_list args;
294   char buffer[200];
295
296   va_start (args, format);
297   vsprintf (buffer, format, args);
298   va_end (args);
299
300   as_bad_internal (file, line, buffer);
301 }
302
303 /*
304  *                      a s _ f a t a l ()
305  *
306  * Send to stderr a string as a fatal message, and print location of error in
307  * input file(s).
308  * Please only use this for when we DON'T have some recovery action.
309  * It exit()s with a warning status.
310  */
311
312 void
313 as_fatal (const char *format,...)
314 {
315   va_list args;
316
317   as_show_where ();
318   va_start (args, format);
319   fprintf (stderr, "Fatal error:");
320   vfprintf (stderr, format, args);
321   (void) putc ('\n', stderr);
322   va_end (args);
323   exit (33);
324 }                               /* as_fatal() */
325
326 void
327 fprint_value (file, val)
328      FILE *file;
329      valueT val;
330 {
331   if (sizeof (val) <= sizeof (long))
332     {
333       fprintf (file, "%ld", (long) val);
334       return;
335     }
336 #ifdef BFD_ASSEMBLER
337   if (sizeof (val) <= sizeof (bfd_vma))
338     {
339       fprintf_vma (file, val);
340       return;
341     }
342 #endif
343   abort ();
344 }
345
346 void
347 sprint_value (buf, val)
348      char *buf;
349      valueT val;
350 {
351   if (sizeof (val) <= sizeof (long))
352     {
353       sprintf (buf, "%ld", (long) val);
354       return;
355     }
356 #ifdef BFD_ASSEMBLER
357   if (sizeof (val) <= sizeof (bfd_vma))
358     {
359       sprintf_vma (buf, val);
360       return;
361     }
362 #endif
363   abort ();
364 }
365
366 /* end of messages.c */