* Merge with edge-vector-mergepoint-20040918.
[official-gcc.git] / gcc / fortran / error.c
blob084f0ef474e9180664c79e3136b61dcef220d9d1
1 /* Handle errors.
2 Copyright (C) 2000, 2001, 2002, 2003, 2004 Free Software Foundation,
3 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, 59 Temple Place - Suite 330, Boston, MA
21 02111-1307, 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"
32 #include <string.h>
33 #include <stdarg.h>
34 #include <stdio.h>
35 #include <stdlib.h>
37 #include "flags.h"
38 #include "gfortran.h"
40 int gfc_suppress_error = 0;
42 static int terminal_width, buffer_flag, errors,
43 use_warning_buffer, warnings;
45 static char *error_ptr, *warning_ptr;
47 static gfc_error_buf error_buffer, warning_buffer;
50 /* Per-file error initialization. */
52 void
53 gfc_error_init_1 (void)
55 terminal_width = gfc_terminal_width ();
56 errors = 0;
57 warnings = 0;
58 buffer_flag = 0;
62 /* Set the flag for buffering errors or not. */
64 void
65 gfc_buffer_error (int flag)
67 buffer_flag = flag;
71 /* Add a single character to the error buffer or output depending on
72 buffer_flag. */
74 static void
75 error_char (char c)
77 if (buffer_flag)
79 if (use_warning_buffer)
81 *warning_ptr++ = c;
82 if (warning_ptr - warning_buffer.message >= MAX_ERROR_MESSAGE)
83 gfc_internal_error ("error_char(): Warning buffer overflow");
85 else
87 *error_ptr++ = c;
88 if (error_ptr - error_buffer.message >= MAX_ERROR_MESSAGE)
89 gfc_internal_error ("error_char(): Error buffer overflow");
92 else
94 if (c != 0)
95 fputc (c, stderr);
100 /* Copy a string to wherever it needs to go. */
102 static void
103 error_string (const char *p)
105 while (*p)
106 error_char (*p++);
110 /* Show the file, where it was included and the source line, give a
111 locus. Calls error_printf() recursively, but the recursion is at
112 most one level deep. */
114 static void error_printf (const char *, ...) ATTRIBUTE_PRINTF_1;
116 static void
117 show_locus (int offset, locus * loc)
119 gfc_linebuf *lb;
120 gfc_file *f;
121 char c, *p;
122 int i, m;
124 /* TODO: Either limit the total length and number of included files
125 displayed or add buffering of arbitrary number of characters in
126 error messages. */
128 lb = loc->lb;
129 f = lb->file;
130 error_printf ("In file %s:%d\n", f->filename,
131 #ifdef USE_MAPPED_LOCATION
132 LOCATION_LINE (lb->location)
133 #else
134 lb->linenum
135 #endif
138 for (;;)
140 i = f->inclusion_line;
142 f = f->included_by;
143 if (f == NULL) break;
145 error_printf (" Included at %s:%d\n", f->filename, i);
148 /* Show the line itself, taking care not to print more than what can
149 show up on the terminal. Tabs are converted to spaces. */
151 p = lb->line + offset;
152 i = strlen (p);
153 if (i > terminal_width)
154 i = terminal_width - 1;
156 for (; i > 0; i--)
158 c = *p++;
159 if (c == '\t')
160 c = ' ';
162 if (ISPRINT (c))
163 error_char (c);
164 else
166 error_char ('\\');
167 error_char ('x');
169 m = ((c >> 4) & 0x0F) + '0';
170 if (m > '9')
171 m += 'A' - '9' - 1;
172 error_char (m);
174 m = (c & 0x0F) + '0';
175 if (m > '9')
176 m += 'A' - '9' - 1;
177 error_char (m);
181 error_char ('\n');
185 /* As part of printing an error, we show the source lines that caused
186 the problem. We show at least one, possibly two loci. If we're
187 showing two loci and they both refer to the same file and line, we
188 only print the line once. */
190 static void
191 show_loci (locus * l1, locus * l2)
193 int offset, flag, i, m, c1, c2, cmax;
195 if (l1 == NULL)
197 error_printf ("<During initialization>\n");
198 return;
201 c1 = l1->nextc - l1->lb->line;
202 c2 = 0;
203 if (l2 == NULL)
204 goto separate;
206 c2 = l2->nextc - l2->lb->line;
208 if (c1 < c2)
209 m = c2 - c1;
210 else
211 m = c1 - c2;
214 if (l1->lb != l2->lb || m > terminal_width - 10)
215 goto separate;
217 offset = 0;
218 cmax = (c1 < c2) ? c2 : c1;
219 if (cmax > terminal_width - 5)
220 offset = cmax - terminal_width + 5;
222 if (offset < 0)
223 offset = 0;
225 c1 -= offset;
226 c2 -= offset;
228 show_locus (offset, l1);
230 /* Arrange that '1' and '2' will show up even if the two columns are equal. */
231 for (i = 1; i <= cmax; i++)
233 flag = 0;
234 if (i == c1)
236 error_char ('1');
237 flag = 1;
239 if (i == c2)
241 error_char ('2');
242 flag = 1;
244 if (flag == 0)
245 error_char (' ');
248 error_char ('\n');
250 return;
252 separate:
253 offset = 0;
255 if (c1 > terminal_width - 5)
257 offset = c1 - 5;
258 if (offset < 0)
259 offset = 0;
260 c1 = c1 - offset;
263 show_locus (offset, l1);
264 for (i = 1; i < c1; i++)
265 error_char (' ');
267 error_char ('1');
268 error_char ('\n');
270 if (l2 != NULL)
272 offset = 0;
274 if (c2 > terminal_width - 20)
276 offset = c2 - 20;
277 if (offset < 0)
278 offset = 0;
279 c2 = c2 - offset;
282 show_locus (offset, l2);
284 for (i = 1; i < c2; i++)
285 error_char (' ');
287 error_char ('2');
288 error_char ('\n');
293 /* Workhorse for the error printing subroutines. This subroutine is
294 inspired by g77's error handling and is similar to printf() with
295 the following %-codes:
297 %c Character, %d Integer, %s String, %% Percent
298 %L Takes locus argument
299 %C Current locus (no argument)
301 If a locus pointer is given, the actual source line is printed out
302 and the column is indicated. Since we want the error message at
303 the bottom of any source file information, we must scan the
304 argument list twice. A maximum of two locus arguments are
305 permitted. */
307 #define IBUF_LEN 30
308 #define MAX_ARGS 10
310 static void
311 error_print (const char *type, const char *format0, va_list argp)
313 char c, *p, int_buf[IBUF_LEN], c_arg[MAX_ARGS], *cp_arg[MAX_ARGS];
314 int i, n, have_l1, i_arg[MAX_ARGS];
315 locus *l1, *l2, *loc;
316 const char *format;
318 l1 = l2 = loc = NULL;
320 have_l1 = 0;
322 n = 0;
323 format = format0;
325 while (*format)
327 c = *format++;
328 if (c == '%')
330 c = *format++;
332 switch (c)
334 case '%':
335 break;
337 case 'L':
338 loc = va_arg (argp, locus *);
339 /* Fall through */
341 case 'C':
342 if (c == 'C')
343 loc = &gfc_current_locus;
345 if (have_l1)
347 l2 = loc;
349 else
351 l1 = loc;
352 have_l1 = 1;
354 break;
356 case 'd':
357 case 'i':
358 i_arg[n++] = va_arg (argp, int);
359 break;
361 case 'c':
362 c_arg[n++] = va_arg (argp, int);
363 break;
365 case 's':
366 cp_arg[n++] = va_arg (argp, char *);
367 break;
372 /* Show the current loci if we have to. */
373 if (have_l1)
374 show_loci (l1, l2);
375 error_string (type);
376 error_char (' ');
378 have_l1 = 0;
379 format = format0;
380 n = 0;
382 for (; *format; format++)
384 if (*format != '%')
386 error_char (*format);
387 continue;
390 format++;
391 switch (*format)
393 case '%':
394 error_char ('%');
395 break;
397 case 'c':
398 error_char (c_arg[n++]);
399 break;
401 case 's':
402 error_string (cp_arg[n++]);
403 break;
405 case 'i':
406 case 'd':
407 i = i_arg[n++];
409 if (i < 0)
411 i = -i;
412 error_char ('-');
415 p = int_buf + IBUF_LEN - 1;
416 *p-- = '\0';
418 if (i == 0)
419 *p-- = '0';
421 while (i > 0)
423 *p-- = i % 10 + '0';
424 i = i / 10;
427 error_string (p + 1);
428 break;
430 case 'C': /* Current locus */
431 case 'L': /* Specified locus */
432 error_string (have_l1 ? "(2)" : "(1)");
433 have_l1 = 1;
434 break;
438 error_char ('\n');
442 /* Wrapper for error_print(). */
444 static void
445 error_printf (const char *format, ...)
447 va_list argp;
449 va_start (argp, format);
450 error_print ("", format, argp);
451 va_end (argp);
455 /* Issue a warning. */
457 void
458 gfc_warning (const char *format, ...)
460 va_list argp;
462 if (inhibit_warnings)
463 return;
465 warning_buffer.flag = 1;
466 warning_ptr = warning_buffer.message;
467 use_warning_buffer = 1;
469 va_start (argp, format);
470 if (buffer_flag == 0)
471 warnings++;
472 error_print ("Warning:", format, argp);
473 va_end (argp);
475 error_char ('\0');
479 /* Possibly issue a warning/error about use of a nonstandard (or deleted)
480 feature. An error/warning will be issued if the currently selected
481 standard does not contain the requested bits. Return FAILURE if
482 and error is generated. */
485 gfc_notify_std (int std, const char *format, ...)
487 va_list argp;
488 bool warning;
490 warning = ((gfc_option.warn_std & std) != 0)
491 && !inhibit_warnings;
492 if ((gfc_option.allow_std & std) != 0
493 && !warning)
494 return SUCCESS;
496 if (gfc_suppress_error)
497 return warning ? SUCCESS : FAILURE;
499 if (warning)
501 warning_buffer.flag = 1;
502 warning_ptr = warning_buffer.message;
503 use_warning_buffer = 1;
505 else
507 error_buffer.flag = 1;
508 error_ptr = error_buffer.message;
509 use_warning_buffer = 0;
512 if (buffer_flag == 0)
514 if (warning)
515 warnings++;
516 else
517 errors++;
519 va_start (argp, format);
520 if (warning)
521 error_print ("Warning:", format, argp);
522 else
523 error_print ("Error:", format, argp);
524 va_end (argp);
526 error_char ('\0');
527 return warning ? SUCCESS : FAILURE;
531 /* Immediate warning (i.e. do not buffer the warning). */
533 void
534 gfc_warning_now (const char *format, ...)
536 va_list argp;
537 int i;
539 if (inhibit_warnings)
540 return;
542 i = buffer_flag;
543 buffer_flag = 0;
544 warnings++;
546 va_start (argp, format);
547 error_print ("Warning:", format, argp);
548 va_end (argp);
550 error_char ('\0');
551 buffer_flag = i;
555 /* Clear the warning flag. */
557 void
558 gfc_clear_warning (void)
560 warning_buffer.flag = 0;
564 /* Check to see if any warnings have been saved.
565 If so, print the warning. */
567 void
568 gfc_warning_check (void)
570 if (warning_buffer.flag)
572 warnings++;
573 fputs (warning_buffer.message, stderr);
574 warning_buffer.flag = 0;
579 /* Issue an error. */
581 void
582 gfc_error (const char *format, ...)
584 va_list argp;
586 if (gfc_suppress_error)
587 return;
589 error_buffer.flag = 1;
590 error_ptr = error_buffer.message;
591 use_warning_buffer = 0;
593 va_start (argp, format);
594 if (buffer_flag == 0)
595 errors++;
596 error_print ("Error:", format, argp);
597 va_end (argp);
599 error_char ('\0');
603 /* Immediate error. */
605 void
606 gfc_error_now (const char *format, ...)
608 va_list argp;
609 int i;
611 error_buffer.flag = 1;
612 error_ptr = error_buffer.message;
614 i = buffer_flag;
615 buffer_flag = 0;
616 errors++;
618 va_start (argp, format);
619 error_print ("Error:", format, argp);
620 va_end (argp);
622 error_char ('\0');
623 buffer_flag = i;
627 /* Fatal error, never returns. */
629 void
630 gfc_fatal_error (const char *format, ...)
632 va_list argp;
634 buffer_flag = 0;
636 va_start (argp, format);
637 error_print ("Fatal Error:", format, argp);
638 va_end (argp);
640 exit (3);
644 /* This shouldn't happen... but sometimes does. */
646 void
647 gfc_internal_error (const char *format, ...)
649 va_list argp;
651 buffer_flag = 0;
653 va_start (argp, format);
655 show_loci (&gfc_current_locus, NULL);
656 error_printf ("Internal Error at (1):");
658 error_print ("", format, argp);
659 va_end (argp);
661 exit (4);
665 /* Clear the error flag when we start to compile a source line. */
667 void
668 gfc_clear_error (void)
670 error_buffer.flag = 0;
674 /* Check to see if any errors have been saved.
675 If so, print the error. Returns the state of error_flag. */
678 gfc_error_check (void)
680 int rc;
682 rc = error_buffer.flag;
684 if (error_buffer.flag)
686 errors++;
687 fputs (error_buffer.message, stderr);
688 error_buffer.flag = 0;
691 return rc;
695 /* Save the existing error state. */
697 void
698 gfc_push_error (gfc_error_buf * err)
700 err->flag = error_buffer.flag;
701 if (error_buffer.flag)
702 strcpy (err->message, error_buffer.message);
704 error_buffer.flag = 0;
708 /* Restore a previous pushed error state. */
710 void
711 gfc_pop_error (gfc_error_buf * err)
713 error_buffer.flag = err->flag;
714 if (error_buffer.flag)
715 strcpy (error_buffer.message, err->message);
719 /* Debug wrapper for printf. */
721 void
722 gfc_status (const char *format, ...)
724 va_list argp;
726 va_start (argp, format);
728 vprintf (format, argp);
730 va_end (argp);
734 /* Subroutine for outputting a single char so that we don't have to go
735 around creating a lot of 1-character strings. */
737 void
738 gfc_status_char (char c)
740 putchar (c);
744 /* Report the number of warnings and errors that occurred to the caller. */
746 void
747 gfc_get_errors (int *w, int *e)
749 if (w != NULL)
750 *w = warnings;
751 if (e != NULL)
752 *e = errors;