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