Fri Apr 5 18:39:28 1996 James G. Smith <jsmith@cygnus.co.uk>
[platform/upstream/binutils.git] / gas / 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 #include <stdio.h>
21 #include <errno.h>
22
23 #include "as.h"
24
25 #ifndef __STDC__
26 #ifndef NO_STDARG
27 #define NO_STDARG
28 #endif
29 #endif
30
31 #ifndef NO_STDARG
32 #include <stdarg.h>
33 #else
34 #ifndef NO_VARARGS
35 #include <varargs.h>
36 #endif /* NO_VARARGS */
37 #endif /* NO_STDARG */
38
39 extern char *strerror ();
40
41 static void as_show_where PARAMS ((void));
42 static void as_warn_internal PARAMS ((char *, unsigned int, char *));
43 static void as_bad_internal PARAMS ((char *, unsigned int, char *));
44
45 /*
46  * Despite the rest of the comments in this file, (FIXME-SOON),
47  * here is the current scheme for error messages etc:
48  *
49  * as_fatal() is used when gas is quite confused and
50  * continuing the assembly is pointless.  In this case we
51  * exit immediately with error status.
52  *
53  * as_bad() is used to mark errors that result in what we
54  * presume to be a useless object file.  Say, we ignored
55  * something that might have been vital.  If we see any of
56  * these, assembly will continue to the end of the source,
57  * no object file will be produced, and we will terminate
58  * with error status.  The new option, -Z, tells us to
59  * produce an object file anyway but we still exit with
60  * error status.  The assumption here is that you don't want
61  * this object file but we could be wrong.
62  *
63  * as_warn() is used when we have an error from which we
64  * have a plausible error recovery.  eg, masking the top
65  * bits of a constant that is longer than will fit in the
66  * destination.  In this case we will continue to assemble
67  * the source, although we may have made a bad assumption,
68  * and we will produce an object file and return normal exit
69  * status (ie, no error).  The new option -X tells us to
70  * treat all as_warn() errors as as_bad() errors.  That is,
71  * no object file will be produced and we will exit with
72  * error status.  The idea here is that we don't kill an
73  * entire make because of an error that we knew how to
74  * correct.  On the other hand, sometimes you might want to
75  * stop the make at these points.
76  *
77  * as_tsktsk() is used when we see a minor error for which
78  * our error recovery action is almost certainly correct.
79  * In this case, we print a message and then assembly
80  * continues as though no error occurred.
81  */
82
83 static void
84 identify (file)
85      char *file;
86 {
87   static int identified;
88   if (identified)
89     return;
90   identified++;
91
92   if (!file)
93     {
94       unsigned int x;
95       as_where (&file, &x);
96     }
97
98   fprintf (stderr, "%s: Assembler messages:\n", file);
99 }
100
101 static int warning_count;       /* Count of number of warnings issued */
102
103 int 
104 had_warnings ()
105 {
106   return (warning_count);
107 }                               /* had_err() */
108
109 /* Nonzero if we've hit a 'bad error', and should not write an obj file,
110    and exit with a nonzero error code */
111
112 static int error_count;
113
114 int 
115 had_errors ()
116 {
117   return (error_count);
118 }                               /* had_errors() */
119
120
121 /* Print the current location to stderr.  */
122
123 static void
124 as_show_where ()
125 {
126   char *file;
127   unsigned int line;
128
129   as_where (&file, &line);
130   identify (file);
131   fprintf (stderr, "%s:%u: ", file, line);
132 }
133
134 /*
135  *                      a s _ p e r r o r
136  *
137  * Like perror(3), but with more info.
138  */
139
140 void 
141 as_perror (gripe, filename)
142      const char *gripe;         /* Unpunctuated error theme. */
143      const char *filename;
144 {
145   const char *errtxt;
146
147   as_show_where ();
148   fprintf (stderr, gripe, filename);
149 #ifdef BFD_ASSEMBLER
150   errtxt = bfd_errmsg (bfd_get_error ());
151 #else
152   errtxt = strerror (errno);
153 #endif
154   fprintf (stderr, ": %s\n", errtxt);
155   errno = 0;
156 #ifdef BFD_ASSEMBLER
157   bfd_set_error (bfd_error_no_error);
158 #endif
159 }
160
161 /*
162  *                      a s _ t s k t s k ()
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 done.
168  */
169
170 #ifndef NO_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 }                               /* as_tsktsk() */
182
183 #else
184 #ifndef NO_VARARGS
185 void 
186 as_tsktsk (format, va_alist)
187      char *format;
188      va_dcl
189 {
190   va_list args;
191
192   as_show_where ();
193   va_start (args);
194   vfprintf (stderr, format, args);
195   va_end (args);
196   (void) putc ('\n', stderr);
197 }                               /* as_tsktsk() */
198
199 #else
200 /*VARARGS1 */
201 as_tsktsk (format, args)
202      char *format;
203 {
204   as_show_where ();
205   _doprnt (format, &args, stderr);
206   (void) putc ('\n', stderr);
207 }                               /* as_tsktsk */
208
209 #endif /* not NO_VARARGS */
210 #endif /* not NO_STDARG */
211
212 /* The common portion of as_warn and as_warn_where.  */
213
214 static void
215 as_warn_internal (file, line, buffer)
216      char *file;
217      unsigned int line;
218      char *buffer;
219 {
220   ++warning_count;
221
222   if (file == NULL)
223     as_where (&file, &line);
224
225   identify (file);
226   fprintf (stderr, "%s:%u: Warning: ", file, line);
227   fputs (buffer, stderr);
228   (void) putc ('\n', stderr);
229 #ifndef NO_LISTING
230   listing_warning (buffer);
231 #endif
232 }
233
234 /*
235  *                      a s _ w a r n ()
236  *
237  * Send to stderr a string as a warning, and locate warning
238  * in input file(s).
239  * Please only use this for when we have some recovery action.
240  * Please explain in string (which may have '\n's) what recovery was done.
241  */
242
243 #ifndef NO_STDARG
244 void 
245 as_warn (const char *format,...)
246 {
247   va_list args;
248   char buffer[200];
249
250   if (!flagseen['W'])
251     {
252       va_start (args, format);
253       vsprintf (buffer, format, args);
254       va_end (args);
255       as_warn_internal ((char *) NULL, 0, buffer);
256     }
257 }                               /* as_warn() */
258
259 #else
260 #ifndef NO_VARARGS
261 void 
262 as_warn (format, va_alist)
263      char *format;
264      va_dcl
265 {
266   va_list args;
267   char buffer[200];
268
269   if (!flagseen['W'])
270     {
271       va_start (args);
272       vsprintf (buffer, format, args);
273       va_end (args);
274       as_warn_internal ((char *) NULL, 0, buffer);
275     }
276 }                               /* as_warn() */
277
278 #else
279 /*VARARGS1 */
280 as_warn (format, args)
281      char *format;
282 {
283   if (!flagseen['W'])
284     {
285       ++warning_count;
286       as_show_where ();
287       fprintf (stderr, "Warning: ");
288       _doprnt (format, &args, stderr);
289       (void) putc ('\n', stderr);
290     }
291 }                               /* as_warn() */
292
293 #endif /* not NO_VARARGS */
294 #endif /* not NO_STDARG */
295
296 /* as_warn_where, like as_bad but the file name and line number are
297    passed in.  Unfortunately, we have to repeat the function in order
298    to handle the varargs correctly and portably.  */
299
300 #ifndef NO_STDARG
301 void 
302 as_warn_where (char *file, unsigned int line, const char *format,...)
303 {
304   va_list args;
305   char buffer[200];
306
307   if (!flagseen['W'])
308     {
309       va_start (args, format);
310       vsprintf (buffer, format, args);
311       va_end (args);
312       as_warn_internal (file, line, buffer);
313     }
314 }                               /* as_warn() */
315
316 #else
317 #ifndef NO_VARARGS
318 void 
319 as_warn_where (file, line, format, va_alist)
320      char *file;
321      unsigned int line;
322      char *format;
323      va_dcl
324 {
325   va_list args;
326   char buffer[200];
327
328   if (!flagseen['W'])
329     {
330       va_start (args);
331       vsprintf (buffer, format, args);
332       va_end (args);
333       as_warn_internal (file, line, buffer);
334     }
335 }                               /* as_warn() */
336
337 #else
338 /*VARARGS1 */
339 as_warn_where (file, line, format, args)
340      char *file;
341      unsigned int line;
342      char *format;
343 {
344   if (!flagseen['W'])
345     {
346       ++warning_count;
347       identify (file);
348       fprintf (stderr, "%s:%u: Warning: ", file, line);
349       _doprnt (format, &args, stderr);
350       (void) putc ('\n', stderr);
351     }
352 }                               /* as_warn() */
353
354 #endif /* not NO_VARARGS */
355 #endif /* not NO_STDARG */
356
357 /* The common portion of as_bad and as_bad_where.  */
358
359 static void
360 as_bad_internal (file, line, buffer)
361      char *file;
362      unsigned int line;
363      char *buffer;
364 {
365   ++error_count;
366
367   if (file == NULL)
368     as_where (&file, &line);
369
370   identify (file);
371   fprintf (stderr, "%s:%u: Error: ", file, line);
372   fputs (buffer, stderr);
373   (void) putc ('\n', stderr);
374 #ifndef NO_LISTING
375   listing_error (buffer);
376 #endif
377 }
378
379 /*
380  *                      a s _ b a d ()
381  *
382  * Send to stderr a string as a warning, and locate warning in input file(s).
383  * Please us when there is no recovery, but we want to continue processing
384  * but not produce an object file.
385  * Please explain in string (which may have '\n's) what recovery was done.
386  */
387
388 #ifndef NO_STDARG
389 void 
390 as_bad (const char *format,...)
391 {
392   va_list args;
393   char buffer[200];
394
395   va_start (args, format);
396   vsprintf (buffer, format, args);
397   va_end (args);
398
399   as_bad_internal ((char *) NULL, 0, buffer);
400 }
401
402 #else
403 #ifndef NO_VARARGS
404 void 
405 as_bad (format, va_alist)
406      char *format;
407      va_dcl
408 {
409   va_list args;
410   char buffer[200];
411
412   va_start (args);
413   vsprintf (buffer, format, args);
414   va_end (args);
415
416   as_bad_internal ((char *) NULL, 0, buffer);
417 }
418
419 #else
420 /*VARARGS1 */
421 as_bad (format, args)
422      char *format;
423 {
424   ++error_count;
425
426   as_show_where ();
427   fprintf (stderr, "Error: ");
428   _doprnt (format, &args, stderr);
429   (void) putc ('\n', stderr);
430 }                               /* as_bad() */
431
432 #endif /* not NO_VARARGS */
433 #endif /* not NO_STDARG */
434
435 /* as_bad_where, like as_bad but the file name and line number are
436    passed in.  Unfortunately, we have to repeat the function in order
437    to handle the varargs correctly and portably.  */
438
439 #ifndef NO_STDARG
440 void 
441 as_bad_where (char *file, unsigned int line, const char *format,...)
442 {
443   va_list args;
444   char buffer[200];
445
446   va_start (args, format);
447   vsprintf (buffer, format, args);
448   va_end (args);
449
450   as_bad_internal (file, line, buffer);
451 }
452
453 #else
454 #ifndef NO_VARARGS
455 void 
456 as_bad_where (file, line, format, va_alist)
457      char *file;
458      unsigned int line;
459      char *format;
460      va_dcl
461 {
462   va_list args;
463   char buffer[200];
464
465   va_start (args);
466   vsprintf (buffer, format, args);
467   va_end (args);
468
469   as_bad_internal (file, line, buffer);
470 }
471
472 #else
473 /*VARARGS1 */
474 as_bad_where (file, line, format, args)
475      char *file;
476      unsigned int line;
477      char *format;
478 {
479   ++error_count;
480
481   identify (file);
482   fprintf (stderr, "%s:%u: Error: ", file, line);
483   _doprnt (format, &args, stderr);
484   (void) putc ('\n', stderr);
485 }                               /* as_bad() */
486
487 #endif /* not NO_VARARGS */
488 #endif /* not NO_STDARG */
489
490 /*
491  *                      a s _ f a t a l ()
492  *
493  * Send to stderr a string as a fatal message, and print location of error in
494  * input file(s).
495  * Please only use this for when we DON'T have some recovery action.
496  * It exit()s with a warning status.
497  */
498
499 #ifndef NO_STDARG
500 void 
501 as_fatal (const char *format,...)
502 {
503   va_list args;
504
505   as_show_where ();
506   va_start (args, format);
507   fprintf (stderr, "Fatal error:");
508   vfprintf (stderr, format, args);
509   (void) putc ('\n', stderr);
510   va_end (args);
511   exit (33);
512 }                               /* as_fatal() */
513
514 #else
515 #ifndef NO_VARARGS
516 void 
517 as_fatal (format, va_alist)
518      char *format;
519      va_dcl
520 {
521   va_list args;
522
523   as_show_where ();
524   va_start (args);
525   fprintf (stderr, "Fatal error:");
526   vfprintf (stderr, format, args);
527   (void) putc ('\n', stderr);
528   va_end (args);
529   exit (33);
530 }                               /* as_fatal() */
531
532 #else
533 /*VARARGS1 */
534 as_fatal (format, args)
535      char *format;
536 {
537   as_show_where ();
538   fprintf (stderr, "Fatal error:");
539   _doprnt (format, &args, stderr);
540   (void) putc ('\n', stderr);
541   exit (33);                    /* What is a good exit status? */
542 }                               /* as_fatal() */
543
544 #endif /* not NO_VARARGS */
545 #endif /* not NO_STDARG */
546
547 void
548 fprint_value (file, val)
549      FILE *file;
550      valueT val;
551 {
552   if (sizeof (val) <= sizeof (long))
553     {
554       fprintf (file, "%ld", val);
555       return;
556     }
557 #ifdef BFD_ASSEMBLER
558   if (sizeof (val) <= sizeof (bfd_vma))
559     {
560       fprintf_vma (file, val);
561       return;
562     }
563 #endif
564   abort ();
565 }
566
567 void
568 sprint_value (buf, val)
569      char *buf;
570      valueT val;
571 {
572   if (sizeof (val) <= sizeof (long))
573     {
574       sprintf (buf, "%ld", val);
575       return;
576     }
577 #ifdef BFD_ASSEMBLER
578   if (sizeof (val) <= sizeof (bfd_vma))
579     {
580       sprintf_vma (buf, val);
581       return;
582     }
583 #endif
584   abort ();
585 }
586
587 /* end of messages.c */