2005-07-14 Jakub Jelinek <jakub@redhat.com>
+ * gfortran.h (MAX_ERROR_MESSAGE): Remove.
+ (gfc_error_buf): Add allocated and index fields. Change message
+ field from array to a pointer.
+ * error.c (use_warning_buffer, error_ptr, warning_ptr): Remove.
+ (cur_error_buffer): New variable.
+ (error_char): Use cur_error_buffer->{message,index} instead of
+ {warning,error}_{buffer.message,ptr}. Reallocate message buffer
+ if too small.
+ (gfc_warning, gfc_notify_std, gfc_error, gfc_error_now): Setup
+ cur_error_buffer and its index rather than {warning,error}_ptr
+ and use_warning_buffer.
+ (gfc_warning_check, gfc_error_check): Don't print anything if
+ message is NULL.
+ (gfc_push_error): Allocate saved message with xstrdup.
+ (gfc_pop_error): Free saved message with gfc_free.
+ (gfc_free_error): New function.
+ * primary.c (match_complex_constant): Call gfc_free_error if
+ gfc_pop_error will not be called.
+ * match.c (gfc_match_st_function): Likewise.
+
PR fortran/22417
* scanner.c (preprocessor_line): Don't treat flag 3 as the start of a new
file. Fix file left but not entered warning.
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);
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);
if (buffer_flag == 0)
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)
{
if (warning_buffer.flag)
{
warnings++;
- fputs (warning_buffer.message, stderr);
+ if (warning_buffer.message != NULL)
+ fputs (warning_buffer.message, stderr);
warning_buffer.flag = 0;
}
}
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);
if (buffer_flag == 0)
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;
if (error_buffer.flag)
{
errors++;
- fputs (error_buffer.message, stderr);
+ if (error_buffer.message != NULL)
+ fputs (error_buffer.message, stderr);
error_buffer.flag = 0;
}
{
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);
}
#define GFC_MAX_LINE 132 /* Characters beyond this are not seen. */
#define GFC_MAX_DIMENSIONS 7 /* Maximum dimensions in an array. */
#define GFC_LETTERS 26 /* Number of letters in the alphabet. */
-#define MAX_ERROR_MESSAGE 1000 /* Maximum length of an error message. */
#define free(x) Use_gfc_free_instead_of_free()
#define gfc_is_whitespace(c) ((c==' ') || (c=='\t'))
typedef struct gfc_error_buf
{
int flag;
- char message[MAX_ERROR_MESSAGE];
+ size_t allocated, index;
+ char *message;
} gfc_error_buf;
void gfc_error_init_1 (void);
void gfc_push_error (gfc_error_buf *);
void gfc_pop_error (gfc_error_buf *);
+void gfc_free_error (gfc_error_buf *);
void gfc_status (const char *, ...) ATTRIBUTE_PRINTF_1;
void gfc_status_char (char);