]> gcc.gnu.org Git - gcc.git/blame - gcc/fortran/error.c
Daily bump.
[gcc.git] / gcc / fortran / error.c
CommitLineData
6de9cd9a 1/* Handle errors.
8f0d39a8
FXC
2 Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software
3 Foundation, 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 19along with GCC; see the file COPYING. If not, write to the Free
ab57747b
KC
20Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
2102110-1301, 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
d71b89ca 36static int terminal_width, buffer_flag, errors, warnings;
6de9cd9a 37
d71b89ca 38static gfc_error_buf error_buffer, warning_buffer, *cur_error_buffer;
6de9cd9a
DN
39
40
41/* Per-file error initialization. */
42
43void
44gfc_error_init_1 (void)
45{
1f05db63 46 terminal_width = gfc_terminal_width ();
6de9cd9a
DN
47 errors = 0;
48 warnings = 0;
49 buffer_flag = 0;
50}
51
52
53/* Set the flag for buffering errors or not. */
54
55void
56gfc_buffer_error (int flag)
57{
6de9cd9a
DN
58 buffer_flag = flag;
59}
60
61
62/* Add a single character to the error buffer or output depending on
63 buffer_flag. */
64
65static void
66error_char (char c)
67{
6de9cd9a
DN
68 if (buffer_flag)
69 {
d71b89ca 70 if (cur_error_buffer->index >= cur_error_buffer->allocated)
6de9cd9a 71 {
d71b89ca
JJ
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);
6de9cd9a 78 }
d71b89ca 79 cur_error_buffer->message[cur_error_buffer->index++] = c;
6de9cd9a
DN
80 }
81 else
82 {
83 if (c != 0)
dfbb4318
TS
84 {
85 /* We build up complete lines before handing things
86 over to the library in order to speed up error printing. */
d71b89ca
JJ
87 static char *line;
88 static size_t allocated = 0, index = 0;
dfbb4318 89
d71b89ca
JJ
90 if (index + 1 >= allocated)
91 {
92 allocated = allocated ? allocated * 2 : 1000;
93 line = xrealloc (line, allocated);
94 }
dfbb4318 95 line[index++] = c;
d71b89ca 96 if (c == '\n')
dfbb4318
TS
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
0ce0154c 121static void error_printf (const char *, ...) ATTRIBUTE_GCC_GFC(1,2);
6de9cd9a
DN
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
0ce0154c 317static void ATTRIBUTE_GCC_GFC(2,0)
6de9cd9a
DN
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
31043f6c 452error_printf (const char *nocmsgid, ...)
6de9cd9a
DN
453{
454 va_list argp;
455
31043f6c
FXC
456 va_start (argp, nocmsgid);
457 error_print ("", _(nocmsgid), argp);
6de9cd9a
DN
458 va_end (argp);
459}
460
461
462/* Issue a warning. */
463
464void
31043f6c 465gfc_warning (const char *nocmsgid, ...)
6de9cd9a
DN
466{
467 va_list argp;
468
469 if (inhibit_warnings)
470 return;
471
472 warning_buffer.flag = 1;
d71b89ca
JJ
473 warning_buffer.index = 0;
474 cur_error_buffer = &warning_buffer;
6de9cd9a 475
31043f6c 476 va_start (argp, nocmsgid);
6de9cd9a
DN
477 if (buffer_flag == 0)
478 warnings++;
31043f6c 479 error_print (_("Warning:"), _(nocmsgid), argp);
6de9cd9a
DN
480 va_end (argp);
481
482 error_char ('\0');
483}
484
485
8f0d39a8
FXC
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. */
488
489notification
490gfc_notification_std (int std)
491{
492 bool warning;
493
494 warning = ((gfc_option.warn_std & std) != 0) && !inhibit_warnings;
495 if ((gfc_option.allow_std & std) != 0 && !warning)
496 return SILENT;
497
498 return warning ? WARNING : ERROR;
499}
500
501
6de9cd9a
DN
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
e88763d1 505 an error is generated. */
6de9cd9a
DN
506
507try
31043f6c 508gfc_notify_std (int std, const char *nocmsgid, ...)
6de9cd9a
DN
509{
510 va_list argp;
511 bool warning;
512
513 warning = ((gfc_option.warn_std & std) != 0)
514 && !inhibit_warnings;
515 if ((gfc_option.allow_std & std) != 0
516 && !warning)
517 return SUCCESS;
518
519 if (gfc_suppress_error)
520 return warning ? SUCCESS : FAILURE;
521
d71b89ca
JJ
522 cur_error_buffer = warning ? &warning_buffer : &error_buffer;
523 cur_error_buffer->flag = 1;
524 cur_error_buffer->index = 0;
6de9cd9a
DN
525
526 if (buffer_flag == 0)
527 {
528 if (warning)
529 warnings++;
530 else
531 errors++;
532 }
31043f6c 533 va_start (argp, nocmsgid);
6de9cd9a 534 if (warning)
31043f6c 535 error_print (_("Warning:"), _(nocmsgid), argp);
6de9cd9a 536 else
31043f6c 537 error_print (_("Error:"), _(nocmsgid), argp);
6de9cd9a
DN
538 va_end (argp);
539
540 error_char ('\0');
541 return warning ? SUCCESS : FAILURE;
542}
543
544
545/* Immediate warning (i.e. do not buffer the warning). */
546
547void
31043f6c 548gfc_warning_now (const char *nocmsgid, ...)
6de9cd9a
DN
549{
550 va_list argp;
551 int i;
552
553 if (inhibit_warnings)
554 return;
555
556 i = buffer_flag;
557 buffer_flag = 0;
558 warnings++;
559
31043f6c
FXC
560 va_start (argp, nocmsgid);
561 error_print (_("Warning:"), _(nocmsgid), argp);
6de9cd9a
DN
562 va_end (argp);
563
564 error_char ('\0');
565 buffer_flag = i;
566}
567
568
569/* Clear the warning flag. */
570
571void
572gfc_clear_warning (void)
573{
6de9cd9a
DN
574 warning_buffer.flag = 0;
575}
576
577
578/* Check to see if any warnings have been saved.
579 If so, print the warning. */
580
581void
582gfc_warning_check (void)
583{
6de9cd9a
DN
584 if (warning_buffer.flag)
585 {
586 warnings++;
d71b89ca
JJ
587 if (warning_buffer.message != NULL)
588 fputs (warning_buffer.message, stderr);
6de9cd9a
DN
589 warning_buffer.flag = 0;
590 }
591}
592
593
594/* Issue an error. */
595
596void
31043f6c 597gfc_error (const char *nocmsgid, ...)
6de9cd9a
DN
598{
599 va_list argp;
600
601 if (gfc_suppress_error)
602 return;
603
604 error_buffer.flag = 1;
d71b89ca
JJ
605 error_buffer.index = 0;
606 cur_error_buffer = &error_buffer;
6de9cd9a 607
31043f6c 608 va_start (argp, nocmsgid);
6de9cd9a
DN
609 if (buffer_flag == 0)
610 errors++;
31043f6c 611 error_print (_("Error:"), _(nocmsgid), argp);
6de9cd9a
DN
612 va_end (argp);
613
614 error_char ('\0');
615}
616
617
618/* Immediate error. */
619
620void
31043f6c 621gfc_error_now (const char *nocmsgid, ...)
6de9cd9a
DN
622{
623 va_list argp;
624 int i;
625
626 error_buffer.flag = 1;
d71b89ca
JJ
627 error_buffer.index = 0;
628 cur_error_buffer = &error_buffer;
6de9cd9a
DN
629
630 i = buffer_flag;
631 buffer_flag = 0;
632 errors++;
633
31043f6c
FXC
634 va_start (argp, nocmsgid);
635 error_print (_("Error:"), _(nocmsgid), argp);
6de9cd9a
DN
636 va_end (argp);
637
638 error_char ('\0');
639 buffer_flag = i;
b3ae6c0f
SK
640
641 if (flag_fatal_errors)
642 exit (1);
6de9cd9a
DN
643}
644
645
646/* Fatal error, never returns. */
647
648void
31043f6c 649gfc_fatal_error (const char *nocmsgid, ...)
6de9cd9a
DN
650{
651 va_list argp;
652
653 buffer_flag = 0;
654
31043f6c
FXC
655 va_start (argp, nocmsgid);
656 error_print (_("Fatal Error:"), _(nocmsgid), argp);
6de9cd9a
DN
657 va_end (argp);
658
659 exit (3);
660}
661
662
663/* This shouldn't happen... but sometimes does. */
664
665void
666gfc_internal_error (const char *format, ...)
667{
668 va_list argp;
669
670 buffer_flag = 0;
671
672 va_start (argp, format);
673
63645982 674 show_loci (&gfc_current_locus, NULL);
6de9cd9a
DN
675 error_printf ("Internal Error at (1):");
676
677 error_print ("", format, argp);
678 va_end (argp);
679
ddaf3b86 680 exit (ICE_EXIT_CODE);
6de9cd9a
DN
681}
682
683
684/* Clear the error flag when we start to compile a source line. */
685
686void
687gfc_clear_error (void)
688{
6de9cd9a
DN
689 error_buffer.flag = 0;
690}
691
692
693/* Check to see if any errors have been saved.
694 If so, print the error. Returns the state of error_flag. */
695
696int
697gfc_error_check (void)
698{
699 int rc;
700
701 rc = error_buffer.flag;
702
703 if (error_buffer.flag)
704 {
705 errors++;
d71b89ca
JJ
706 if (error_buffer.message != NULL)
707 fputs (error_buffer.message, stderr);
6de9cd9a 708 error_buffer.flag = 0;
b3ae6c0f
SK
709
710 if (flag_fatal_errors)
711 exit (1);
6de9cd9a
DN
712 }
713
714 return rc;
715}
716
717
718/* Save the existing error state. */
719
720void
721gfc_push_error (gfc_error_buf * err)
722{
6de9cd9a
DN
723 err->flag = error_buffer.flag;
724 if (error_buffer.flag)
d71b89ca 725 err->message = xstrdup (error_buffer.message);
6de9cd9a
DN
726
727 error_buffer.flag = 0;
728}
729
730
731/* Restore a previous pushed error state. */
732
733void
734gfc_pop_error (gfc_error_buf * err)
735{
6de9cd9a
DN
736 error_buffer.flag = err->flag;
737 if (error_buffer.flag)
d71b89ca
JJ
738 {
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);
743 }
744}
745
746
747/* Free a pushed error state, but keep the current error state. */
748
749void
750gfc_free_error (gfc_error_buf * err)
751{
752 if (err->flag)
753 gfc_free (err->message);
6de9cd9a
DN
754}
755
756
757/* Debug wrapper for printf. */
758
759void
31043f6c 760gfc_status (const char *cmsgid, ...)
6de9cd9a
DN
761{
762 va_list argp;
763
31043f6c 764 va_start (argp, cmsgid);
6de9cd9a 765
31043f6c 766 vprintf (_(cmsgid), argp);
6de9cd9a
DN
767
768 va_end (argp);
769}
770
771
772/* Subroutine for outputting a single char so that we don't have to go
773 around creating a lot of 1-character strings. */
774
775void
776gfc_status_char (char c)
777{
778 putchar (c);
779}
780
781
1f2959f0 782/* Report the number of warnings and errors that occurred to the caller. */
6de9cd9a
DN
783
784void
785gfc_get_errors (int *w, int *e)
786{
6de9cd9a
DN
787 if (w != NULL)
788 *w = warnings;
789 if (e != NULL)
790 *e = errors;
791}
This page took 0.775401 seconds and 5 git commands to generate.