OSDN Git Service

Fix a typo.
[pf3gnuchains/gcc-fork.git] / gcc / fortran / error.c
index d028d5a..435fc16 100644 (file)
@@ -1,6 +1,6 @@
 /* Handle errors.
-   Copyright (C) 2000, 2001, 2002, 2003, 2004 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.
@@ -17,8 +17,8 @@ for more details.
 
 You should have received a copy of the GNU General Public License
 along with GCC; see the file COPYING.  If not, write to the Free
-Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-02111-1307, USA.  */
+Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301, USA.  */
 
 /* Handle the inevitable errors.  A major catch here is that things
    flagged as errors in one match subroutine can conceivably be legal
@@ -28,23 +28,14 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 
 #include "config.h"
 #include "system.h"
-
-#include <string.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-
 #include "flags.h"
 #include "gfortran.h"
 
 int gfc_suppress_error = 0;
 
-static int terminal_width, buffer_flag, errors,
-  use_warning_buffer, warnings;
-
-static char *error_ptr, *warning_ptr;
+static int terminal_width, buffer_flag, errors, warnings;
 
-static gfc_error_buf error_buffer, warning_buffer;
+static gfc_error_buf error_buffer, warning_buffer, *cur_error_buffer;
 
 
 /* Per-file error initialization.  */
@@ -76,23 +67,39 @@ error_char (char c)
 {
   if (buffer_flag)
     {
-      if (use_warning_buffer)
-       {
-         *warning_ptr++ = c;
-         if (warning_ptr - warning_buffer.message >= MAX_ERROR_MESSAGE)
-           gfc_internal_error ("error_char(): Warning buffer overflow");
-       }
-      else
+      if (cur_error_buffer->index >= cur_error_buffer->allocated)
        {
-         *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
     {
       if (c != 0)
-       fputc (c, stderr);
+       {
+         /* We build up complete lines before handing things
+            over to the library in order to speed up error printing.  */
+         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')
+           {
+             line[index] = '\0';
+             fputs (line, stderr);
+             index = 0;
+           }
+       }
     }
 }
 
@@ -111,7 +118,7 @@ error_string (const char *p)
    locus.  Calls error_printf() recursively, but the recursion is at
    most one level deep.  */
 
-static void error_printf (const char *, ...) ATTRIBUTE_PRINTF_1;
+static void error_printf (const char *, ...) ATTRIBUTE_GCC_GFC(1,2);
 
 static void
 show_locus (int offset, locus * loc)
@@ -127,7 +134,13 @@ show_locus (int offset, locus * loc)
 
   lb = loc->lb;
   f = lb->file;
-  error_printf ("In file %s:%d\n", f->filename, lb->linenum);
+  error_printf ("In file %s:%d\n", f->filename,
+#ifdef USE_MAPPED_LOCATION
+               LOCATION_LINE (lb->location)
+#else
+               lb->linenum
+#endif
+               );
 
   for (;;)
     {
@@ -301,7 +314,7 @@ separate:
 #define IBUF_LEN 30
 #define MAX_ARGS 10
 
-static void
+static void ATTRIBUTE_GCC_GFC(2,0)
 error_print (const char *type, const char *format0, va_list argp)
 {
   char c, *p, int_buf[IBUF_LEN], c_arg[MAX_ARGS], *cp_arg[MAX_ARGS];
@@ -436,12 +449,12 @@ error_print (const char *type, const char *format0, va_list argp)
 /* 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);
 }
 
@@ -449,7 +462,7 @@ error_printf (const char *format, ...)
 /* Issue a warning.  */
 
 void
-gfc_warning (const char *format, ...)
+gfc_warning (const char *nocmsgid, ...)
 {
   va_list argp;
 
@@ -457,26 +470,42 @@ gfc_warning (const char *format, ...)
     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
-   and error is generated.  */
+   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;
@@ -490,18 +519,9 @@ gfc_notify_std (int std, const char *format, ...)
   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)
     {
@@ -510,11 +530,11 @@ gfc_notify_std (int std, const char *format, ...)
       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');
@@ -525,7 +545,7 @@ gfc_notify_std (int std, const char *format, ...)
 /* 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;
@@ -537,8 +557,8 @@ gfc_warning_now (const char *format, ...)
   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');
@@ -564,7 +584,8 @@ gfc_warning_check (void)
   if (warning_buffer.flag)
     {
       warnings++;
-      fputs (warning_buffer.message, stderr);
+      if (warning_buffer.message != NULL)
+       fputs (warning_buffer.message, stderr);
       warning_buffer.flag = 0;
     }
 }
@@ -573,7 +594,7 @@ gfc_warning_check (void)
 /* Issue an error.  */
 
 void
-gfc_error (const char *format, ...)
+gfc_error (const char *nocmsgid, ...)
 {
   va_list argp;
 
@@ -581,13 +602,13 @@ gfc_error (const char *format, ...)
     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');
@@ -597,38 +618,42 @@ gfc_error (const char *format, ...)
 /* 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);
@@ -652,7 +677,7 @@ gfc_internal_error (const char *format, ...)
   error_print ("", format, argp);
   va_end (argp);
 
-  exit (4);
+  exit (ICE_EXIT_CODE);
 }
 
 
@@ -678,8 +703,12 @@ gfc_error_check (void)
   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;
@@ -693,7 +722,7 @@ gfc_push_error (gfc_error_buf * err)
 {
   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;
 }
@@ -706,20 +735,35 @@ gfc_pop_error (gfc_error_buf * err)
 {
   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);
 }
@@ -735,7 +779,7 @@ gfc_status_char (char c)
 }
 
 
-/* Report the number of warnings and errors that occured to the caller.  */
+/* Report the number of warnings and errors that occurred to the caller.  */
 
 void
 gfc_get_errors (int *w, int *e)