Merge from vendor branch GCC:
[dragonfly.git] / contrib / binutils-2.14 / 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 PARAMS ((char *));
46 static void as_show_where PARAMS ((void));
47 static void as_warn_internal PARAMS ((char *, unsigned int, char *));
48 static void as_bad_internal PARAMS ((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 (file)
89      char *file;
90 {
91   static int identified;
92   if (identified)
93     return;
94   identified++;
95
96   if (!file)
97     {
98       unsigned int x;
99       as_where (&file, &x);
100     }
101
102   if (file)
103     fprintf (stderr, "%s: ", file);
104   fprintf (stderr, _("Assembler messages:\n"));
105 }
106
107 /* The number of warnings issued.  */
108 static int warning_count;
109
110 int
111 had_warnings ()
112 {
113   return (warning_count);
114 }
115
116 /* Nonzero if we've hit a 'bad error', and should not write an obj file,
117    and exit with a nonzero error code.  */
118
119 static int error_count;
120
121 int
122 had_errors ()
123 {
124   return (error_count);
125 }
126
127 /* Print the current location to stderr.  */
128
129 static void
130 as_show_where ()
131 {
132   char *file;
133   unsigned int line;
134
135   as_where (&file, &line);
136   identify (file);
137   if (file)
138     fprintf (stderr, "%s:%u: ", file, line);
139 }
140
141 /* Like perror(3), but with more info.  */
142
143 void
144 as_perror (gripe, filename)
145      const char *gripe;         /* Unpunctuated error theme.  */
146      const char *filename;
147 {
148   const char *errtxt;
149
150   as_show_where ();
151   fprintf (stderr, gripe, filename);
152 #ifdef BFD_ASSEMBLER
153   errtxt = bfd_errmsg (bfd_get_error ());
154 #else
155   errtxt = xstrerror (errno);
156 #endif
157   fprintf (stderr, ": %s\n", errtxt);
158   errno = 0;
159 #ifdef BFD_ASSEMBLER
160   bfd_set_error (bfd_error_no_error);
161 #endif
162 }
163
164 /* Send to stderr a string as a warning, and locate warning
165    in input file(s).
166    Please only use this for when we have some recovery action.
167    Please explain in string (which may have '\n's) what recovery was
168    done.  */
169
170 #ifdef USE_STDARG
171 void
172 as_tsktsk (const char *format, ...)
173 {
174   va_list args;
175
176   as_show_where ();
177   va_start (args, format);
178   vfprintf (stderr, format, args);
179   va_end (args);
180   (void) putc ('\n', stderr);
181 }
182 #else
183 void
184 as_tsktsk (format, va_alist)
185      const char *format;
186      va_dcl
187 {
188   va_list args;
189
190   as_show_where ();
191   va_start (args);
192   vfprintf (stderr, format, args);
193   va_end (args);
194   (void) putc ('\n', stderr);
195 }
196 #endif /* not NO_STDARG */
197
198 /* The common portion of as_warn and as_warn_where.  */
199
200 static void
201 as_warn_internal (file, line, buffer)
202      char *file;
203      unsigned int line;
204      char *buffer;
205 {
206   ++warning_count;
207
208   if (file == NULL)
209     as_where (&file, &line);
210
211   identify (file);
212   if (file)
213     fprintf (stderr, "%s:%u: ", file, line);
214   fprintf (stderr, _("Warning: "));
215   fputs (buffer, stderr);
216   (void) putc ('\n', stderr);
217 #ifndef NO_LISTING
218   listing_warning (buffer);
219 #endif
220 }
221
222 /* Send to stderr a string as a warning, and locate warning
223    in input file(s).
224    Please only use this for when we have some recovery action.
225    Please explain in string (which may have '\n's) what recovery was
226    done.  */
227
228 #ifdef USE_STDARG
229 void
230 as_warn (const char *format, ...)
231 {
232   va_list args;
233   char buffer[2000];
234
235   if (!flag_no_warnings)
236     {
237       va_start (args, format);
238       vsprintf (buffer, format, args);
239       va_end (args);
240       as_warn_internal ((char *) NULL, 0, buffer);
241     }
242 }
243 #else
244 void
245 as_warn (format, va_alist)
246      const char *format;
247      va_dcl
248 {
249   va_list args;
250   char buffer[2000];
251
252   if (!flag_no_warnings)
253     {
254       va_start (args);
255       vsprintf (buffer, format, args);
256       va_end (args);
257       as_warn_internal ((char *) NULL, 0, buffer);
258     }
259 }
260 #endif /* not NO_STDARG */
261
262 /* Like as_bad but the file name and line number are passed in.
263    Unfortunately, we have to repeat the function in order to handle
264    the varargs correctly and portably.  */
265
266 #ifdef USE_STDARG
267 void
268 as_warn_where (char *file, unsigned int line, const char *format, ...)
269 {
270   va_list args;
271   char buffer[2000];
272
273   if (!flag_no_warnings)
274     {
275       va_start (args, format);
276       vsprintf (buffer, format, args);
277       va_end (args);
278       as_warn_internal (file, line, buffer);
279     }
280 }
281 #else
282 void
283 as_warn_where (file, line, format, va_alist)
284      char *file;
285      unsigned int line;
286      const char *format;
287      va_dcl
288 {
289   va_list args;
290   char buffer[2000];
291
292   if (!flag_no_warnings)
293     {
294       va_start (args);
295       vsprintf (buffer, format, args);
296       va_end (args);
297       as_warn_internal (file, line, buffer);
298     }
299 }
300 #endif /* not NO_STDARG */
301
302 /* The common portion of as_bad and as_bad_where.  */
303
304 static void
305 as_bad_internal (file, line, buffer)
306      char *file;
307      unsigned int line;
308      char *buffer;
309 {
310   ++error_count;
311
312   if (file == NULL)
313     as_where (&file, &line);
314
315   identify (file);
316   if (file)
317     fprintf (stderr, "%s:%u: ", file, line);
318   fprintf (stderr, _("Error: "));
319   fputs (buffer, stderr);
320   (void) putc ('\n', stderr);
321 #ifndef NO_LISTING
322   listing_error (buffer);
323 #endif
324 }
325
326 /* Send to stderr a string as a warning, and locate warning in input
327    file(s).  Please us when there is no recovery, but we want to
328    continue processing but not produce an object file.
329    Please explain in string (which may have '\n's) what recovery was
330    done.  */
331
332 #ifdef USE_STDARG
333 void
334 as_bad (const char *format, ...)
335 {
336   va_list args;
337   char buffer[2000];
338
339   va_start (args, format);
340   vsprintf (buffer, format, args);
341   va_end (args);
342
343   as_bad_internal ((char *) NULL, 0, buffer);
344 }
345
346 #else
347 void
348 as_bad (format, va_alist)
349      const char *format;
350      va_dcl
351 {
352   va_list args;
353   char buffer[2000];
354
355   va_start (args);
356   vsprintf (buffer, format, args);
357   va_end (args);
358
359   as_bad_internal ((char *) NULL, 0, buffer);
360 }
361 #endif /* not NO_STDARG */
362
363 /* Like as_bad but the file name and line number are passed in.
364    Unfortunately, we have to repeat the function in order to handle
365    the varargs correctly and portably.  */
366
367 #ifdef USE_STDARG
368 void
369 as_bad_where (char *file, unsigned int line, const char *format, ...)
370 {
371   va_list args;
372   char buffer[2000];
373
374   va_start (args, format);
375   vsprintf (buffer, format, args);
376   va_end (args);
377
378   as_bad_internal (file, line, buffer);
379 }
380
381 #else
382 void
383 as_bad_where (file, line, format, va_alist)
384      char *file;
385      unsigned int line;
386      const char *format;
387      va_dcl
388 {
389   va_list args;
390   char buffer[2000];
391
392   va_start (args);
393   vsprintf (buffer, format, args);
394   va_end (args);
395
396   as_bad_internal (file, line, buffer);
397 }
398 #endif /* not NO_STDARG */
399
400 /* Send to stderr a string as a fatal message, and print location of
401    error in input file(s).
402    Please only use this for when we DON'T have some recovery action.
403    It xexit()s with a warning status.  */
404
405 #ifdef USE_STDARG
406 void
407 as_fatal (const char *format, ...)
408 {
409   va_list args;
410
411   as_show_where ();
412   va_start (args, format);
413   fprintf (stderr, _("Fatal error: "));
414   vfprintf (stderr, format, args);
415   (void) putc ('\n', stderr);
416   va_end (args);
417   /* Delete the output file, if it exists.  This will prevent make from
418      thinking that a file was created and hence does not need rebuilding.  */
419   if (out_file_name != NULL)
420     unlink (out_file_name);
421   xexit (EXIT_FAILURE);
422 }
423 #else
424 void
425 as_fatal (format, va_alist)
426      char *format;
427      va_dcl
428 {
429   va_list args;
430
431   as_show_where ();
432   va_start (args);
433   fprintf (stderr, _("Fatal error: "));
434   vfprintf (stderr, format, args);
435   (void) putc ('\n', stderr);
436   va_end (args);
437   xexit (EXIT_FAILURE);
438 }
439 #endif /* not NO_STDARG */
440
441 /* Indicate assertion failure.
442    Arguments: Filename, line number, optional function name.  */
443
444 void
445 as_assert (file, line, fn)
446      const char *file, *fn;
447      int line;
448 {
449   as_show_where ();
450   fprintf (stderr, _("Internal error!\n"));
451   if (fn)
452     fprintf (stderr, _("Assertion failure in %s at %s line %d.\n"),
453              fn, file, line);
454   else
455     fprintf (stderr, _("Assertion failure at %s line %d.\n"), file, line);
456   fprintf (stderr, _("Please report this bug.\n"));
457   xexit (EXIT_FAILURE);
458 }
459
460 /* as_abort: Print a friendly message saying how totally hosed we are,
461    and exit without producing a core file.  */
462
463 void
464 as_abort (file, line, fn)
465      const char *file, *fn;
466      int line;
467 {
468   as_show_where ();
469   if (fn)
470     fprintf (stderr, _("Internal error, aborting at %s line %d in %s\n"),
471              file, line, fn);
472   else
473     fprintf (stderr, _("Internal error, aborting at %s line %d\n"),
474              file, line);
475   fprintf (stderr, _("Please report this bug.\n"));
476   xexit (EXIT_FAILURE);
477 }
478
479 /* Support routines.  */
480
481 void
482 fprint_value (file, val)
483      FILE *file;
484      valueT val;
485 {
486   if (sizeof (val) <= sizeof (long))
487     {
488       fprintf (file, "%ld", (long) val);
489       return;
490     }
491 #ifdef BFD_ASSEMBLER
492   if (sizeof (val) <= sizeof (bfd_vma))
493     {
494       fprintf_vma (file, val);
495       return;
496     }
497 #endif
498   abort ();
499 }
500
501 void
502 sprint_value (buf, val)
503      char *buf;
504      valueT val;
505 {
506   if (sizeof (val) <= sizeof (long))
507     {
508       sprintf (buf, "%ld", (long) val);
509       return;
510     }
511 #ifdef BFD_ASSEMBLER
512   if (sizeof (val) <= sizeof (bfd_vma))
513     {
514       sprintf_vma (buf, val);
515       return;
516     }
517 #endif
518   abort ();
519 }