* listing.c: Convert to ISO-C.
[external/binutils.git] / gas / messages.c
1 /* messages.c - error reporter -
2    Copyright 1987, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 2000, 2001
3    Free Software Foundation, Inc.
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 the Free
18    Software Foundation, 59 Temple Place - Suite 330, Boston, MA
19    02111-1307, USA.  */
20
21 #include "as.h"
22
23 #include <stdio.h>
24 #ifdef HAVE_ERRNO_H
25 #include <errno.h>
26 #endif
27
28 #ifdef USE_STDARG
29 #include <stdarg.h>
30 #endif
31
32 #ifdef USE_VARARGS
33 #include <varargs.h>
34 #endif
35
36 #if !defined (USE_STDARG) && !defined (USE_VARARGS)
37 /* Roll our own.  */
38 #define va_alist REST
39 #define va_dcl
40 typedef int * va_list;
41 #define va_start(ARGS)  ARGS = &REST
42 #define va_end(ARGS)
43 #endif
44
45 static void identify (char *);
46 static void as_show_where (void);
47 static void as_warn_internal (char *, unsigned int, char *);
48 static void as_bad_internal (char *, unsigned int, char *);
49
50 /* Despite the rest of the comments in this file, (FIXME-SOON),
51  * here is the current scheme for error messages etc:
52  *
53  * as_fatal() is used when gas is quite confused and
54  * continuing the assembly is pointless.  In this case we
55  * exit immediately with error status.
56  *
57  * as_bad() is used to mark errors that result in what we
58  * presume to be a useless object file.  Say, we ignored
59  * something that might have been vital.  If we see any of
60  * these, assembly will continue to the end of the source,
61  * no object file will be produced, and we will terminate
62  * with error status.  The new option, -Z, tells us to
63  * produce an object file anyway but we still exit with
64  * error status.  The assumption here is that you don't want
65  * this object file but we could be wrong.
66  *
67  * as_warn() is used when we have an error from which we
68  * have a plausible error recovery.  eg, masking the top
69  * bits of a constant that is longer than will fit in the
70  * destination.  In this case we will continue to assemble
71  * the source, although we may have made a bad assumption,
72  * and we will produce an object file and return normal exit
73  * status (ie, no error).  The new option -X tells us to
74  * treat all as_warn() errors as as_bad() errors.  That is,
75  * no object file will be produced and we will exit with
76  * error status.  The idea here is that we don't kill an
77  * entire make because of an error that we knew how to
78  * correct.  On the other hand, sometimes you might want to
79  * stop the make at these points.
80  *
81  * as_tsktsk() is used when we see a minor error for which
82  * our error recovery action is almost certainly correct.
83  * In this case, we print a message and then assembly
84  * continues as though no error occurred.
85  */
86
87 static void
88 identify (char *file)
89 {
90   static int identified;
91   if (identified)
92     return;
93   identified++;
94
95   if (!file)
96     {
97       unsigned int x;
98       as_where (&file, &x);
99     }
100
101   if (file)
102     fprintf (stderr, "%s: ", file);
103   fprintf (stderr, _("Assembler messages:\n"));
104 }
105
106 /* The number of warnings issued.  */
107 static int warning_count;
108
109 int
110 had_warnings (void)
111 {
112   return (warning_count);
113 }
114
115 /* Nonzero if we've hit a 'bad error', and should not write an obj file,
116    and exit with a nonzero error code.  */
117
118 static int error_count;
119
120 int
121 had_errors (void)
122 {
123   return (error_count);
124 }
125
126 /* Print the current location to stderr.  */
127
128 static void
129 as_show_where (void)
130 {
131   char *file;
132   unsigned int line;
133
134   as_where (&file, &line);
135   identify (file);
136   if (file)
137     fprintf (stderr, "%s:%u: ", file, line);
138 }
139
140 /* Like perror(3), but with more info.  */
141
142 void
143 as_perror (const char *gripe,           /* Unpunctuated error theme.  */
144            const char *filename)
145 {
146   const char *errtxt;
147
148   as_show_where ();
149   fprintf (stderr, gripe, filename);
150 #ifdef BFD_ASSEMBLER
151   errtxt = bfd_errmsg (bfd_get_error ());
152 #else
153   errtxt = xstrerror (errno);
154 #endif
155   fprintf (stderr, ": %s\n", errtxt);
156   errno = 0;
157 #ifdef BFD_ASSEMBLER
158   bfd_set_error (bfd_error_no_error);
159 #endif
160 }
161
162 /* Send to stderr a string as a warning, and locate warning
163    in input file(s).
164    Please only use this for when we have some recovery action.
165    Please explain in string (which may have '\n's) what recovery was
166    done.  */
167
168 #ifdef USE_STDARG
169 void
170 as_tsktsk (const char *format, ...)
171 {
172   va_list args;
173
174   as_show_where ();
175   va_start (args, format);
176   vfprintf (stderr, format, args);
177   va_end (args);
178   (void) putc ('\n', stderr);
179 }
180 #else
181 void
182 as_tsktsk (format, va_alist)
183      const char *format;
184      va_dcl
185 {
186   va_list args;
187
188   as_show_where ();
189   va_start (args);
190   vfprintf (stderr, format, args);
191   va_end (args);
192   (void) putc ('\n', stderr);
193 }
194 #endif /* not NO_STDARG */
195
196 /* The common portion of as_warn and as_warn_where.  */
197
198 static void
199 as_warn_internal (char *file, unsigned int line, char *buffer)
200 {
201   ++warning_count;
202
203   if (file == NULL)
204     as_where (&file, &line);
205
206   identify (file);
207   if (file)
208     fprintf (stderr, "%s:%u: ", file, line);
209   fprintf (stderr, _("Warning: "));
210   fputs (buffer, stderr);
211   (void) putc ('\n', stderr);
212 #ifndef NO_LISTING
213   listing_warning (buffer);
214 #endif
215 }
216
217 /* Send to stderr a string as a warning, and locate warning
218    in input file(s).
219    Please only use this for when we have some recovery action.
220    Please explain in string (which may have '\n's) what recovery was
221    done.  */
222
223 #ifdef USE_STDARG
224 void
225 as_warn (const char *format, ...)
226 {
227   va_list args;
228   char buffer[2000];
229
230   if (!flag_no_warnings)
231     {
232       va_start (args, format);
233       vsprintf (buffer, format, args);
234       va_end (args);
235       as_warn_internal ((char *) NULL, 0, buffer);
236     }
237 }
238 #else
239 void
240 as_warn (format, va_alist)
241      const char *format;
242      va_dcl
243 {
244   va_list args;
245   char buffer[2000];
246
247   if (!flag_no_warnings)
248     {
249       va_start (args);
250       vsprintf (buffer, format, args);
251       va_end (args);
252       as_warn_internal ((char *) NULL, 0, buffer);
253     }
254 }
255 #endif /* not NO_STDARG */
256
257 /* Like as_bad but the file name and line number are passed in.
258    Unfortunately, we have to repeat the function in order to handle
259    the varargs correctly and portably.  */
260
261 #ifdef USE_STDARG
262 void
263 as_warn_where (char *file, unsigned int line, const char *format, ...)
264 {
265   va_list args;
266   char buffer[2000];
267
268   if (!flag_no_warnings)
269     {
270       va_start (args, format);
271       vsprintf (buffer, format, args);
272       va_end (args);
273       as_warn_internal (file, line, buffer);
274     }
275 }
276 #else
277 void
278 as_warn_where (file, line, format, va_alist)
279      char *file;
280      unsigned int line;
281      const char *format;
282      va_dcl
283 {
284   va_list args;
285   char buffer[2000];
286
287   if (!flag_no_warnings)
288     {
289       va_start (args);
290       vsprintf (buffer, format, args);
291       va_end (args);
292       as_warn_internal (file, line, buffer);
293     }
294 }
295 #endif /* not NO_STDARG */
296
297 /* The common portion of as_bad and as_bad_where.  */
298
299 static void
300 as_bad_internal (char *file, unsigned int line, char *buffer)
301 {
302   ++error_count;
303
304   if (file == NULL)
305     as_where (&file, &line);
306
307   identify (file);
308   if (file)
309     fprintf (stderr, "%s:%u: ", file, line);
310   fprintf (stderr, _("Error: "));
311   fputs (buffer, stderr);
312   (void) putc ('\n', stderr);
313 #ifndef NO_LISTING
314   listing_error (buffer);
315 #endif
316 }
317
318 /* Send to stderr a string as a warning, and locate warning in input
319    file(s).  Please us when there is no recovery, but we want to
320    continue processing but not produce an object file.
321    Please explain in string (which may have '\n's) what recovery was
322    done.  */
323
324 #ifdef USE_STDARG
325 void
326 as_bad (const char *format, ...)
327 {
328   va_list args;
329   char buffer[2000];
330
331   va_start (args, format);
332   vsprintf (buffer, format, args);
333   va_end (args);
334
335   as_bad_internal ((char *) NULL, 0, buffer);
336 }
337
338 #else
339 void
340 as_bad (format, va_alist)
341      const char *format;
342      va_dcl
343 {
344   va_list args;
345   char buffer[2000];
346
347   va_start (args);
348   vsprintf (buffer, format, args);
349   va_end (args);
350
351   as_bad_internal ((char *) NULL, 0, buffer);
352 }
353 #endif /* not NO_STDARG */
354
355 /* Like as_bad but the file name and line number are passed in.
356    Unfortunately, we have to repeat the function in order to handle
357    the varargs correctly and portably.  */
358
359 #ifdef USE_STDARG
360 void
361 as_bad_where (char *file, unsigned int line, const char *format, ...)
362 {
363   va_list args;
364   char buffer[2000];
365
366   va_start (args, format);
367   vsprintf (buffer, format, args);
368   va_end (args);
369
370   as_bad_internal (file, line, buffer);
371 }
372
373 #else
374 void
375 as_bad_where (file, line, format, va_alist)
376      char *file;
377      unsigned int line;
378      const char *format;
379      va_dcl
380 {
381   va_list args;
382   char buffer[2000];
383
384   va_start (args);
385   vsprintf (buffer, format, args);
386   va_end (args);
387
388   as_bad_internal (file, line, buffer);
389 }
390 #endif /* not NO_STDARG */
391
392 /* Send to stderr a string as a fatal message, and print location of
393    error in input file(s).
394    Please only use this for when we DON'T have some recovery action.
395    It xexit()s with a warning status.  */
396
397 #ifdef USE_STDARG
398 void
399 as_fatal (const char *format, ...)
400 {
401   va_list args;
402
403   as_show_where ();
404   va_start (args, format);
405   fprintf (stderr, _("Fatal error: "));
406   vfprintf (stderr, format, args);
407   (void) putc ('\n', stderr);
408   va_end (args);
409   /* Delete the output file, if it exists.  This will prevent make from
410      thinking that a file was created and hence does not need rebuilding.  */
411   if (out_file_name != NULL)
412     unlink (out_file_name);
413   xexit (EXIT_FAILURE);
414 }
415 #else
416 void
417 as_fatal (format, va_alist)
418      char *format;
419      va_dcl
420 {
421   va_list args;
422
423   as_show_where ();
424   va_start (args);
425   fprintf (stderr, _("Fatal error: "));
426   vfprintf (stderr, format, args);
427   (void) putc ('\n', stderr);
428   va_end (args);
429   xexit (EXIT_FAILURE);
430 }
431 #endif /* not NO_STDARG */
432
433 /* Indicate assertion failure.
434    Arguments: Filename, line number, optional function name.  */
435
436 void
437 as_assert (const char *file, int line, const char *fn)
438 {
439   as_show_where ();
440   fprintf (stderr, _("Internal error!\n"));
441   if (fn)
442     fprintf (stderr, _("Assertion failure in %s at %s line %d.\n"),
443              fn, file, line);
444   else
445     fprintf (stderr, _("Assertion failure at %s line %d.\n"), file, line);
446   fprintf (stderr, _("Please report this bug.\n"));
447   xexit (EXIT_FAILURE);
448 }
449
450 /* as_abort: Print a friendly message saying how totally hosed we are,
451    and exit without producing a core file.  */
452
453 void
454 as_abort (const char *file, int line, const char *fn)
455 {
456   as_show_where ();
457   if (fn)
458     fprintf (stderr, _("Internal error, aborting at %s line %d in %s\n"),
459              file, line, fn);
460   else
461     fprintf (stderr, _("Internal error, aborting at %s line %d\n"),
462              file, line);
463   fprintf (stderr, _("Please report this bug.\n"));
464   xexit (EXIT_FAILURE);
465 }
466
467 /* Support routines.  */
468
469 void
470 fprint_value (FILE *file, valueT val)
471 {
472   if (sizeof (val) <= sizeof (long))
473     {
474       fprintf (file, "%ld", (long) val);
475       return;
476     }
477 #ifdef BFD_ASSEMBLER
478   if (sizeof (val) <= sizeof (bfd_vma))
479     {
480       fprintf_vma (file, val);
481       return;
482     }
483 #endif
484   abort ();
485 }
486
487 void
488 sprint_value (char *buf, valueT val)
489 {
490   if (sizeof (val) <= sizeof (long))
491     {
492       sprintf (buf, "%ld", (long) val);
493       return;
494     }
495 #ifdef BFD_ASSEMBLER
496   if (sizeof (val) <= sizeof (bfd_vma))
497     {
498       sprintf_vma (buf, val);
499       return;
500     }
501 #endif
502   abort ();
503 }