OSDN Git Service

ch:
[pf3gnuchains/gcc-fork.git] / gcc / diagnostic.c
index 7124ecd..55f5dd3 100644 (file)
@@ -67,6 +67,7 @@ static void output_do_verbatim PARAMS ((output_buffer *,
                                         const char *, va_list *));
 static void output_to_stream PARAMS ((output_buffer *, FILE *));
 static void output_format PARAMS ((output_buffer *));
+static void output_indent PARAMS ((output_buffer *));
 
 static char *vbuild_message_string PARAMS ((const char *, va_list));
 static char *build_message_string PARAMS ((const char *, ...))
@@ -92,7 +93,6 @@ static void output_append_r PARAMS ((output_buffer *, const char *, int));
 static void wrap_text PARAMS ((output_buffer *, const char *, const char *));
 static void maybe_wrap_text PARAMS ((output_buffer *, const char *,
                                      const char *));
-static void clear_text_info PARAMS ((output_buffer *));
 static void clear_diagnostic_info PARAMS ((output_buffer *));
 
 static void default_diagnostic_starter PARAMS ((output_buffer *,
@@ -229,8 +229,12 @@ 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))
+  /* If we're told not to wrap lines then do the obvious thing.  In case
+   we'll emit prefix only once per diagnostic message, it is appropriate
+  not to increase unncessarily the line-length cut-off.  */
+  if (! output_is_line_wrapping (buffer)
+      || prefixing_policy (buffer) == DIAGNOSTICS_SHOW_PREFIX_ONCE
+      || prefixing_policy (buffer) == DIAGNOSTICS_SHOW_PREFIX_NEVER)
     line_wrap_cutoff (buffer) = ideal_line_wrap_cutoff (buffer);
   else
     {
@@ -267,6 +271,20 @@ output_set_prefix (buffer, prefix)
   output_prefix (buffer) = prefix;
   set_real_maximum_length (buffer);
   prefix_was_emitted_for (buffer) = 0;
+  output_indentation (buffer) = 0;
+}
+
+/*  Return a pointer to the last character emitted in the output
+    BUFFER area.  A NULL pointer means no character available.  */
+const char *
+output_last_position (buffer)
+     const output_buffer *buffer;
+{
+  const char *p = NULL;
+  
+  if (obstack_base (&buffer->obstack) != obstack_next_free (&buffer->obstack))
+    p = ((const char *) obstack_next_free (&buffer->obstack)) - 1;
+  return p;
 }
 
 /* Free BUFFER's prefix, a previously malloc'd string.  */
@@ -284,8 +302,8 @@ output_destroy_prefix (buffer)
 
 /* Zero out any text output so far in BUFFER.  */
 
-static void
-clear_text_info (buffer)
+void
+output_clear_message_text (buffer)
      output_buffer *buffer;
 {
   obstack_free (&buffer->obstack, obstack_base (&buffer->obstack));
@@ -301,6 +319,7 @@ clear_diagnostic_info (buffer)
   output_buffer_text_cursor (buffer) = NULL;
   output_buffer_ptr_to_format_args (buffer) = NULL;
   prefix_was_emitted_for (buffer) = 0;
+  output_indentation (buffer) = 0;
 }
 
 /* Construct an output BUFFER with PREFIX and of MAXIMUM_LENGTH
@@ -347,7 +366,7 @@ void
 output_clear (buffer)
      output_buffer *buffer;
 {
-  clear_text_info (buffer);
+  output_clear_message_text (buffer);
   clear_diagnostic_info (buffer);
 }
 
@@ -355,11 +374,18 @@ output_clear (buffer)
    the BUFFERed message.  */
 
 const char *
-output_finish (buffer)
+output_finalize_message (buffer)
      output_buffer *buffer;
 {
   obstack_1grow (&buffer->obstack, '\0');
-  return (const char *) obstack_finish (&buffer->obstack);
+  return output_message_text (buffer);
+}
+
+void
+flush_diagnostic_buffer ()
+{
+  output_to_stream (diagnostic_buffer, stderr);
+  fflush (stderr);
 }
 
 /* Return the amount of characters BUFFER can accept to
@@ -388,8 +414,12 @@ output_emit_prefix (buffer)
 
         case DIAGNOSTICS_SHOW_PREFIX_ONCE:
           if (prefix_was_emitted_for (buffer))
-            break;
-          /* Else fall through.  */
+            {
+              output_indent (buffer);
+              break;
+            }
+          output_indentation (buffer) += 3;          
+          /* Fall through.  */
 
         case DIAGNOSTICS_SHOW_PREFIX_EVERY_LINE:
           {
@@ -542,6 +572,17 @@ output_append (buffer, start, end)
   output_append_r (buffer, start, end - start);
 }
 
+static void
+output_indent (buffer)
+     output_buffer *buffer;
+{
+  int n = output_indentation (buffer);
+  int i;
+
+  for (i = 0; i < n; ++i)
+    output_add_character (buffer, ' ');
+}
+
 /* Wrap a text delimited by START and END into BUFFER.  */
 
 static void
@@ -550,6 +591,8 @@ wrap_text (buffer, start, end)
      const char *start;
      const char *end;
 {
+  int is_wrapping = output_is_line_wrapping (buffer);
+  
   while (start != end)
     {
       /* Dump anything bodered by whitespaces.  */ 
@@ -557,7 +600,7 @@ wrap_text (buffer, start, end)
         const char *p = start;
         while (p != end && *p != ' ' && *p != '\n')
           ++p;
-        if (p - start >= output_space_left (buffer))
+        if (is_wrapping && p - start >= output_space_left (buffer))
           output_add_newline (buffer);
         output_append (buffer, start, p);
         start = p;
@@ -608,9 +651,9 @@ output_to_stream (buffer, file)
      output_buffer *buffer;
      FILE *file;
 {
-  const char *text = output_finish (buffer);
+  const char *text = output_finalize_message (buffer);
   fputs (text, file);
-  clear_text_info (buffer);
+  output_clear_message_text (buffer);
 }
 
 /* Format a message pointed to by output_buffer_text_cursor (BUFFER) using
@@ -640,7 +683,7 @@ output_format (buffer)
         const char *p = output_buffer_text_cursor (buffer);
         while (*p && *p != '%')
           ++p;
-        maybe_wrap_text (buffer, output_buffer_text_cursor (buffer), p);
+        wrap_text (buffer, output_buffer_text_cursor (buffer), p);
         output_buffer_text_cursor (buffer) = p;
       }
 
@@ -701,6 +744,7 @@ output_format (buffer)
             output_unsigned_decimal
               (buffer, va_arg (output_buffer_format_args (buffer),
                                unsigned int));
+          break;
           
         case 'x':
           if (long_integer)
@@ -821,7 +865,7 @@ output_do_printf (buffer, msgid)
   char *message = vbuild_message_string (msgid,
                                          output_buffer_format_args (buffer));
 
-  output_add_string (buffer, message);
+  wrap_text (buffer, message, message + strlen (message));
   free (message);
 }
 
@@ -984,7 +1028,7 @@ diagnostic_for_decl (decl, msg, args_ptr, warn)
 
   if (count_error (warn))
     {
-      os = diagnostic_buffer->state;
+      os = output_buffer_state (diagnostic_buffer);
       report_error_function (DECL_SOURCE_FILE (decl));
       output_set_prefix
        (diagnostic_buffer, context_as_prefix
@@ -995,7 +1039,7 @@ diagnostic_for_decl (decl, msg, args_ptr, warn)
       finish_diagnostic ();
       output_destroy_prefix (diagnostic_buffer);
   
-      diagnostic_buffer->state = os;
+      output_buffer_state (diagnostic_buffer) = os;
     }
   diagnostic_lock--;
 }
@@ -1007,7 +1051,9 @@ int
 count_error (warningp)
      int warningp;
 {
-  if (warningp && inhibit_warnings)
+  if (warningp
+      && (inhibit_warnings
+          || (in_system_header && !warn_system_headers)))
     return 0;
 
   if (warningp && !warnings_are_errors)
@@ -1159,7 +1205,7 @@ sorry VPARAMS ((const char *msgid, ...))
   va_list ap;
   output_state os;
 
-  os = diagnostic_buffer->state;
+  os = output_buffer_state (diagnostic_buffer);
   VA_START (ap, msgid);
 
 #ifndef ANSI_PROTOTYPES
@@ -1173,7 +1219,7 @@ sorry VPARAMS ((const char *msgid, ...))
   output_buffer_text_cursor (diagnostic_buffer) = msgid;
   output_format (diagnostic_buffer);
   finish_diagnostic ();
-  diagnostic_buffer->state = os;
+  output_buffer_state (diagnostic_buffer) = os;
   va_end (ap);
 }
 
@@ -1208,29 +1254,27 @@ default_print_error_function (file)
       char *prefix = file ? build_message_string ("%s: ", file) : NULL;
       output_state os;
 
-      os = diagnostic_buffer->state;
+      os = output_buffer_state (diagnostic_buffer);
       output_set_prefix (diagnostic_buffer, prefix);
       
       if (current_function_decl == NULL)
-        {
           output_add_string (diagnostic_buffer, "At top level:");
-          output_add_newline (diagnostic_buffer);
-        }
       else
        {
          if (TREE_CODE (TREE_TYPE (current_function_decl)) == METHOD_TYPE)
             output_printf
-              (diagnostic_buffer, "In method `%s':\n",
+              (diagnostic_buffer, "In method `%s':",
                (*decl_printable_name) (current_function_decl, 2));
          else
             output_printf
-              (diagnostic_buffer, "In function `%s':\n",
+              (diagnostic_buffer, "In function `%s':",
                (*decl_printable_name) (current_function_decl, 2));
        }
+      output_add_newline (diagnostic_buffer);
 
       record_last_error_function ();
       output_to_stream (diagnostic_buffer, stderr);
-      diagnostic_buffer->state = os;
+      output_buffer_state (diagnostic_buffer) = os;
       free ((char*) prefix);
     }
 }
@@ -1243,26 +1287,7 @@ void
 report_error_function (file)
   const char *file ATTRIBUTE_UNUSED;
 {
-  struct file_stack *p;
-
-  if (output_needs_newline (diagnostic_buffer))
-    {
-      verbatim ("\n");
-      output_needs_newline (diagnostic_buffer) = 0;
-    }
-
-  if (input_file_stack && input_file_stack->next != 0
-      && error_function_changed ())
-    {
-      for (p = input_file_stack->next; p; p = p->next)
-       if (p == input_file_stack->next)
-         verbatim ("In file included from %s:%d", p->name, p->line);
-       else
-         verbatim (",\n                 from %s:%d", p->name, p->line);
-      verbatim (":\n");
-      record_last_error_function ();
-    }
-
+  report_problematic_module (diagnostic_buffer);
   (*print_error_function) (input_filename);
 }
 
@@ -1524,14 +1549,14 @@ output_do_verbatim (buffer, msg, args_ptr)
 {
   output_state os;
 
-  os = buffer->state;
+  os = output_buffer_state (buffer);
   output_prefix (buffer) = NULL;
   prefixing_policy (buffer) = DIAGNOSTICS_SHOW_PREFIX_NEVER;
   output_buffer_text_cursor (buffer) = msg;
   output_buffer_ptr_to_format_args (buffer) = args_ptr;
   output_set_maximum_length (buffer, 0);
   output_format (buffer);
-  buffer->state = os;
+  output_buffer_state (buffer) = os;
 }
 
 /* Output MESSAGE verbatim into BUFFER.  */
@@ -1587,14 +1612,14 @@ report_diagnostic (dc)
 
   if (count_error (diagnostic_is_warning (dc)))
     {
-      os = diagnostic_buffer->state;
+      os = output_buffer_state (diagnostic_buffer);
       diagnostic_msg = diagnostic_message (dc);
       diagnostic_args = diagnostic_argument_list (dc);
       (*diagnostic_starter (dc)) (diagnostic_buffer, dc);
       output_format (diagnostic_buffer);
       (*diagnostic_finalizer (dc)) (diagnostic_buffer, dc);
       finish_diagnostic ();
-      diagnostic_buffer->state = os;
+      output_buffer_state (diagnostic_buffer) = os;
     }
 
   diagnostic_lock--;
@@ -1677,6 +1702,33 @@ set_diagnostic_context (dc, message, args_ptr, file, line, warn)
   diagnostic_finalizer (dc) = lang_diagnostic_finalizer;
 }
 
+void
+report_problematic_module (buffer)
+     output_buffer *buffer;
+{
+  struct file_stack *p;
+
+  if (output_needs_newline (buffer))
+    {
+      output_add_newline (buffer);
+      output_needs_newline (buffer) = 0;
+    }
+
+  if (input_file_stack && input_file_stack->next != 0
+      && error_function_changed ())
+    {
+      for (p = input_file_stack->next; p; p = p->next)
+       if (p == input_file_stack->next)
+         output_verbatim
+            (buffer, "In file included from %s:%d", p->name, p->line);
+       else
+         output_verbatim
+            (buffer, ",\n                 from %s:%d", p->name, p->line);
+      output_verbatim (buffer, ":\n");
+      record_last_error_function ();
+    }
+}
+
 static void
 default_diagnostic_starter (buffer, dc)
      output_buffer *buffer;