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