OSDN Git Service

Daily bump.
[pf3gnuchains/gcc-fork.git] / gcc / diagnostic.c
index 8572913..634ff51 100644 (file)
@@ -1,5 +1,5 @@
-/* Top level of GNU C compiler
-   Copyright (C) 1999 Free Software Foundation, Inc.
+/* Language-independent diagnostic subroutines for the GNU C compiler
+   Copyright (C) 1999, 2000 Free Software Foundation, Inc.
 
 This file is part of GNU CC.
 
@@ -37,34 +37,45 @@ Boston, MA 02111-1307, USA.  */
 #include "insn-config.h"
 #include "toplev.h"
 #include "intl.h"
+#include "diagnostic.h"
 
+#define obstack_chunk_alloc xmalloc
+#define obstack_chunk_free  free
 
 /* Prototypes. */
-static void notice PVPROTO((const char *s, ...)) ATTRIBUTE_PRINTF_1;
-static void vmessage PROTO((const char *, const char *, va_list));
-static void v_message_with_file_and_line PROTO((const char *, int, int,
+static int doing_line_wrapping PARAMS ((void));
+
+static char *vbuild_message_string PARAMS ((const char *, va_list));
+static char *build_message_string PARAMS ((const char *, ...))
+     ATTRIBUTE_PRINTF_1;
+static char *build_location_prefix PARAMS ((const char *, int, int));
+static void output_notice PARAMS ((output_buffer *, const char *));
+static void line_wrapper_printf PARAMS ((FILE *, const char *, ...))
+     ATTRIBUTE_PRINTF_2;
+static void vline_wrapper_message_with_location PARAMS ((const char *, int,
+                                                        int, const char *,
+                                                        va_list));
+static void notice PARAMS ((const char *s, ...)) ATTRIBUTE_PRINTF_1;
+static void v_message_with_file_and_line PARAMS ((const char *, int, int,
+                                                 const char *, va_list));
+static void v_message_with_decl PARAMS ((tree, int, const char *, va_list));
+static void file_and_line_for_asm PARAMS ((rtx, const char **, int *));
+static void v_error_with_file_and_line PARAMS ((const char *, int,
                                                const char *, va_list));
-static void v_message_with_decl PROTO((tree, int, const char *, va_list));
-static void file_and_line_for_asm PROTO((rtx, char **, int *));
-static void v_error_with_file_and_line PROTO((const char *, int,
-                                             const char *, va_list));
-static void v_error_with_decl PROTO((tree, const char *, va_list));
-static void v_error_for_asm PROTO((rtx, const char *, va_list));
-static void verror PROTO((const char *, va_list));
-static void vfatal PROTO((const char *, va_list)) ATTRIBUTE_NORETURN;
-static void v_warning_with_file_and_line PROTO ((const char *, int,
-                                                const char *, va_list));
-static void v_warning_with_decl PROTO((tree, const char *, va_list));
-static void v_warning_for_asm PROTO((rtx, const char *, va_list));
-static void vwarning PROTO((const char *, va_list));
-static void vpedwarn PROTO((const char *, va_list));
-static void v_pedwarn_with_decl PROTO((tree, const char *, va_list));
-static void v_pedwarn_with_file_and_line PROTO((const char *, int,
-                                               const char *, va_list));
-static void vsorry PROTO((const char *, va_list));
-static void report_file_and_line PROTO ((const char *, int, int));
-static void vnotice PROTO ((FILE *, const char *, va_list));
-
+static void v_error_with_decl PARAMS ((tree, const char *, va_list));
+static void v_error_for_asm PARAMS ((rtx, const char *, va_list));
+static void vfatal PARAMS ((const char *, va_list)) ATTRIBUTE_NORETURN;
+static void v_warning_with_file_and_line PARAMS ((const char *, int,
+                                                 const char *, va_list));
+static void v_warning_with_decl PARAMS ((tree, const char *, va_list));
+static void v_warning_for_asm PARAMS ((rtx, const char *, va_list));
+static void v_pedwarn_with_decl PARAMS ((tree, const char *, va_list));
+static void v_pedwarn_with_file_and_line PARAMS ((const char *, int,
+                                                 const char *, va_list));
+static void vsorry PARAMS ((const char *, va_list));
+static void report_file_and_line PARAMS ((const char *, int, int));
+static void vnotice PARAMS ((FILE *, const char *, va_list));
+static void set_real_maximum_length PARAMS ((output_buffer *));
 
 extern int rtl_dump_and_exit;
 extern int inhibit_warnings;
@@ -72,6 +83,13 @@ extern int warnings_are_errors;
 extern int warningcount;
 extern int errorcount;
 
+/* Front-end specific tree formatter, if non-NULL.  */
+printer_fn lang_printer = NULL;
+
+/* An output_buffer surrogate for stderr.  */
+static output_buffer global_output_buffer;
+output_buffer *diagnostic_buffer = &global_output_buffer;
+
 static int need_error_newline;
 
 /* Function of last error message;
@@ -85,10 +103,517 @@ static int last_error_tick;
 /* Called by report_error_function to print out function name.
  * Default may be overridden by language front-ends.  */
 
-void (*print_error_function) PROTO((const char *)) =
+void (*print_error_function) PARAMS ((const char *)) =
   default_print_error_function;
 
+/* Maximum characters per line in automatic line wrapping mode.
+   Zero means don't wrap lines. */
+
+int diagnostic_message_length_per_line;
+
+/* Used to control every diagnostic message formatting.  Front-ends should
+   call set_message_prefixing_rule to set up their politics.  */
+static int current_prefixing_rule;
 \f
+/* Initialize the diagnostic message outputting machinery.  */
+
+void
+initialize_diagnostics ()
+{
+  /* By default, we don't line-wrap messages.  */
+  diagnostic_message_length_per_line = 0;
+  set_message_prefixing_rule (DIAGNOSTICS_SHOW_PREFIX_ONCE);
+  /* Proceed to actual initialization.  */
+  default_initialize_buffer (diagnostic_buffer);
+}
+
+/* Predicate. Return 1 if we're in automatic line wrapping mode.  */
+
+static int
+doing_line_wrapping ()
+{
+  return diagnostic_message_length_per_line > 0;
+}
+
+void
+set_message_prefixing_rule (rule)
+     int rule;
+{
+  current_prefixing_rule = rule;
+}
+
+/* Returns true if BUFFER is in line-wrappind mode.  */
+int
+output_is_line_wrapping (buffer)
+     output_buffer *buffer;
+{
+  return buffer->ideal_maximum_length > 0;
+}
+
+/* Return BUFFER's prefix.  */
+const char *
+output_get_prefix (buffer)
+     const output_buffer *buffer;
+{
+  return buffer->prefix;
+}
+
+/* Subroutine of output_set_maximum_length.  Set up BUFFER's
+   internal maximum characters per line.  */
+static void
+set_real_maximum_length (buffer)
+     output_buffer *buffer;
+{
+  /* If we're told not to wrap lines then do the obvious thing.  */
+  if (! output_is_line_wrapping (buffer))
+    buffer->maximum_length = buffer->ideal_maximum_length;
+  else
+    {
+      int prefix_length = buffer->prefix ? strlen (buffer->prefix) : 0;
+      /* If the prefix is ridiculously too long, output at least
+         32 characters.  */
+      if (buffer->ideal_maximum_length - prefix_length < 32)
+        buffer->maximum_length = buffer->ideal_maximum_length + 32;
+      else
+        buffer->maximum_length = buffer->ideal_maximum_length;
+    }
+}
+
+/* Sets the number of maximum characters per line BUFFER can output
+   in line-wrapping mode.  A LENGTH value 0 suppresses line-wrapping.  */
+void
+output_set_maximum_length (buffer, length)
+     output_buffer *buffer;
+     int length;
+{
+  buffer->ideal_maximum_length = length;
+  set_real_maximum_length (buffer);
+}
+
+/* Sets BUFFER's PREFIX.  */
+void
+output_set_prefix (buffer, prefix)
+     output_buffer *buffer;
+     const char *prefix;
+{
+  buffer->prefix = prefix;
+  set_real_maximum_length (buffer);
+  buffer->emitted_prefix_p = 0;
+}
+
+/* Free BUFFER's prefix, a previously malloc()'d string.  */
+
+void
+output_destroy_prefix (buffer)
+     output_buffer *buffer;
+{
+  if (buffer->prefix)
+    {
+      free ((char *) buffer->prefix);
+      buffer->prefix = NULL;
+    }
+}
+
+/* Construct an output BUFFER with PREFIX and of MAXIMUM_LENGTH
+   characters per line.  */
+void
+init_output_buffer (buffer, prefix, maximum_length)
+     output_buffer *buffer;
+     const char *prefix;
+     int maximum_length;
+{
+  obstack_init (&buffer->obstack);
+  buffer->ideal_maximum_length = maximum_length;
+  buffer->line_length = 0;
+  output_set_prefix (buffer, prefix);
+  buffer->emitted_prefix_p = 0;
+  buffer->prefixing_rule = current_prefixing_rule;
+  
+  buffer->cursor = NULL;
+}
+
+/* Initialize BUFFER with a NULL prefix and current diagnostic message
+   length cutoff.  */
+void
+default_initialize_buffer (buffer)
+     output_buffer *buffer;
+{
+  init_output_buffer (buffer, NULL, diagnostic_message_length_per_line);
+}
+
+/* Recompute diagnostic_buffer's attributes to reflect any change
+   in diagnostic formatting global options.  */
+void
+reshape_diagnostic_buffer ()
+{
+  diagnostic_buffer->ideal_maximum_length = diagnostic_message_length_per_line;
+  diagnostic_buffer->prefixing_rule = current_prefixing_rule;
+  set_real_maximum_length (diagnostic_buffer);
+}
+
+/* Reinitialize BUFFER.  */
+void
+output_clear (buffer)
+     output_buffer *buffer;
+{
+  obstack_free (&buffer->obstack, obstack_base (&buffer->obstack));
+  buffer->line_length = 0;
+  buffer->cursor = NULL;
+  buffer->emitted_prefix_p = 0;
+}
+
+/* Finishes to construct a NULL-terminated character string representing
+   the BUFFERed message.  */
+const char *
+output_finish (buffer)
+     output_buffer *buffer;
+{
+  obstack_1grow (&buffer->obstack, '\0');
+  return (const char *) obstack_finish (&buffer->obstack);
+}
+
+/* Return the amount of characters BUFFER can accept to
+   make a full line.  */
+int
+output_space_left (buffer)
+     const output_buffer *buffer;
+{
+  return buffer->maximum_length - buffer->line_length;
+}
+
+/* Write out BUFFER's prefix.  */
+void
+output_emit_prefix (buffer)
+     output_buffer *buffer;
+{
+  if (buffer->prefix)
+    {
+      switch (buffer->prefixing_rule)
+        {
+        default:
+        case DIAGNOSTICS_SHOW_PREFIX_NEVER:
+          break;
+
+        case DIAGNOSTICS_SHOW_PREFIX_ONCE:
+          if (buffer->emitted_prefix_p)
+            break;
+          else
+            buffer->emitted_prefix_p = 1;
+          /* Fall through.  */
+
+        case DIAGNOSTICS_SHOW_PREFIX_EVERY_LINE:
+          buffer->line_length += strlen (buffer->prefix);
+          obstack_grow
+            (&buffer->obstack, buffer->prefix, buffer->line_length);
+          break;
+        }
+    }
+}
+
+/* Have BUFFER start a new line.  */
+void
+output_add_newline (buffer)
+     output_buffer *buffer;
+{
+  obstack_1grow (&buffer->obstack, '\n');
+  buffer->line_length = 0;
+}
+
+/* Appends a character to BUFFER.  */
+void
+output_add_character (buffer, c)
+     output_buffer *buffer;
+     int c;
+{
+  if (output_is_line_wrapping (buffer) && output_space_left (buffer) <= 0)
+    output_add_newline (buffer);
+  obstack_1grow (&buffer->obstack, c);
+  ++buffer->line_length;
+}
+
+/* Adds a space to BUFFER.  */
+void
+output_add_space (buffer)
+     output_buffer *buffer;
+{
+  if (output_is_line_wrapping (buffer) && output_space_left (buffer) <= 0)
+    {
+      output_add_newline (buffer);
+      return;
+    }
+  obstack_1grow (&buffer->obstack, ' ');
+  ++buffer->line_length;
+}
+
+/* Add the stringified version of an integer to BUFFER.  */
+void
+output_add_integer (buffer, i)
+     output_buffer *buffer;
+     HOST_WIDE_INT i;
+{
+  /* This must be large enough to hold any printed integer or
+     floating-point value.  */
+  static char digit_buffer[128];
+
+  sprintf (digit_buffer, HOST_WIDE_INT_PRINT_DEC, i);
+  output_add_string (buffer, digit_buffer);
+}
+
+/* Append a string deliminated by START and END to BUFFER.  No wrapping is
+   done.  The caller must ensure that it is safe to do so.  */
+
+void
+output_append (buffer, start, end)
+     output_buffer *buffer;
+     const char *start;
+     const char *end;
+{
+  int n;
+
+  /* Emit prefix and skip whitespace if we're starting a new line.  */
+  if (buffer->line_length == 0)
+    {
+      output_emit_prefix (buffer);
+      while (start != end && *start == ' ')
+        ++start;
+    }
+  n = end - start;
+  obstack_grow (&buffer->obstack, start, n);
+  buffer->line_length += n;
+}
+
+/* Wrap a STRing into BUFFER.  */
+
+void
+output_add_string (buffer, str)
+     output_buffer *buffer;
+     const char *str;
+{
+  const char *p = str;
+
+  if (!output_is_line_wrapping (buffer))
+    output_append (buffer, str, str + strlen (str));
+  else while (*str)
+    {
+      while (*p && *p != ' ' && *p != '\n')
+        ++p;
+      
+      if (p - str < output_space_left (buffer))
+        output_append (buffer, str, p);
+      else
+        {
+          output_add_newline (buffer);
+          output_append (buffer, str, p);
+        }
+      
+      while (*p && *p == '\n')
+        {
+          output_add_newline (buffer);
+          ++p;
+        }
+
+      str = p++;
+    }
+}
+
+/* Flush the content of BUFFER onto FILE and reinitialize BUFFER.  */
+
+void
+output_flush_on (buffer, file)
+     output_buffer *buffer;
+     FILE *file;
+{
+  const char *text = output_finish (buffer);
+  fputs (text, file);
+  output_clear (buffer);
+}
+
+/* Format MESSAGE into BUFFER.  */
+void
+output_format (buffer, msg)
+     output_buffer *buffer;
+     const char *msg;
+{
+  for (buffer->cursor = msg; *buffer->cursor; ++buffer->cursor)
+    {
+      /* Ignore text.  */
+      if (*buffer->cursor != '%')
+        {
+          output_add_character (buffer, *buffer->cursor);
+          continue;
+        }
+
+      /* We got a '%'.  Let's see what happens.  */
+      ++buffer->cursor;
+
+      /* Let's handle the traditional cases.  */
+      if (*buffer->cursor == 's')
+        output_add_string (buffer, va_arg (buffer->format_args, const char *));
+      else if (*buffer->cursor == 'd')
+        output_add_integer (buffer, va_arg (buffer->format_args, int));
+      else if (*buffer->cursor == '%')
+        /* It was a '%%'.  Just output a '%'.  */
+        output_add_character (buffer, '%');
+      else if (lang_printer)
+        (*lang_printer) (buffer);
+      else
+        {
+          /* Hmmm.  The front-end failed to install a format translator
+             but called us with an unrecognized format.  Sorry.  */
+          abort();
+        }
+    }
+  output_finish (buffer);
+}
+
+static char *
+vbuild_message_string (msgid, ap)
+     const char *msgid;
+     va_list ap;
+{
+  char *str;
+
+  vasprintf (&str, msgid, ap);
+  return str;
+}
+
+/*  Return a malloc'd string containing MSGID formatted a la
+    printf.  The caller is reponsible for freeing the memory.  */
+
+static char *
+build_message_string VPARAMS ((const char *msgid, ...))
+{
+#ifndef ANSI_PROTOTYPES
+  const char *msgid;
+#endif
+  va_list ap;
+  char *str;
+
+  VA_START (ap, msgid);
+
+#ifndef ANSI_PROTOTYPES
+  msgid = va_arg (ap, const char *);
+#endif
+
+  str = vbuild_message_string (msgid, ap);
+
+  va_end (ap);
+
+  return str;
+}
+
+
+/* Return a malloc'd string describing a location.  The caller is
+   responsible for freeing the memory.  */
+
+static char *
+build_location_prefix (file, line, warn)
+     const char *file;
+     int line;
+     int warn;
+{
+  if (file)
+    {
+      if (warn)
+       return build_message_string ("%s:%d: warning: ", file, line);
+      else
+       return build_message_string ("%s:%d: ", file, line);
+    }
+  else
+    {
+      if (warn)
+       return build_message_string ("%s: warning: ", progname);
+      else
+       return build_message_string ("%s: ", progname);
+    }
+}
+
+/* Format a MESSAGE into BUFFER.  Automatically wrap lines.  */
+
+static void
+output_notice (buffer, msgid)
+     output_buffer *buffer;
+     const char *msgid;
+{
+  char *message = vbuild_message_string (msgid, buffer->format_args);
+
+  output_add_string (buffer, message);
+  free (message);
+}
+
+
+/* Format a message into BUFFER a la printf.  */
+
+void
+output_printf VPARAMS ((struct output_buffer *buffer, const char *msgid, ...))
+{
+#ifndef ANSI_PROTOTYPES
+  struct output_buffer *buffer;
+  const char *msgid;
+#endif
+  va_list ap;
+
+  VA_START (ap, msgid);
+
+#ifndef ANSI_PROTOTYPES
+  buffer = va_arg (ap, struct output_buffer *);
+  msgid = va_arg (ap, const char *);
+#endif
+
+  va_copy (buffer->format_args, ap);
+  output_notice (buffer, msgid);
+  va_end (buffer->format_args);
+}
+
+
+/* Format a MESSAGE into FILE.  Do line wrapping, starting new lines
+   with PREFIX.  */
+
+static void
+line_wrapper_printf VPARAMS ((FILE *file, const char *msgid, ...))
+{
+#ifndef ANSI_PROTOTYPES
+  FILE *file;
+  const char *msgid;
+#endif
+  output_buffer buffer;
+  
+  init_output_buffer (&buffer, NULL, diagnostic_message_length_per_line);
+  VA_START (buffer.format_args, msgid);
+
+#ifndef ANSI_PROTOTYPES
+  file = va_arg (buffer.format_args, FILE *);
+  msgid = va_arg (buffer.format_args, const char *);
+#endif  
+
+  output_notice (&buffer, msgid);
+  output_flush_on (&buffer, file);
+
+  va_end (buffer.format_args);
+}
+
+
+static void
+vline_wrapper_message_with_location (file, line, warn, msgid, ap)
+     const char *file;
+     int line;
+     int warn;
+     const char *msgid;
+     va_list ap;
+{
+  output_buffer buffer;
+  
+  init_output_buffer (&buffer, build_location_prefix (file, line, warn),
+                     diagnostic_message_length_per_line);
+  va_copy (buffer.format_args, ap);
+  output_notice (&buffer, msgid);
+  output_flush_on (&buffer, stderr);
+
+  output_destroy_prefix (&buffer);
+  fputc ('\n', stderr);
+}
+
+
 /* Print the message MSGID in FILE.  */
 
 static void
@@ -103,7 +628,7 @@ vnotice (file, msgid, ap)
 /* Print MSGID on stderr.  */
 
 static void
-notice VPROTO((const char *msgid, ...))
+notice VPARAMS ((const char *msgid, ...))
 {
 #ifndef ANSI_PROTOTYPES
   char *msgid;
@@ -137,20 +662,6 @@ report_file_and_line (file, line, warn)
     notice ("warning: ");
 }
 
-/* Print a PREFIXed MSGID.  */
-
-static void
-vmessage (prefix, msgid, ap)
-     const char *prefix;
-     const char *msgid;
-     va_list ap;
-{
-  if (prefix)
-    fprintf (stderr, "%s: ", prefix);
-
-  vfprintf (stderr, msgid, ap);
-}
-
 /* Print a message relevant to line LINE of file FILE.  */
 
 static void
@@ -176,9 +687,18 @@ v_message_with_decl (decl, warn, msgid, ap)
      va_list ap;
 {
   const char *p;
+  output_buffer buffer;
 
-  report_file_and_line (DECL_SOURCE_FILE (decl),
-                       DECL_SOURCE_LINE (decl), warn);
+  if (doing_line_wrapping ())
+    {
+      init_output_buffer
+        (&buffer, build_location_prefix
+         (DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl), warn),
+         diagnostic_message_length_per_line);
+    }
+  else
+    report_file_and_line (DECL_SOURCE_FILE (decl),
+                          DECL_SOURCE_LINE (decl), warn);
 
   /* Do magic to get around lack of varargs support for insertion
      of arguments into existing list.  We know that the decl is first;
@@ -199,20 +719,21 @@ v_message_with_decl (decl, warn, msgid, ap)
 
   if (p > _(msgid))                    /* Print the left-hand substring.  */
     {
-      char fmt[sizeof "%.255s"];
-      long width = p - _(msgid);
-             
-      if (width > 255L) width = 255L;  /* arbitrary */
-      sprintf (fmt, "%%.%lds", width);
-      fprintf (stderr, fmt, _(msgid));
+      if (doing_line_wrapping ())
+        output_printf (&buffer, "%.*s", (int)(p - _(msgid)), _(msgid));
+      else
+        fprintf (stderr, "%.*s", (int)(p - _(msgid)), _(msgid));
     }
 
   if (*p == '%')               /* Print the name.  */
     {
       const char *n = (DECL_NAME (decl)
                 ? (*decl_printable_name) (decl, 2)
-                : "((anonymous))");
-      fputs (n, stderr);
+                : _("((anonymous))"));
+      if (doing_line_wrapping ())
+        output_add_string (&buffer, n);
+      else
+        fputs (n, stderr);
       while (*p)
        {
          ++p;
@@ -222,8 +743,23 @@ v_message_with_decl (decl, warn, msgid, ap)
     }
 
   if (*p)                      /* Print the rest of the message.  */
-    vmessage ((char *)NULL, p, ap);
+    {
+      if (doing_line_wrapping ())
+        {
+         va_copy (buffer.format_args, ap);
+          output_notice (&buffer, p);
+          va_copy (ap, buffer.format_args);
+        }
+      else
+        vfprintf (stderr, p, ap);
+    }
 
+  if (doing_line_wrapping())
+    {
+      output_flush_on (&buffer, stderr);
+      output_destroy_prefix (&buffer);
+    }
+  
   fputc ('\n', stderr);
 }
 
@@ -232,7 +768,7 @@ v_message_with_decl (decl, warn, msgid, ap)
 static void
 file_and_line_for_asm (insn, pfile, pline)
      rtx insn;
-     char **pfile;
+     const char **pfile;
      int *pline;
 {
   rtx body = PATTERN (insn);
@@ -275,7 +811,10 @@ v_error_with_file_and_line (file, line, msgid, ap)
 {
   count_error (0);
   report_error_function (file);
-  v_message_with_file_and_line (file, line, 0, msgid, ap);
+  if (doing_line_wrapping ())
+    vline_wrapper_message_with_location (file, line, 0, msgid, ap);
+  else
+    v_message_with_file_and_line (file, line, 0, msgid, ap);
 }
 
 /* Report an error at the declaration DECL.
@@ -304,7 +843,7 @@ v_error_for_asm (insn, msgid, ap)
      const char *msgid;
      va_list ap;
 {
-  char *file;
+  const char *file;
   int line;
 
   count_error (0);
@@ -316,7 +855,7 @@ v_error_for_asm (insn, msgid, ap)
 
 /* Report an error at the current line number.  */
 
-static void
+void
 verror (msgid, ap)
      const char *msgid;
      va_list ap;
@@ -328,7 +867,7 @@ verror (msgid, ap)
 /* Report a fatal error at the current line number.  Allow a front end to
    intercept the message.  */
 
-static void (*fatal_function) PROTO ((const char *, va_list));
+static void (*fatal_function) PARAMS ((const char *, va_list));
 
 static void
 vfatal (msgid, ap)
@@ -354,7 +893,10 @@ v_warning_with_file_and_line (file, line, msgid, ap)
   if (count_error (1))
     {
       report_error_function (file);
-      v_message_with_file_and_line (file, line, 1, msgid, ap);
+      if (doing_line_wrapping ())
+        vline_wrapper_message_with_location (file, line, 1, msgid, ap);
+      else
+        v_message_with_file_and_line (file, line, 1, msgid, ap);
     }
 }
 
@@ -389,7 +931,7 @@ v_warning_for_asm (insn, msgid, ap)
 {
   if (count_error (1))
     {
-      char *file;
+      const char *file;
       int line;
 
       file_and_line_for_asm (insn, &file, &line);
@@ -401,7 +943,7 @@ v_warning_for_asm (insn, msgid, ap)
 
 /* Report a warning at the current line number.  */
 
-static void
+void
 vwarning (msgid, ap)
      const char *msgid;
      va_list ap;
@@ -412,7 +954,7 @@ vwarning (msgid, ap)
 /* These functions issue either warnings or errors depending on
    -pedantic-errors.  */
 
-static void
+void
 vpedwarn (msgid, ap)
      const char *msgid;
      va_list ap;
@@ -507,7 +1049,7 @@ count_error (warningp)
 
 /* Print a diagnistic MSGID on FILE.  */
 void
-fnotice VPROTO((FILE *file, const char *msgid, ...))
+fnotice VPARAMS ((FILE *file, const char *msgid, ...))
 {
 #ifndef ANSI_PROTOTYPES
   FILE *file;
@@ -549,7 +1091,7 @@ fatal_io_error (name)
 
 /* Issue a pedantic warning MSGID.  */
 void
-pedwarn VPROTO((const char *msgid, ...))
+pedwarn VPARAMS ((const char *msgid, ...))
 {
 #ifndef ANSI_PROTOTYPES
   const char *msgid;
@@ -568,7 +1110,7 @@ pedwarn VPROTO((const char *msgid, ...))
 
 /* Issue a pedantic waring about DECL.  */
 void
-pedwarn_with_decl VPROTO((tree decl, const char *msgid, ...))
+pedwarn_with_decl VPARAMS ((tree decl, const char *msgid, ...))
 {
 #ifndef ANSI_PROTOTYPES
   tree decl;
@@ -589,8 +1131,8 @@ pedwarn_with_decl VPROTO((tree decl, const char *msgid, ...))
 
 /* Same as above but within the context FILE and LINE. */
 void
-pedwarn_with_file_and_line VPROTO((const char *file, int line,
-                                  const char *msgid, ...))
+pedwarn_with_file_and_line VPARAMS ((const char *file, int line,
+                                    const char *msgid, ...))
 {
 #ifndef ANSI_PROTOTYPES
   const char *file;
@@ -613,7 +1155,7 @@ pedwarn_with_file_and_line VPROTO((const char *file, int line,
 
 /* Just apologize with MSGID.  */
 void
-sorry VPROTO((const char *msgid, ...))
+sorry VPARAMS ((const char *msgid, ...))
 {
 #ifndef ANSI_PROTOTYPES
   const char *msgid;
@@ -642,7 +1184,13 @@ announce_function (decl)
       if (rtl_dump_and_exit)
        fprintf (stderr, "%s ", IDENTIFIER_POINTER (DECL_NAME (decl)));
       else
-       fprintf (stderr, " %s", (*decl_printable_name) (decl, 2));
+        {
+          if (doing_line_wrapping ())
+            line_wrapper_printf
+              (stderr, " %s", (*decl_printable_name) (decl, 2));
+          else
+            fprintf (stderr, " %s", (*decl_printable_name) (decl, 2));
+        }
       fflush (stderr);
       need_error_newline = 1;
       last_error_function = current_function_decl;
@@ -658,22 +1206,58 @@ default_print_error_function (file)
 {
   if (last_error_function != current_function_decl)
     {
+      char *prefix = NULL;
+      output_buffer buffer;
+      
       if (file)
-       fprintf (stderr, "%s: ", file);
+        prefix = build_message_string ("%s: ", file);
 
+      if (doing_line_wrapping ())
+        init_output_buffer
+          (&buffer, prefix, diagnostic_message_length_per_line);
+      else
+        {
+          if (file)
+            fprintf (stderr, "%s: ", file);
+        }
+      
       if (current_function_decl == NULL)
-       notice ("At top level:\n");
+        {
+          if (doing_line_wrapping ())
+            output_printf (&buffer, "At top level:\n");
+          else
+            notice ("At top level:\n");
+        }
       else
        {
          if (TREE_CODE (TREE_TYPE (current_function_decl)) == METHOD_TYPE)
-           notice ("In method `%s':\n",
-                   (*decl_printable_name) (current_function_decl, 2));
+            {
+              if (doing_line_wrapping ())
+                output_printf
+                  (&buffer, "In method `%s':\n",
+                   (*decl_printable_name) (current_function_decl, 2));
+              else
+                notice ("In method `%s':\n",
+                        (*decl_printable_name) (current_function_decl, 2));
+            }
          else
-           notice ("In function `%s':\n",
-                   (*decl_printable_name) (current_function_decl, 2));
+            {
+              if (doing_line_wrapping ())
+                output_printf
+                  (&buffer, "In function `%s':\n",
+                   (*decl_printable_name) (current_function_decl, 2));
+              else
+                notice ("In function `%s':\n",
+                        (*decl_printable_name) (current_function_decl, 2));
+            }
        }
 
       last_error_function = current_function_decl;
+
+      if (doing_line_wrapping ())
+        output_flush_on (&buffer, stderr);
+      
+      free ((char*) prefix);
     }
 }
 
@@ -709,8 +1293,8 @@ report_error_function (file)
 }
 
 void
-error_with_file_and_line VPROTO((const char *file, int line,
-                                const char *msgid, ...))
+error_with_file_and_line VPARAMS ((const char *file, int line,
+                                  const char *msgid, ...))
 {
 #ifndef ANSI_PROTOTYPES
   const char *file;
@@ -732,7 +1316,7 @@ error_with_file_and_line VPROTO((const char *file, int line,
 }
 
 void
-error_with_decl VPROTO((tree decl, const char *msgid, ...))
+error_with_decl VPARAMS ((tree decl, const char *msgid, ...))
 {
 #ifndef ANSI_PROTOTYPES
   tree decl;
@@ -752,7 +1336,7 @@ error_with_decl VPROTO((tree decl, const char *msgid, ...))
 }
 
 void
-error_for_asm VPROTO((rtx insn, const char *msgid, ...))
+error_for_asm VPARAMS ((rtx insn, const char *msgid, ...))
 {
 #ifndef ANSI_PROTOTYPES
   rtx insn;
@@ -772,7 +1356,7 @@ error_for_asm VPROTO((rtx insn, const char *msgid, ...))
 }
 
 void
-error VPROTO((const char *msgid, ...))
+error VPARAMS ((const char *msgid, ...))
 {
 #ifndef ANSI_PROTOTYPES
   const char *msgid;
@@ -793,13 +1377,13 @@ error VPROTO((const char *msgid, ...))
 
 void
 set_fatal_function (f)
-     void (*f) PROTO ((const char *, va_list));
+     void (*f) PARAMS ((const char *, va_list));
 {
   fatal_function = f;
 }
 
 void
-fatal VPROTO((const char *msgid, ...))
+fatal VPARAMS ((const char *msgid, ...))
 {
 #ifndef ANSI_PROTOTYPES
   const char *msgid;
@@ -844,8 +1428,8 @@ _fatal_insn_not_found (insn, file, line, function)
 }
 
 void
-warning_with_file_and_line VPROTO((const char *file, int line,
-                                  const char *msgid, ...))
+warning_with_file_and_line VPARAMS ((const char *file, int line,
+                                    const char *msgid, ...))
 {
 #ifndef ANSI_PROTOTYPES
   const char *file;
@@ -867,7 +1451,7 @@ warning_with_file_and_line VPROTO((const char *file, int line,
 }
 
 void
-warning_with_decl VPROTO((tree decl, const char *msgid, ...))
+warning_with_decl VPARAMS ((tree decl, const char *msgid, ...))
 {
 #ifndef ANSI_PROTOTYPES
   tree decl;
@@ -887,7 +1471,7 @@ warning_with_decl VPROTO((tree decl, const char *msgid, ...))
 }
 
 void
-warning_for_asm VPROTO((rtx insn, const char *msgid, ...))
+warning_for_asm VPARAMS ((rtx insn, const char *msgid, ...))
 {
 #ifndef ANSI_PROTOTYPES
   rtx insn;
@@ -907,7 +1491,7 @@ warning_for_asm VPROTO((rtx insn, const char *msgid, ...))
 }
 
 void
-warning VPROTO((const char *msgid, ...))
+warning VPARAMS ((const char *msgid, ...))
 {
 #ifndef ANSI_PROTOTYPES
   const char *msgid;