Add SB-1 specific multilib support. Patch by Fred Fish.
[official-gcc.git] / gcc / fortran / error.c
blob435fc16a36fff9b5ddbf03f4bbef1125f93d982a
1 /* Handle errors.
2 Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software
3 Foundation, Inc.
4 Contributed by Andy Vaught & Niels Kristian Bech Jensen
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 2, or (at your option) any later
11 version.
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 for more details.
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING. If not, write to the Free
20 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
21 02110-1301, USA. */
23 /* Handle the inevitable errors. A major catch here is that things
24 flagged as errors in one match subroutine can conceivably be legal
25 elsewhere. This means that error messages are recorded and saved
26 for possible use later. If a line does not match a legal
27 construction, then the saved error message is reported. */
29 #include "config.h"
30 #include "system.h"
31 #include "flags.h"
32 #include "gfortran.h"
34 int gfc_suppress_error = 0;
36 static int terminal_width, buffer_flag, errors, warnings;
38 static gfc_error_buf error_buffer, warning_buffer, *cur_error_buffer;
41 /* Per-file error initialization. */
43 void
44 gfc_error_init_1 (void)
46 terminal_width = gfc_terminal_width ();
47 errors = 0;
48 warnings = 0;
49 buffer_flag = 0;
53 /* Set the flag for buffering errors or not. */
55 void
56 gfc_buffer_error (int flag)
58 buffer_flag = flag;
62 /* Add a single character to the error buffer or output depending on
63 buffer_flag. */
65 static void
66 error_char (char c)
68 if (buffer_flag)
70 if (cur_error_buffer->index >= cur_error_buffer->allocated)
72 cur_error_buffer->allocated =
73 cur_error_buffer->allocated
74 ? cur_error_buffer->allocated * 2 : 1000;
75 cur_error_buffer->message
76 = xrealloc (cur_error_buffer->message,
77 cur_error_buffer->allocated);
79 cur_error_buffer->message[cur_error_buffer->index++] = c;
81 else
83 if (c != 0)
85 /* We build up complete lines before handing things
86 over to the library in order to speed up error printing. */
87 static char *line;
88 static size_t allocated = 0, index = 0;
90 if (index + 1 >= allocated)
92 allocated = allocated ? allocated * 2 : 1000;
93 line = xrealloc (line, allocated);
95 line[index++] = c;
96 if (c == '\n')
98 line[index] = '\0';
99 fputs (line, stderr);
100 index = 0;
107 /* Copy a string to wherever it needs to go. */
109 static void
110 error_string (const char *p)
112 while (*p)
113 error_char (*p++);
117 /* Show the file, where it was included and the source line, give a
118 locus. Calls error_printf() recursively, but the recursion is at
119 most one level deep. */
121 static void error_printf (const char *, ...) ATTRIBUTE_GCC_GFC(1,2);
123 static void
124 show_locus (int offset, locus * loc)
126 gfc_linebuf *lb;
127 gfc_file *f;
128 char c, *p;
129 int i, m;
131 /* TODO: Either limit the total length and number of included files
132 displayed or add buffering of arbitrary number of characters in
133 error messages. */
135 lb = loc->lb;
136 f = lb->file;
137 error_printf ("In file %s:%d\n", f->filename,
138 #ifdef USE_MAPPED_LOCATION
139 LOCATION_LINE (lb->location)
140 #else
141 lb->linenum
142 #endif
145 for (;;)
147 i = f->inclusion_line;
149 f = f->included_by;
150 if (f == NULL) break;
152 error_printf (" Included at %s:%d\n", f->filename, i);
155 /* Show the line itself, taking care not to print more than what can
156 show up on the terminal. Tabs are converted to spaces. */
158 p = lb->line + offset;
159 i = strlen (p);
160 if (i > terminal_width)
161 i = terminal_width - 1;
163 for (; i > 0; i--)
165 c = *p++;
166 if (c == '\t')
167 c = ' ';
169 if (ISPRINT (c))
170 error_char (c);
171 else
173 error_char ('\\');
174 error_char ('x');
176 m = ((c >> 4) & 0x0F) + '0';
177 if (m > '9')
178 m += 'A' - '9' - 1;
179 error_char (m);
181 m = (c & 0x0F) + '0';
182 if (m > '9')
183 m += 'A' - '9' - 1;
184 error_char (m);
188 error_char ('\n');
192 /* As part of printing an error, we show the source lines that caused
193 the problem. We show at least one, possibly two loci. If we're
194 showing two loci and they both refer to the same file and line, we
195 only print the line once. */
197 static void
198 show_loci (locus * l1, locus * l2)
200 int offset, flag, i, m, c1, c2, cmax;
202 if (l1 == NULL)
204 error_printf ("<During initialization>\n");
205 return;
208 c1 = l1->nextc - l1->lb->line;
209 c2 = 0;
210 if (l2 == NULL)
211 goto separate;
213 c2 = l2->nextc - l2->lb->line;
215 if (c1 < c2)
216 m = c2 - c1;
217 else
218 m = c1 - c2;
221 if (l1->lb != l2->lb || m > terminal_width - 10)
222 goto separate;
224 offset = 0;
225 cmax = (c1 < c2) ? c2 : c1;
226 if (cmax > terminal_width - 5)
227 offset = cmax - terminal_width + 5;
229 if (offset < 0)
230 offset = 0;
232 c1 -= offset;
233 c2 -= offset;
235 show_locus (offset, l1);
237 /* Arrange that '1' and '2' will show up even if the two columns are equal. */
238 for (i = 1; i <= cmax; i++)
240 flag = 0;
241 if (i == c1)
243 error_char ('1');
244 flag = 1;
246 if (i == c2)
248 error_char ('2');
249 flag = 1;
251 if (flag == 0)
252 error_char (' ');
255 error_char ('\n');
257 return;
259 separate:
260 offset = 0;
262 if (c1 > terminal_width - 5)
264 offset = c1 - 5;
265 if (offset < 0)
266 offset = 0;
267 c1 = c1 - offset;
270 show_locus (offset, l1);
271 for (i = 1; i < c1; i++)
272 error_char (' ');
274 error_char ('1');
275 error_char ('\n');
277 if (l2 != NULL)
279 offset = 0;
281 if (c2 > terminal_width - 20)
283 offset = c2 - 20;
284 if (offset < 0)
285 offset = 0;
286 c2 = c2 - offset;
289 show_locus (offset, l2);
291 for (i = 1; i < c2; i++)
292 error_char (' ');
294 error_char ('2');
295 error_char ('\n');
300 /* Workhorse for the error printing subroutines. This subroutine is
301 inspired by g77's error handling and is similar to printf() with
302 the following %-codes:
304 %c Character, %d Integer, %s String, %% Percent
305 %L Takes locus argument
306 %C Current locus (no argument)
308 If a locus pointer is given, the actual source line is printed out
309 and the column is indicated. Since we want the error message at
310 the bottom of any source file information, we must scan the
311 argument list twice. A maximum of two locus arguments are
312 permitted. */
314 #define IBUF_LEN 30
315 #define MAX_ARGS 10
317 static void ATTRIBUTE_GCC_GFC(2,0)
318 error_print (const char *type, const char *format0, va_list argp)
320 char c, *p, int_buf[IBUF_LEN], c_arg[MAX_ARGS], *cp_arg[MAX_ARGS];
321 int i, n, have_l1, i_arg[MAX_ARGS];
322 locus *l1, *l2, *loc;
323 const char *format;
325 l1 = l2 = loc = NULL;
327 have_l1 = 0;
329 n = 0;
330 format = format0;
332 while (*format)
334 c = *format++;
335 if (c == '%')
337 c = *format++;
339 switch (c)
341 case '%':
342 break;
344 case 'L':
345 loc = va_arg (argp, locus *);
346 /* Fall through */
348 case 'C':
349 if (c == 'C')
350 loc = &gfc_current_locus;
352 if (have_l1)
354 l2 = loc;
356 else
358 l1 = loc;
359 have_l1 = 1;
361 break;
363 case 'd':
364 case 'i':
365 i_arg[n++] = va_arg (argp, int);
366 break;
368 case 'c':
369 c_arg[n++] = va_arg (argp, int);
370 break;
372 case 's':
373 cp_arg[n++] = va_arg (argp, char *);
374 break;
379 /* Show the current loci if we have to. */
380 if (have_l1)
381 show_loci (l1, l2);
382 error_string (type);
383 error_char (' ');
385 have_l1 = 0;
386 format = format0;
387 n = 0;
389 for (; *format; format++)
391 if (*format != '%')
393 error_char (*format);
394 continue;
397 format++;
398 switch (*format)
400 case '%':
401 error_char ('%');
402 break;
404 case 'c':
405 error_char (c_arg[n++]);
406 break;
408 case 's':
409 error_string (cp_arg[n++]);
410 break;
412 case 'i':
413 case 'd':
414 i = i_arg[n++];
416 if (i < 0)
418 i = -i;
419 error_char ('-');
422 p = int_buf + IBUF_LEN - 1;
423 *p-- = '\0';
425 if (i == 0)
426 *p-- = '0';
428 while (i > 0)
430 *p-- = i % 10 + '0';
431 i = i / 10;
434 error_string (p + 1);
435 break;
437 case 'C': /* Current locus */
438 case 'L': /* Specified locus */
439 error_string (have_l1 ? "(2)" : "(1)");
440 have_l1 = 1;
441 break;
445 error_char ('\n');
449 /* Wrapper for error_print(). */
451 static void
452 error_printf (const char *nocmsgid, ...)
454 va_list argp;
456 va_start (argp, nocmsgid);
457 error_print ("", _(nocmsgid), argp);
458 va_end (argp);
462 /* Issue a warning. */
464 void
465 gfc_warning (const char *nocmsgid, ...)
467 va_list argp;
469 if (inhibit_warnings)
470 return;
472 warning_buffer.flag = 1;
473 warning_buffer.index = 0;
474 cur_error_buffer = &warning_buffer;
476 va_start (argp, nocmsgid);
477 if (buffer_flag == 0)
478 warnings++;
479 error_print (_("Warning:"), _(nocmsgid), argp);
480 va_end (argp);
482 error_char ('\0');
486 /* Whether, for a feature included in a given standard set (GFC_STD_*),
487 we should issue an error or a warning, or be quiet. */
489 notification
490 gfc_notification_std (int std)
492 bool warning;
494 warning = ((gfc_option.warn_std & std) != 0) && !inhibit_warnings;
495 if ((gfc_option.allow_std & std) != 0 && !warning)
496 return SILENT;
498 return warning ? WARNING : ERROR;
502 /* Possibly issue a warning/error about use of a nonstandard (or deleted)
503 feature. An error/warning will be issued if the currently selected
504 standard does not contain the requested bits. Return FAILURE if
505 an error is generated. */
508 gfc_notify_std (int std, const char *nocmsgid, ...)
510 va_list argp;
511 bool warning;
513 warning = ((gfc_option.warn_std & std) != 0)
514 && !inhibit_warnings;
515 if ((gfc_option.allow_std & std) != 0
516 && !warning)
517 return SUCCESS;
519 if (gfc_suppress_error)
520 return warning ? SUCCESS : FAILURE;
522 cur_error_buffer = warning ? &warning_buffer : &error_buffer;
523 cur_error_buffer->flag = 1;
524 cur_error_buffer->index = 0;
526 if (buffer_flag == 0)
528 if (warning)
529 warnings++;
530 else
531 errors++;
533 va_start (argp, nocmsgid);
534 if (warning)
535 error_print (_("Warning:"), _(nocmsgid), argp);
536 else
537 error_print (_("Error:"), _(nocmsgid), argp);
538 va_end (argp);
540 error_char ('\0');
541 return warning ? SUCCESS : FAILURE;
545 /* Immediate warning (i.e. do not buffer the warning). */
547 void
548 gfc_warning_now (const char *nocmsgid, ...)
550 va_list argp;
551 int i;
553 if (inhibit_warnings)
554 return;
556 i = buffer_flag;
557 buffer_flag = 0;
558 warnings++;
560 va_start (argp, nocmsgid);
561 error_print (_("Warning:"), _(nocmsgid), argp);
562 va_end (argp);
564 error_char ('\0');
565 buffer_flag = i;
569 /* Clear the warning flag. */
571 void
572 gfc_clear_warning (void)
574 warning_buffer.flag = 0;
578 /* Check to see if any warnings have been saved.
579 If so, print the warning. */
581 void
582 gfc_warning_check (void)
584 if (warning_buffer.flag)
586 warnings++;
587 if (warning_buffer.message != NULL)
588 fputs (warning_buffer.message, stderr);
589 warning_buffer.flag = 0;
594 /* Issue an error. */
596 void
597 gfc_error (const char *nocmsgid, ...)
599 va_list argp;
601 if (gfc_suppress_error)
602 return;
604 error_buffer.flag = 1;
605 error_buffer.index = 0;
606 cur_error_buffer = &error_buffer;
608 va_start (argp, nocmsgid);
609 if (buffer_flag == 0)
610 errors++;
611 error_print (_("Error:"), _(nocmsgid), argp);
612 va_end (argp);
614 error_char ('\0');
618 /* Immediate error. */
620 void
621 gfc_error_now (const char *nocmsgid, ...)
623 va_list argp;
624 int i;
626 error_buffer.flag = 1;
627 error_buffer.index = 0;
628 cur_error_buffer = &error_buffer;
630 i = buffer_flag;
631 buffer_flag = 0;
632 errors++;
634 va_start (argp, nocmsgid);
635 error_print (_("Error:"), _(nocmsgid), argp);
636 va_end (argp);
638 error_char ('\0');
639 buffer_flag = i;
641 if (flag_fatal_errors)
642 exit (1);
646 /* Fatal error, never returns. */
648 void
649 gfc_fatal_error (const char *nocmsgid, ...)
651 va_list argp;
653 buffer_flag = 0;
655 va_start (argp, nocmsgid);
656 error_print (_("Fatal Error:"), _(nocmsgid), argp);
657 va_end (argp);
659 exit (3);
663 /* This shouldn't happen... but sometimes does. */
665 void
666 gfc_internal_error (const char *format, ...)
668 va_list argp;
670 buffer_flag = 0;
672 va_start (argp, format);
674 show_loci (&gfc_current_locus, NULL);
675 error_printf ("Internal Error at (1):");
677 error_print ("", format, argp);
678 va_end (argp);
680 exit (ICE_EXIT_CODE);
684 /* Clear the error flag when we start to compile a source line. */
686 void
687 gfc_clear_error (void)
689 error_buffer.flag = 0;
693 /* Check to see if any errors have been saved.
694 If so, print the error. Returns the state of error_flag. */
697 gfc_error_check (void)
699 int rc;
701 rc = error_buffer.flag;
703 if (error_buffer.flag)
705 errors++;
706 if (error_buffer.message != NULL)
707 fputs (error_buffer.message, stderr);
708 error_buffer.flag = 0;
710 if (flag_fatal_errors)
711 exit (1);
714 return rc;
718 /* Save the existing error state. */
720 void
721 gfc_push_error (gfc_error_buf * err)
723 err->flag = error_buffer.flag;
724 if (error_buffer.flag)
725 err->message = xstrdup (error_buffer.message);
727 error_buffer.flag = 0;
731 /* Restore a previous pushed error state. */
733 void
734 gfc_pop_error (gfc_error_buf * err)
736 error_buffer.flag = err->flag;
737 if (error_buffer.flag)
739 size_t len = strlen (err->message) + 1;
740 gcc_assert (len <= error_buffer.allocated);
741 memcpy (error_buffer.message, err->message, len);
742 gfc_free (err->message);
747 /* Free a pushed error state, but keep the current error state. */
749 void
750 gfc_free_error (gfc_error_buf * err)
752 if (err->flag)
753 gfc_free (err->message);
757 /* Debug wrapper for printf. */
759 void
760 gfc_status (const char *cmsgid, ...)
762 va_list argp;
764 va_start (argp, cmsgid);
766 vprintf (_(cmsgid), argp);
768 va_end (argp);
772 /* Subroutine for outputting a single char so that we don't have to go
773 around creating a lot of 1-character strings. */
775 void
776 gfc_status_char (char c)
778 putchar (c);
782 /* Report the number of warnings and errors that occurred to the caller. */
784 void
785 gfc_get_errors (int *w, int *e)
787 if (w != NULL)
788 *w = warnings;
789 if (e != NULL)
790 *e = errors;