/* Handle errors.
- Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation,
- Inc.
+ Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software
+ Foundation, Inc.
Contributed by Andy Vaught & Niels Kristian Bech Jensen
This file is part of GCC.
int gfc_suppress_error = 0;
-static int terminal_width, buffer_flag, errors,
- use_warning_buffer, warnings;
+static int terminal_width, buffer_flag, errors, warnings;
-static char *error_ptr, *warning_ptr;
-
-static gfc_error_buf error_buffer, warning_buffer;
+static gfc_error_buf error_buffer, warning_buffer, *cur_error_buffer;
/* Per-file error initialization. */
{
if (buffer_flag)
{
- if (use_warning_buffer)
+ if (cur_error_buffer->index >= cur_error_buffer->allocated)
{
- *warning_ptr++ = c;
- if (warning_ptr - warning_buffer.message >= MAX_ERROR_MESSAGE)
- gfc_internal_error ("error_char(): Warning buffer overflow");
- }
- else
- {
- *error_ptr++ = c;
- if (error_ptr - error_buffer.message >= MAX_ERROR_MESSAGE)
- gfc_internal_error ("error_char(): Error buffer overflow");
+ cur_error_buffer->allocated =
+ cur_error_buffer->allocated
+ ? cur_error_buffer->allocated * 2 : 1000;
+ cur_error_buffer->message
+ = xrealloc (cur_error_buffer->message,
+ cur_error_buffer->allocated);
}
+ cur_error_buffer->message[cur_error_buffer->index++] = c;
}
else
{
{
/* We build up complete lines before handing things
over to the library in order to speed up error printing. */
- static char line[MAX_ERROR_MESSAGE + 1];
- static int index = 0;
+ static char *line;
+ static size_t allocated = 0, index = 0;
+ if (index + 1 >= allocated)
+ {
+ allocated = allocated ? allocated * 2 : 1000;
+ line = xrealloc (line, allocated);
+ }
line[index++] = c;
- if (c == '\n' || index == MAX_ERROR_MESSAGE)
+ if (c == '\n')
{
line[index] = '\0';
fputs (line, stderr);
/* Wrapper for error_print(). */
static void
-error_printf (const char *format, ...)
+error_printf (const char *nocmsgid, ...)
{
va_list argp;
- va_start (argp, format);
- error_print ("", format, argp);
+ va_start (argp, nocmsgid);
+ error_print ("", _(nocmsgid), argp);
va_end (argp);
}
/* Issue a warning. */
void
-gfc_warning (const char *format, ...)
+gfc_warning (const char *nocmsgid, ...)
{
va_list argp;
return;
warning_buffer.flag = 1;
- warning_ptr = warning_buffer.message;
- use_warning_buffer = 1;
+ warning_buffer.index = 0;
+ cur_error_buffer = &warning_buffer;
- va_start (argp, format);
+ va_start (argp, nocmsgid);
if (buffer_flag == 0)
warnings++;
- error_print ("Warning:", format, argp);
+ error_print (_("Warning:"), _(nocmsgid), argp);
va_end (argp);
error_char ('\0');
}
+/* Whether, for a feature included in a given standard set (GFC_STD_*),
+ we should issue an error or a warning, or be quiet. */
+
+notification
+gfc_notification_std (int std)
+{
+ bool warning;
+
+ warning = ((gfc_option.warn_std & std) != 0) && !inhibit_warnings;
+ if ((gfc_option.allow_std & std) != 0 && !warning)
+ return SILENT;
+
+ return warning ? WARNING : ERROR;
+}
+
+
/* Possibly issue a warning/error about use of a nonstandard (or deleted)
feature. An error/warning will be issued if the currently selected
standard does not contain the requested bits. Return FAILURE if
an error is generated. */
try
-gfc_notify_std (int std, const char *format, ...)
+gfc_notify_std (int std, const char *nocmsgid, ...)
{
va_list argp;
bool warning;
if (gfc_suppress_error)
return warning ? SUCCESS : FAILURE;
- if (warning)
- {
- warning_buffer.flag = 1;
- warning_ptr = warning_buffer.message;
- use_warning_buffer = 1;
- }
- else
- {
- error_buffer.flag = 1;
- error_ptr = error_buffer.message;
- use_warning_buffer = 0;
- }
+ cur_error_buffer = warning ? &warning_buffer : &error_buffer;
+ cur_error_buffer->flag = 1;
+ cur_error_buffer->index = 0;
if (buffer_flag == 0)
{
else
errors++;
}
- va_start (argp, format);
+ va_start (argp, nocmsgid);
if (warning)
- error_print ("Warning:", format, argp);
+ error_print (_("Warning:"), _(nocmsgid), argp);
else
- error_print ("Error:", format, argp);
+ error_print (_("Error:"), _(nocmsgid), argp);
va_end (argp);
error_char ('\0');
/* Immediate warning (i.e. do not buffer the warning). */
void
-gfc_warning_now (const char *format, ...)
+gfc_warning_now (const char *nocmsgid, ...)
{
va_list argp;
int i;
buffer_flag = 0;
warnings++;
- va_start (argp, format);
- error_print ("Warning:", format, argp);
+ va_start (argp, nocmsgid);
+ error_print (_("Warning:"), _(nocmsgid), argp);
va_end (argp);
error_char ('\0');
if (warning_buffer.flag)
{
warnings++;
- fputs (warning_buffer.message, stderr);
+ if (warning_buffer.message != NULL)
+ fputs (warning_buffer.message, stderr);
warning_buffer.flag = 0;
}
}
/* Issue an error. */
void
-gfc_error (const char *format, ...)
+gfc_error (const char *nocmsgid, ...)
{
va_list argp;
return;
error_buffer.flag = 1;
- error_ptr = error_buffer.message;
- use_warning_buffer = 0;
+ error_buffer.index = 0;
+ cur_error_buffer = &error_buffer;
- va_start (argp, format);
+ va_start (argp, nocmsgid);
if (buffer_flag == 0)
errors++;
- error_print ("Error:", format, argp);
+ error_print (_("Error:"), _(nocmsgid), argp);
va_end (argp);
error_char ('\0');
/* Immediate error. */
void
-gfc_error_now (const char *format, ...)
+gfc_error_now (const char *nocmsgid, ...)
{
va_list argp;
int i;
error_buffer.flag = 1;
- error_ptr = error_buffer.message;
+ error_buffer.index = 0;
+ cur_error_buffer = &error_buffer;
i = buffer_flag;
buffer_flag = 0;
errors++;
- va_start (argp, format);
- error_print ("Error:", format, argp);
+ va_start (argp, nocmsgid);
+ error_print (_("Error:"), _(nocmsgid), argp);
va_end (argp);
error_char ('\0');
buffer_flag = i;
+
+ if (flag_fatal_errors)
+ exit (1);
}
/* Fatal error, never returns. */
void
-gfc_fatal_error (const char *format, ...)
+gfc_fatal_error (const char *nocmsgid, ...)
{
va_list argp;
buffer_flag = 0;
- va_start (argp, format);
- error_print ("Fatal Error:", format, argp);
+ va_start (argp, nocmsgid);
+ error_print (_("Fatal Error:"), _(nocmsgid), argp);
va_end (argp);
exit (3);
error_print ("", format, argp);
va_end (argp);
- exit (4);
+ exit (ICE_EXIT_CODE);
}
if (error_buffer.flag)
{
errors++;
- fputs (error_buffer.message, stderr);
+ if (error_buffer.message != NULL)
+ fputs (error_buffer.message, stderr);
error_buffer.flag = 0;
+
+ if (flag_fatal_errors)
+ exit (1);
}
return rc;
{
err->flag = error_buffer.flag;
if (error_buffer.flag)
- strcpy (err->message, error_buffer.message);
+ err->message = xstrdup (error_buffer.message);
error_buffer.flag = 0;
}
{
error_buffer.flag = err->flag;
if (error_buffer.flag)
- strcpy (error_buffer.message, err->message);
+ {
+ size_t len = strlen (err->message) + 1;
+ gcc_assert (len <= error_buffer.allocated);
+ memcpy (error_buffer.message, err->message, len);
+ gfc_free (err->message);
+ }
+}
+
+
+/* Free a pushed error state, but keep the current error state. */
+
+void
+gfc_free_error (gfc_error_buf * err)
+{
+ if (err->flag)
+ gfc_free (err->message);
}
/* Debug wrapper for printf. */
void
-gfc_status (const char *format, ...)
+gfc_status (const char *cmsgid, ...)
{
va_list argp;
- va_start (argp, format);
+ va_start (argp, cmsgid);
- vprintf (format, argp);
+ vprintf (_(cmsgid), argp);
va_end (argp);
}