Merge branch 'vendor/DIFFUTILS'
[dragonfly.git] / contrib / binutils-2.27 / gas / messages.c
1 /* messages.c - error reporter -
2    Copyright (C) 1987-2016 Free Software Foundation, Inc.
3    This file is part of GAS, the GNU Assembler.
4
5    GAS is free software; you can redistribute it and/or modify
6    it under the terms of the GNU General Public License as published by
7    the Free Software Foundation; either version 3, or (at your option)
8    any later version.
9
10    GAS is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13    GNU General Public License for more details.
14
15    You should have received a copy of the GNU General Public License
16    along with GAS; see the file COPYING.  If not, write to the Free
17    Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
18    02110-1301, USA.  */
19
20 #include "as.h"
21
22 static void identify (const char *);
23 static void as_show_where (void);
24 static void as_warn_internal (const char *, unsigned int, char *);
25 static void as_bad_internal (const char *, unsigned int, char *);
26
27 /* Despite the rest of the comments in this file, (FIXME-SOON),
28    here is the current scheme for error messages etc:
29
30    as_fatal() is used when gas is quite confused and
31    continuing the assembly is pointless.  In this case we
32    exit immediately with error status.
33
34    as_bad() is used to mark errors that result in what we
35    presume to be a useless object file.  Say, we ignored
36    something that might have been vital.  If we see any of
37    these, assembly will continue to the end of the source,
38    no object file will be produced, and we will terminate
39    with error status.  The new option, -Z, tells us to
40    produce an object file anyway but we still exit with
41    error status.  The assumption here is that you don't want
42    this object file but we could be wrong.
43
44    as_warn() is used when we have an error from which we
45    have a plausible error recovery.  eg, masking the top
46    bits of a constant that is longer than will fit in the
47    destination.  In this case we will continue to assemble
48    the source, although we may have made a bad assumption,
49    and we will produce an object file and return normal exit
50    status (ie, no error).  The new option -X tells us to
51    treat all as_warn() errors as as_bad() errors.  That is,
52    no object file will be produced and we will exit with
53    error status.  The idea here is that we don't kill an
54    entire make because of an error that we knew how to
55    correct.  On the other hand, sometimes you might want to
56    stop the make at these points.
57
58    as_tsktsk() is used when we see a minor error for which
59    our error recovery action is almost certainly correct.
60    In this case, we print a message and then assembly
61    continues as though no error occurred.  */
62
63 static void
64 identify (const char *file)
65 {
66   static int identified;
67
68   if (identified)
69     return;
70   identified++;
71
72   if (!file)
73     {
74       unsigned int x;
75       file = as_where (&x);
76     }
77
78   if (file)
79     fprintf (stderr, "%s: ", file);
80   fprintf (stderr, _("Assembler messages:\n"));
81 }
82
83 /* The number of warnings issued.  */
84 static int warning_count;
85
86 int
87 had_warnings (void)
88 {
89   return warning_count;
90 }
91
92 /* Nonzero if we've hit a 'bad error', and should not write an obj file,
93    and exit with a nonzero error code.  */
94
95 static int error_count;
96
97 int
98 had_errors (void)
99 {
100   return error_count;
101 }
102
103 /* Print the current location to stderr.  */
104
105 static void
106 as_show_where (void)
107 {
108   const char *file;
109   unsigned int line;
110
111   file = as_where (&line);
112   identify (file);
113   if (file)
114     {
115       if (line != 0)
116         fprintf (stderr, "%s:%u: ", file, line);
117       else
118         fprintf (stderr, "%s: ", file);
119     }
120 }
121
122 /* Send to stderr a string as a warning, and locate warning
123    in input file(s).
124    Please only use this for when we have some recovery action.
125    Please explain in string (which may have '\n's) what recovery was
126    done.  */
127
128 void
129 as_tsktsk (const char *format, ...)
130 {
131   va_list args;
132
133   as_show_where ();
134   va_start (args, format);
135   vfprintf (stderr, format, args);
136   va_end (args);
137   (void) putc ('\n', stderr);
138 }
139
140 /* The common portion of as_warn and as_warn_where.  */
141
142 static void
143 as_warn_internal (const char *file, unsigned int line, char *buffer)
144 {
145   ++warning_count;
146
147   if (file == NULL)
148     file = as_where (&line);
149
150   identify (file);
151   if (file)
152     {
153       if (line != 0)
154         fprintf (stderr, "%s:%u: %s%s\n", file, line, _("Warning: "), buffer);
155       else
156         fprintf (stderr, "%s: %s%s\n", file, _("Warning: "), buffer);
157     }
158   else
159     fprintf (stderr, "%s%s\n", _("Warning: "), buffer);
160 #ifndef NO_LISTING
161   listing_warning (buffer);
162 #endif
163 }
164
165 /* Send to stderr a string as a warning, and locate warning
166    in input file(s).
167    Please only use this for when we have some recovery action.
168    Please explain in string (which may have '\n's) what recovery was
169    done.  */
170
171 void
172 as_warn (const char *format, ...)
173 {
174   va_list args;
175   char buffer[2000];
176
177   if (!flag_no_warnings)
178     {
179       va_start (args, format);
180       vsnprintf (buffer, sizeof (buffer), format, args);
181       va_end (args);
182       as_warn_internal ((char *) NULL, 0, buffer);
183     }
184 }
185
186 /* Like as_bad but the file name and line number are passed in.
187    Unfortunately, we have to repeat the function in order to handle
188    the varargs correctly and portably.  */
189
190 void
191 as_warn_where (const char *file, unsigned int line, const char *format, ...)
192 {
193   va_list args;
194   char buffer[2000];
195
196   if (!flag_no_warnings)
197     {
198       va_start (args, format);
199       vsnprintf (buffer, sizeof (buffer), format, args);
200       va_end (args);
201       as_warn_internal (file, line, buffer);
202     }
203 }
204
205 /* The common portion of as_bad and as_bad_where.  */
206
207 static void
208 as_bad_internal (const char *file, unsigned int line, char *buffer)
209 {
210   ++error_count;
211
212   if (file == NULL)
213     file = as_where (&line);
214
215   identify (file);
216   if (file)
217     {
218       if (line != 0)
219         fprintf (stderr, "%s:%u: %s%s\n", file, line, _("Error: "), buffer);
220       else
221         fprintf (stderr, "%s: %s%s\n", file, _("Error: "), buffer);
222     }
223   else
224     fprintf (stderr, "%s%s\n", _("Error: "), buffer);
225 #ifndef NO_LISTING
226   listing_error (buffer);
227 #endif
228 }
229
230 /* Send to stderr a string as a warning, and locate warning in input
231    file(s).  Please use when there is no recovery, but we want to
232    continue processing but not produce an object file.
233    Please explain in string (which may have '\n's) what recovery was
234    done.  */
235
236 void
237 as_bad (const char *format, ...)
238 {
239   va_list args;
240   char buffer[2000];
241
242   va_start (args, format);
243   vsnprintf (buffer, sizeof (buffer), format, args);
244   va_end (args);
245
246   as_bad_internal ((char *) NULL, 0, buffer);
247 }
248
249 /* Like as_bad but the file name and line number are passed in.
250    Unfortunately, we have to repeat the function in order to handle
251    the varargs correctly and portably.  */
252
253 void
254 as_bad_where (const char *file, unsigned int line, const char *format, ...)
255 {
256   va_list args;
257   char buffer[2000];
258
259   va_start (args, format);
260   vsnprintf (buffer, sizeof (buffer), format, args);
261   va_end (args);
262
263   as_bad_internal (file, line, buffer);
264 }
265
266 /* Send to stderr a string as a fatal message, and print location of
267    error in input file(s).
268    Please only use this for when we DON'T have some recovery action.
269    It xexit()s with a warning status.  */
270
271 void
272 as_fatal (const char *format, ...)
273 {
274   va_list args;
275
276   as_show_where ();
277   va_start (args, format);
278   fprintf (stderr, _("Fatal error: "));
279   vfprintf (stderr, format, args);
280   (void) putc ('\n', stderr);
281   va_end (args);
282   /* Delete the output file, if it exists.  This will prevent make from
283      thinking that a file was created and hence does not need rebuilding.  */
284   if (out_file_name != NULL)
285     unlink_if_ordinary (out_file_name);
286   xexit (EXIT_FAILURE);
287 }
288
289 /* Indicate assertion failure.
290    Arguments: Filename, line number, optional function name.  */
291
292 void
293 as_assert (const char *file, int line, const char *fn)
294 {
295   as_show_where ();
296   fprintf (stderr, _("Internal error!\n"));
297   if (fn)
298     fprintf (stderr, _("Assertion failure in %s at %s:%d.\n"),
299              fn, file, line);
300   else
301     fprintf (stderr, _("Assertion failure at %s:%d.\n"), file, line);
302   fprintf (stderr, _("Please report this bug.\n"));
303   xexit (EXIT_FAILURE);
304 }
305
306 /* as_abort: Print a friendly message saying how totally hosed we are,
307    and exit without producing a core file.  */
308
309 void
310 as_abort (const char *file, int line, const char *fn)
311 {
312   as_show_where ();
313   if (fn)
314     fprintf (stderr, _("Internal error, aborting at %s:%d in %s\n"),
315              file, line, fn);
316   else
317     fprintf (stderr, _("Internal error, aborting at %s:%d\n"),
318              file, line);
319   fprintf (stderr, _("Please report this bug.\n"));
320   xexit (EXIT_FAILURE);
321 }
322
323 /* Support routines.  */
324
325 void
326 sprint_value (char *buf, valueT val)
327 {
328   if (sizeof (val) <= sizeof (long))
329     {
330       sprintf (buf, "%ld", (long) val);
331       return;
332     }
333   if (sizeof (val) <= sizeof (bfd_vma))
334     {
335       sprintf_vma (buf, val);
336       return;
337     }
338   abort ();
339 }
340
341 #define HEX_MAX_THRESHOLD       1024
342 #define HEX_MIN_THRESHOLD       -(HEX_MAX_THRESHOLD)
343
344 static void
345 as_internal_value_out_of_range (const char *prefix,
346                                 offsetT val,
347                                 offsetT min,
348                                 offsetT max,
349                                 const char *file,
350                                 unsigned line,
351                                 int bad)
352 {
353   const char * err;
354
355   if (prefix == NULL)
356     prefix = "";
357
358   if (val >= min && val <= max)
359     {
360       addressT right = max & -max;
361
362       if (max <= 1)
363         abort ();
364
365       /* xgettext:c-format  */
366       err = _("%s out of domain (%d is not a multiple of %d)");
367       if (bad)
368         as_bad_where (file, line, err,
369                       prefix, (int) val, (int) right);
370       else
371         as_warn_where (file, line, err,
372                        prefix, (int) val, (int) right);
373       return;
374     }
375
376   if (   val < HEX_MAX_THRESHOLD
377       && min < HEX_MAX_THRESHOLD
378       && max < HEX_MAX_THRESHOLD
379       && val > HEX_MIN_THRESHOLD
380       && min > HEX_MIN_THRESHOLD
381       && max > HEX_MIN_THRESHOLD)
382     {
383       /* xgettext:c-format  */
384       err = _("%s out of range (%d is not between %d and %d)");
385
386       if (bad)
387         as_bad_where (file, line, err,
388                       prefix, (int) val, (int) min, (int) max);
389       else
390         as_warn_where (file, line, err,
391                        prefix, (int) val, (int) min, (int) max);
392     }
393   else
394     {
395       char val_buf [sizeof (val) * 3 + 2];
396       char min_buf [sizeof (val) * 3 + 2];
397       char max_buf [sizeof (val) * 3 + 2];
398
399       if (sizeof (val) > sizeof (bfd_vma))
400         abort ();
401
402       sprintf_vma (val_buf, (bfd_vma) val);
403       sprintf_vma (min_buf, (bfd_vma) min);
404       sprintf_vma (max_buf, (bfd_vma) max);
405
406       /* xgettext:c-format.  */
407       err = _("%s out of range (0x%s is not between 0x%s and 0x%s)");
408
409       if (bad)
410         as_bad_where (file, line, err, prefix, val_buf, min_buf, max_buf);
411       else
412         as_warn_where (file, line, err, prefix, val_buf, min_buf, max_buf);
413     }
414 }
415
416 void
417 as_warn_value_out_of_range (const char *prefix,
418                            offsetT value,
419                            offsetT min,
420                            offsetT max,
421                            const char *file,
422                            unsigned line)
423 {
424   as_internal_value_out_of_range (prefix, value, min, max, file, line, 0);
425 }
426
427 void
428 as_bad_value_out_of_range (const char *prefix,
429                            offsetT value,
430                            offsetT min,
431                            offsetT max,
432                            const char *file,
433                            unsigned line)
434 {
435   as_internal_value_out_of_range (prefix, value, min, max, file, line, 1);
436 }