xref: /openbsd/gnu/usr.bin/binutils/gas/messages.c (revision 007c2a45)
1 /* messages.c - error reporter -
2    Copyright 1987, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 2000, 2001, 2003
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 static void
identify(char * file)87 identify (char *file)
88 {
89   static int identified;
90 
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
had_warnings(void)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
had_errors(void)121 had_errors (void)
122 {
123   return error_count;
124 }
125 
126 /* Print the current location to stderr.  */
127 
128 static void
as_show_where(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
as_perror(const char * gripe,const char * filename)143 as_perror (const char *gripe,		/* Unpunctuated error theme.  */
144 	   const char *filename)
145 {
146   const char *errtxt;
147   int saved_errno = errno;
148 
149   as_show_where ();
150   fprintf (stderr, gripe, filename);
151   errno = saved_errno;
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
as_tsktsk(const char * format,...)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
as_tsktsk(format,va_alist)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
as_warn_internal(char * file,unsigned int line,char * buffer)201 as_warn_internal (char *file, unsigned int line, char *buffer)
202 {
203   ++warning_count;
204 
205   if (file == NULL)
206     as_where (&file, &line);
207 
208   identify (file);
209   if (file)
210     fprintf (stderr, "%s:%u: ", file, line);
211   fprintf (stderr, _("Warning: "));
212   fputs (buffer, stderr);
213   (void) putc ('\n', stderr);
214 #ifndef NO_LISTING
215   listing_warning (buffer);
216 #endif
217 }
218 
219 /* Send to stderr a string as a warning, and locate warning
220    in input file(s).
221    Please only use this for when we have some recovery action.
222    Please explain in string (which may have '\n's) what recovery was
223    done.  */
224 
225 #ifdef USE_STDARG
226 void
as_warn(const char * format,...)227 as_warn (const char *format, ...)
228 {
229   va_list args;
230   char buffer[2000];
231 
232   if (!flag_no_warnings)
233     {
234       va_start (args, format);
235       vsprintf (buffer, format, args);
236       va_end (args);
237       as_warn_internal ((char *) NULL, 0, buffer);
238     }
239 }
240 #else
241 void
as_warn(format,va_alist)242 as_warn (format, va_alist)
243      const char *format;
244      va_dcl
245 {
246   va_list args;
247   char buffer[2000];
248 
249   if (!flag_no_warnings)
250     {
251       va_start (args);
252       vsprintf (buffer, format, args);
253       va_end (args);
254       as_warn_internal ((char *) NULL, 0, buffer);
255     }
256 }
257 #endif /* not NO_STDARG */
258 
259 /* Like as_bad but the file name and line number are passed in.
260    Unfortunately, we have to repeat the function in order to handle
261    the varargs correctly and portably.  */
262 
263 #ifdef USE_STDARG
264 void
as_warn_where(char * file,unsigned int line,const char * format,...)265 as_warn_where (char *file, unsigned int line, const char *format, ...)
266 {
267   va_list args;
268   char buffer[2000];
269 
270   if (!flag_no_warnings)
271     {
272       va_start (args, format);
273       vsprintf (buffer, format, args);
274       va_end (args);
275       as_warn_internal (file, line, buffer);
276     }
277 }
278 #else
279 void
as_warn_where(file,line,format,va_alist)280 as_warn_where (file, line, format, va_alist)
281      char *file;
282      unsigned int line;
283      const char *format;
284      va_dcl
285 {
286   va_list args;
287   char buffer[2000];
288 
289   if (!flag_no_warnings)
290     {
291       va_start (args);
292       vsprintf (buffer, format, args);
293       va_end (args);
294       as_warn_internal (file, line, buffer);
295     }
296 }
297 #endif /* not NO_STDARG */
298 
299 /* The common portion of as_bad and as_bad_where.  */
300 
301 static void
as_bad_internal(char * file,unsigned int line,char * buffer)302 as_bad_internal (char *file, unsigned int line, char *buffer)
303 {
304   ++error_count;
305 
306   if (file == NULL)
307     as_where (&file, &line);
308 
309   identify (file);
310   if (file)
311     fprintf (stderr, "%s:%u: ", file, line);
312   fprintf (stderr, _("Error: "));
313   fputs (buffer, stderr);
314   (void) putc ('\n', stderr);
315 #ifndef NO_LISTING
316   listing_error (buffer);
317 #endif
318 }
319 
320 /* Send to stderr a string as a warning, and locate warning in input
321    file(s).  Please us when there is no recovery, but we want to
322    continue processing but not produce an object file.
323    Please explain in string (which may have '\n's) what recovery was
324    done.  */
325 
326 #ifdef USE_STDARG
327 void
as_bad(const char * format,...)328 as_bad (const char *format, ...)
329 {
330   va_list args;
331   char buffer[2000];
332 
333   va_start (args, format);
334   vsprintf (buffer, format, args);
335   va_end (args);
336 
337   as_bad_internal ((char *) NULL, 0, buffer);
338 }
339 
340 #else
341 void
as_bad(format,va_alist)342 as_bad (format, va_alist)
343      const char *format;
344      va_dcl
345 {
346   va_list args;
347   char buffer[2000];
348 
349   va_start (args);
350   vsprintf (buffer, format, args);
351   va_end (args);
352 
353   as_bad_internal ((char *) NULL, 0, buffer);
354 }
355 #endif /* not NO_STDARG */
356 
357 /* Like as_bad but the file name and line number are passed in.
358    Unfortunately, we have to repeat the function in order to handle
359    the varargs correctly and portably.  */
360 
361 #ifdef USE_STDARG
362 void
as_bad_where(char * file,unsigned int line,const char * format,...)363 as_bad_where (char *file, unsigned int line, const char *format, ...)
364 {
365   va_list args;
366   char buffer[2000];
367 
368   va_start (args, format);
369   vsprintf (buffer, format, args);
370   va_end (args);
371 
372   as_bad_internal (file, line, buffer);
373 }
374 
375 #else
376 void
as_bad_where(file,line,format,va_alist)377 as_bad_where (file, line, format, va_alist)
378      char *file;
379      unsigned int line;
380      const char *format;
381      va_dcl
382 {
383   va_list args;
384   char buffer[2000];
385 
386   va_start (args);
387   vsprintf (buffer, format, args);
388   va_end (args);
389 
390   as_bad_internal (file, line, buffer);
391 }
392 #endif /* not NO_STDARG */
393 
394 /* Send to stderr a string as a fatal message, and print location of
395    error in input file(s).
396    Please only use this for when we DON'T have some recovery action.
397    It xexit()s with a warning status.  */
398 
399 #ifdef USE_STDARG
400 void
as_fatal(const char * format,...)401 as_fatal (const char *format, ...)
402 {
403   va_list args;
404 
405   as_show_where ();
406   va_start (args, format);
407   fprintf (stderr, _("Fatal error: "));
408   vfprintf (stderr, format, args);
409   (void) putc ('\n', stderr);
410   va_end (args);
411   /* Delete the output file, if it exists.  This will prevent make from
412      thinking that a file was created and hence does not need rebuilding.  */
413   if (out_file_name != NULL)
414     unlink (out_file_name);
415   xexit (EXIT_FAILURE);
416 }
417 #else
418 void
as_fatal(format,va_alist)419 as_fatal (format, va_alist)
420      char *format;
421      va_dcl
422 {
423   va_list args;
424 
425   as_show_where ();
426   va_start (args);
427   fprintf (stderr, _("Fatal error: "));
428   vfprintf (stderr, format, args);
429   (void) putc ('\n', stderr);
430   va_end (args);
431   xexit (EXIT_FAILURE);
432 }
433 #endif /* not NO_STDARG */
434 
435 /* Indicate assertion failure.
436    Arguments: Filename, line number, optional function name.  */
437 
438 void
as_assert(const char * file,int line,const char * fn)439 as_assert (const char *file, int line, const char *fn)
440 {
441   as_show_where ();
442   fprintf (stderr, _("Internal error!\n"));
443   if (fn)
444     fprintf (stderr, _("Assertion failure in %s at %s line %d.\n"),
445 	     fn, file, line);
446   else
447     fprintf (stderr, _("Assertion failure at %s line %d.\n"), file, line);
448   fprintf (stderr, _("Please report this bug.\n"));
449   xexit (EXIT_FAILURE);
450 }
451 
452 /* as_abort: Print a friendly message saying how totally hosed we are,
453    and exit without producing a core file.  */
454 
455 void
as_abort(const char * file,int line,const char * fn)456 as_abort (const char *file, int line, const char *fn)
457 {
458   as_show_where ();
459   if (fn)
460     fprintf (stderr, _("Internal error, aborting at %s line %d in %s\n"),
461 	     file, line, fn);
462   else
463     fprintf (stderr, _("Internal error, aborting at %s line %d\n"),
464 	     file, line);
465   fprintf (stderr, _("Please report this bug.\n"));
466   xexit (EXIT_FAILURE);
467 }
468 
469 /* Support routines.  */
470 
471 void
fprint_value(FILE * file,valueT val)472 fprint_value (FILE *file, valueT val)
473 {
474   if (sizeof (val) <= sizeof (long))
475     {
476       fprintf (file, "%ld", (long) val);
477       return;
478     }
479 #ifdef BFD_ASSEMBLER
480   if (sizeof (val) <= sizeof (bfd_vma))
481     {
482       fprintf_vma (file, val);
483       return;
484     }
485 #endif
486   abort ();
487 }
488 
489 void
sprint_value(char * buf,valueT val)490 sprint_value (char *buf, valueT val)
491 {
492   if (sizeof (val) <= sizeof (long))
493     {
494       sprintf (buf, "%ld", (long) val);
495       return;
496     }
497 #ifdef BFD_ASSEMBLER
498   if (sizeof (val) <= sizeof (bfd_vma))
499     {
500       sprintf_vma (buf, val);
501       return;
502     }
503 #endif
504   abort ();
505 }
506