]> gcc.gnu.org Git - gcc.git/blame - gcc/fortran/error.c
* error.c (gfc_warning): Fix typo in comment.
[gcc.git] / gcc / fortran / error.c
CommitLineData
6de9cd9a 1/* Handle errors.
35e4be35 2 Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation,
9fc4d79b 3 Inc.
6de9cd9a
DN
4 Contributed by Andy Vaught & Niels Kristian Bech Jensen
5
9fc4d79b 6This file is part of GCC.
6de9cd9a 7
9fc4d79b
TS
8GCC is free software; you can redistribute it and/or modify it under
9the terms of the GNU General Public License as published by the Free
10Software Foundation; either version 2, or (at your option) any later
11version.
6de9cd9a 12
9fc4d79b
TS
13GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14WARRANTY; without even the implied warranty of MERCHANTABILITY or
15FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16for more details.
6de9cd9a
DN
17
18You should have received a copy of the GNU General Public License
9fc4d79b
TS
19along with GCC; see the file COPYING. If not, write to the Free
20Software Foundation, 59 Temple Place - Suite 330, Boston, MA
2102111-1307, USA. */
6de9cd9a
DN
22
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. */
28
29#include "config.h"
30#include "system.h"
6de9cd9a
DN
31#include "flags.h"
32#include "gfortran.h"
33
34int gfc_suppress_error = 0;
35
36static int terminal_width, buffer_flag, errors,
37 use_warning_buffer, warnings;
38
39static char *error_ptr, *warning_ptr;
40
41static gfc_error_buf error_buffer, warning_buffer;
42
43
44/* Per-file error initialization. */
45
46void
47gfc_error_init_1 (void)
48{
1f05db63 49 terminal_width = gfc_terminal_width ();
6de9cd9a
DN
50 errors = 0;
51 warnings = 0;
52 buffer_flag = 0;
53}
54
55
56/* Set the flag for buffering errors or not. */
57
58void
59gfc_buffer_error (int flag)
60{
6de9cd9a
DN
61 buffer_flag = flag;
62}
63
64
65/* Add a single character to the error buffer or output depending on
66 buffer_flag. */
67
68static void
69error_char (char c)
70{
6de9cd9a
DN
71 if (buffer_flag)
72 {
73 if (use_warning_buffer)
74 {
75 *warning_ptr++ = c;
76 if (warning_ptr - warning_buffer.message >= MAX_ERROR_MESSAGE)
77 gfc_internal_error ("error_char(): Warning buffer overflow");
78 }
79 else
80 {
81 *error_ptr++ = c;
82 if (error_ptr - error_buffer.message >= MAX_ERROR_MESSAGE)
83 gfc_internal_error ("error_char(): Error buffer overflow");
84 }
85 }
86 else
87 {
88 if (c != 0)
dfbb4318
TS
89 {
90 /* We build up complete lines before handing things
91 over to the library in order to speed up error printing. */
92 static char line[MAX_ERROR_MESSAGE + 1];
93 static int index = 0;
94
95 line[index++] = c;
96 if (c == '\n' || index == MAX_ERROR_MESSAGE)
97 {
98 line[index] = '\0';
99 fputs (line, stderr);
100 index = 0;
101 }
102 }
6de9cd9a
DN
103 }
104}
105
106
107/* Copy a string to wherever it needs to go. */
108
109static void
110error_string (const char *p)
111{
6de9cd9a
DN
112 while (*p)
113 error_char (*p++);
114}
115
116
1f05db63 117/* Show the file, where it was included and the source line, give a
6de9cd9a
DN
118 locus. Calls error_printf() recursively, but the recursion is at
119 most one level deep. */
120
121static void error_printf (const char *, ...) ATTRIBUTE_PRINTF_1;
122
123static void
d4fa05b9 124show_locus (int offset, locus * loc)
6de9cd9a 125{
d4fa05b9 126 gfc_linebuf *lb;
6de9cd9a
DN
127 gfc_file *f;
128 char c, *p;
129 int i, m;
130
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. */
6de9cd9a 134
d4fa05b9
TS
135 lb = loc->lb;
136 f = lb->file;
c8cc8542
PB
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
143 );
d4fa05b9
TS
144
145 for (;;)
6de9cd9a 146 {
d4fa05b9
TS
147 i = f->inclusion_line;
148
6de9cd9a 149 f = f->included_by;
d4fa05b9
TS
150 if (f == NULL) break;
151
152 error_printf (" Included at %s:%d\n", f->filename, i);
6de9cd9a
DN
153 }
154
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. */
d4fa05b9
TS
157
158 p = lb->line + offset;
6de9cd9a
DN
159 i = strlen (p);
160 if (i > terminal_width)
161 i = terminal_width - 1;
162
163 for (; i > 0; i--)
164 {
165 c = *p++;
166 if (c == '\t')
167 c = ' ';
168
169 if (ISPRINT (c))
170 error_char (c);
171 else
172 {
173 error_char ('\\');
174 error_char ('x');
175
176 m = ((c >> 4) & 0x0F) + '0';
177 if (m > '9')
178 m += 'A' - '9' - 1;
179 error_char (m);
180
181 m = (c & 0x0F) + '0';
182 if (m > '9')
183 m += 'A' - '9' - 1;
184 error_char (m);
185 }
186 }
187
188 error_char ('\n');
189}
190
191
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. */
196
197static void
198show_loci (locus * l1, locus * l2)
199{
200 int offset, flag, i, m, c1, c2, cmax;
201
202 if (l1 == NULL)
203 {
204 error_printf ("<During initialization>\n");
205 return;
206 }
207
d4fa05b9 208 c1 = l1->nextc - l1->lb->line;
6de9cd9a
DN
209 c2 = 0;
210 if (l2 == NULL)
211 goto separate;
212
d4fa05b9 213 c2 = l2->nextc - l2->lb->line;
6de9cd9a
DN
214
215 if (c1 < c2)
216 m = c2 - c1;
217 else
218 m = c1 - c2;
219
220
d4fa05b9 221 if (l1->lb != l2->lb || m > terminal_width - 10)
6de9cd9a
DN
222 goto separate;
223
224 offset = 0;
225 cmax = (c1 < c2) ? c2 : c1;
226 if (cmax > terminal_width - 5)
227 offset = cmax - terminal_width + 5;
228
229 if (offset < 0)
230 offset = 0;
231
232 c1 -= offset;
233 c2 -= offset;
234
235 show_locus (offset, l1);
236
237 /* Arrange that '1' and '2' will show up even if the two columns are equal. */
238 for (i = 1; i <= cmax; i++)
239 {
240 flag = 0;
241 if (i == c1)
242 {
243 error_char ('1');
244 flag = 1;
245 }
246 if (i == c2)
247 {
248 error_char ('2');
249 flag = 1;
250 }
251 if (flag == 0)
252 error_char (' ');
253 }
254
255 error_char ('\n');
256
257 return;
258
259separate:
260 offset = 0;
261
262 if (c1 > terminal_width - 5)
263 {
264 offset = c1 - 5;
265 if (offset < 0)
266 offset = 0;
267 c1 = c1 - offset;
268 }
269
270 show_locus (offset, l1);
271 for (i = 1; i < c1; i++)
272 error_char (' ');
273
274 error_char ('1');
275 error_char ('\n');
276
277 if (l2 != NULL)
278 {
279 offset = 0;
280
281 if (c2 > terminal_width - 20)
282 {
283 offset = c2 - 20;
284 if (offset < 0)
285 offset = 0;
286 c2 = c2 - offset;
287 }
288
289 show_locus (offset, l2);
290
291 for (i = 1; i < c2; i++)
292 error_char (' ');
293
294 error_char ('2');
295 error_char ('\n');
296 }
297}
298
299
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:
303
304 %c Character, %d Integer, %s String, %% Percent
305 %L Takes locus argument
306 %C Current locus (no argument)
307
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. */
313
314#define IBUF_LEN 30
315#define MAX_ARGS 10
316
317static void
318error_print (const char *type, const char *format0, va_list argp)
319{
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;
324
325 l1 = l2 = loc = NULL;
326
327 have_l1 = 0;
328
329 n = 0;
330 format = format0;
331
332 while (*format)
333 {
334 c = *format++;
335 if (c == '%')
336 {
337 c = *format++;
338
339 switch (c)
340 {
341 case '%':
342 break;
343
344 case 'L':
345 loc = va_arg (argp, locus *);
346 /* Fall through */
347
348 case 'C':
349 if (c == 'C')
63645982 350 loc = &gfc_current_locus;
6de9cd9a
DN
351
352 if (have_l1)
353 {
354 l2 = loc;
355 }
356 else
357 {
358 l1 = loc;
359 have_l1 = 1;
360 }
361 break;
362
363 case 'd':
364 case 'i':
365 i_arg[n++] = va_arg (argp, int);
366 break;
367
368 case 'c':
369 c_arg[n++] = va_arg (argp, int);
370 break;
371
372 case 's':
373 cp_arg[n++] = va_arg (argp, char *);
374 break;
375 }
376 }
377 }
378
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 (' ');
384
385 have_l1 = 0;
386 format = format0;
387 n = 0;
388
389 for (; *format; format++)
390 {
391 if (*format != '%')
392 {
393 error_char (*format);
394 continue;
395 }
396
397 format++;
398 switch (*format)
399 {
400 case '%':
401 error_char ('%');
402 break;
403
404 case 'c':
405 error_char (c_arg[n++]);
406 break;
407
408 case 's':
409 error_string (cp_arg[n++]);
410 break;
411
412 case 'i':
413 case 'd':
414 i = i_arg[n++];
415
416 if (i < 0)
417 {
418 i = -i;
419 error_char ('-');
420 }
421
422 p = int_buf + IBUF_LEN - 1;
423 *p-- = '\0';
424
425 if (i == 0)
426 *p-- = '0';
427
428 while (i > 0)
429 {
430 *p-- = i % 10 + '0';
431 i = i / 10;
432 }
433
434 error_string (p + 1);
435 break;
436
437 case 'C': /* Current locus */
438 case 'L': /* Specified locus */
439 error_string (have_l1 ? "(2)" : "(1)");
440 have_l1 = 1;
441 break;
442 }
443 }
444
445 error_char ('\n');
446}
447
448
449/* Wrapper for error_print(). */
450
451static void
452error_printf (const char *format, ...)
453{
454 va_list argp;
455
456 va_start (argp, format);
457 error_print ("", format, argp);
458 va_end (argp);
459}
460
461
462/* Issue a warning. */
463
464void
465gfc_warning (const char *format, ...)
466{
467 va_list argp;
468
469 if (inhibit_warnings)
470 return;
471
472 warning_buffer.flag = 1;
473 warning_ptr = warning_buffer.message;
474 use_warning_buffer = 1;
475
476 va_start (argp, format);
477 if (buffer_flag == 0)
478 warnings++;
479 error_print ("Warning:", format, argp);
480 va_end (argp);
481
482 error_char ('\0');
483}
484
485
486/* Possibly issue a warning/error about use of a nonstandard (or deleted)
487 feature. An error/warning will be issued if the currently selected
488 standard does not contain the requested bits. Return FAILURE if
e88763d1 489 an error is generated. */
6de9cd9a
DN
490
491try
492gfc_notify_std (int std, const char *format, ...)
493{
494 va_list argp;
495 bool warning;
496
497 warning = ((gfc_option.warn_std & std) != 0)
498 && !inhibit_warnings;
499 if ((gfc_option.allow_std & std) != 0
500 && !warning)
501 return SUCCESS;
502
503 if (gfc_suppress_error)
504 return warning ? SUCCESS : FAILURE;
505
506 if (warning)
507 {
508 warning_buffer.flag = 1;
509 warning_ptr = warning_buffer.message;
510 use_warning_buffer = 1;
511 }
512 else
513 {
514 error_buffer.flag = 1;
515 error_ptr = error_buffer.message;
516 use_warning_buffer = 0;
517 }
518
519 if (buffer_flag == 0)
520 {
521 if (warning)
522 warnings++;
523 else
524 errors++;
525 }
526 va_start (argp, format);
527 if (warning)
528 error_print ("Warning:", format, argp);
529 else
530 error_print ("Error:", format, argp);
531 va_end (argp);
532
533 error_char ('\0');
534 return warning ? SUCCESS : FAILURE;
535}
536
537
538/* Immediate warning (i.e. do not buffer the warning). */
539
540void
541gfc_warning_now (const char *format, ...)
542{
543 va_list argp;
544 int i;
545
546 if (inhibit_warnings)
547 return;
548
549 i = buffer_flag;
550 buffer_flag = 0;
551 warnings++;
552
553 va_start (argp, format);
554 error_print ("Warning:", format, argp);
555 va_end (argp);
556
557 error_char ('\0');
558 buffer_flag = i;
559}
560
561
562/* Clear the warning flag. */
563
564void
565gfc_clear_warning (void)
566{
6de9cd9a
DN
567 warning_buffer.flag = 0;
568}
569
570
571/* Check to see if any warnings have been saved.
572 If so, print the warning. */
573
574void
575gfc_warning_check (void)
576{
6de9cd9a
DN
577 if (warning_buffer.flag)
578 {
579 warnings++;
580 fputs (warning_buffer.message, stderr);
581 warning_buffer.flag = 0;
582 }
583}
584
585
586/* Issue an error. */
587
588void
589gfc_error (const char *format, ...)
590{
591 va_list argp;
592
593 if (gfc_suppress_error)
594 return;
595
596 error_buffer.flag = 1;
597 error_ptr = error_buffer.message;
598 use_warning_buffer = 0;
599
600 va_start (argp, format);
601 if (buffer_flag == 0)
602 errors++;
603 error_print ("Error:", format, argp);
604 va_end (argp);
605
606 error_char ('\0');
607}
608
609
610/* Immediate error. */
611
612void
613gfc_error_now (const char *format, ...)
614{
615 va_list argp;
616 int i;
617
618 error_buffer.flag = 1;
619 error_ptr = error_buffer.message;
620
621 i = buffer_flag;
622 buffer_flag = 0;
623 errors++;
624
625 va_start (argp, format);
626 error_print ("Error:", format, argp);
627 va_end (argp);
628
629 error_char ('\0');
630 buffer_flag = i;
631}
632
633
634/* Fatal error, never returns. */
635
636void
637gfc_fatal_error (const char *format, ...)
638{
639 va_list argp;
640
641 buffer_flag = 0;
642
643 va_start (argp, format);
644 error_print ("Fatal Error:", format, argp);
645 va_end (argp);
646
647 exit (3);
648}
649
650
651/* This shouldn't happen... but sometimes does. */
652
653void
654gfc_internal_error (const char *format, ...)
655{
656 va_list argp;
657
658 buffer_flag = 0;
659
660 va_start (argp, format);
661
63645982 662 show_loci (&gfc_current_locus, NULL);
6de9cd9a
DN
663 error_printf ("Internal Error at (1):");
664
665 error_print ("", format, argp);
666 va_end (argp);
667
668 exit (4);
669}
670
671
672/* Clear the error flag when we start to compile a source line. */
673
674void
675gfc_clear_error (void)
676{
6de9cd9a
DN
677 error_buffer.flag = 0;
678}
679
680
681/* Check to see if any errors have been saved.
682 If so, print the error. Returns the state of error_flag. */
683
684int
685gfc_error_check (void)
686{
687 int rc;
688
689 rc = error_buffer.flag;
690
691 if (error_buffer.flag)
692 {
693 errors++;
694 fputs (error_buffer.message, stderr);
695 error_buffer.flag = 0;
696 }
697
698 return rc;
699}
700
701
702/* Save the existing error state. */
703
704void
705gfc_push_error (gfc_error_buf * err)
706{
6de9cd9a
DN
707 err->flag = error_buffer.flag;
708 if (error_buffer.flag)
709 strcpy (err->message, error_buffer.message);
710
711 error_buffer.flag = 0;
712}
713
714
715/* Restore a previous pushed error state. */
716
717void
718gfc_pop_error (gfc_error_buf * err)
719{
6de9cd9a
DN
720 error_buffer.flag = err->flag;
721 if (error_buffer.flag)
722 strcpy (error_buffer.message, err->message);
723}
724
725
726/* Debug wrapper for printf. */
727
728void
729gfc_status (const char *format, ...)
730{
731 va_list argp;
732
733 va_start (argp, format);
734
735 vprintf (format, argp);
736
737 va_end (argp);
738}
739
740
741/* Subroutine for outputting a single char so that we don't have to go
742 around creating a lot of 1-character strings. */
743
744void
745gfc_status_char (char c)
746{
747 putchar (c);
748}
749
750
1f2959f0 751/* Report the number of warnings and errors that occurred to the caller. */
6de9cd9a
DN
752
753void
754gfc_get_errors (int *w, int *e)
755{
6de9cd9a
DN
756 if (w != NULL)
757 *w = warnings;
758 if (e != NULL)
759 *e = errors;
760}
This page took 0.475805 seconds and 5 git commands to generate.